1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use crate::Cmd;
use std::{
io,
path::PathBuf,
process::{Command, Stdio},
};
pub fn find_cmd() -> io::Result<Cmd> {
if has_nvim_on_path() {
Ok(Cmd::Neovim)
} else if has_vim_on_path() {
Ok(Cmd::Vim)
} else {
Err(io::Error::new(
io::ErrorKind::NotFound,
"No vim or neovim instance found in path",
))
}
}
pub fn has_vim_on_path() -> bool {
has_on_path("vim")
}
pub fn has_nvim_on_path() -> bool {
has_on_path("nvim")
}
fn has_on_path(cmd: &str) -> bool {
!matches!(
Command::new(cmd)
.arg("--help")
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn(),
Err(x) if x.kind() == io::ErrorKind::NotFound
)
}
pub fn find_vimrc() -> Option<PathBuf> {
let xdg_config_home = shellexpand::env("$XDG_CONFIG_HOME");
if cfg!(unix) {
let home = shellexpand::tilde("~");
let path1 = xdg_config_home.map(|home| {
[home.as_ref(), "nvim", "init.vim"]
.iter()
.collect::<PathBuf>()
});
let path2 = [home.as_ref(), ".config", "nvim", "init.vim"]
.iter()
.collect::<PathBuf>();
let path3 = [home.as_ref(), ".vimrc"].iter().collect::<PathBuf>();
let path4 = [home.as_ref(), ".vim", "vimrc"].iter().collect::<PathBuf>();
match (path1, path2, path3, path4) {
(Ok(path), _, _, _) if path.exists() => Some(path),
(_, path, _, _) if path.exists() => Some(path),
(_, _, path, _) if path.exists() => Some(path),
(_, _, _, path) if path.exists() => Some(path),
_ => None,
}
} else if cfg!(windows) {
let home = shellexpand::tilde("~");
let vim_env = shellexpand::env("$VIM");
let path1 = xdg_config_home.map(|home| {
[home.as_ref(), "nvim", "init.vim"]
.iter()
.collect::<PathBuf>()
});
let path2 = [home.as_ref(), "AppData", "Local", "nvim", "init.vim"]
.iter()
.collect::<PathBuf>();
let path3 = [home.as_ref(), "_vimrc"].iter().collect::<PathBuf>();
let path4 = [home.as_ref(), "vimfiles", "vimrc"]
.iter()
.collect::<PathBuf>();
let path5 = vim_env.map(|vim| [vim.as_ref(), "_vimrc"].iter().collect::<PathBuf>());
match (path1, path2, path3, path4, path5) {
(Ok(path), _, _, _, _) if path.exists() => Some(path),
(_, path, _, _, _) if path.exists() => Some(path),
(_, _, path, _, _) if path.exists() => Some(path),
(_, _, _, path, _) if path.exists() => Some(path),
(_, _, _, _, Ok(path)) if path.exists() => Some(path),
_ => None,
}
} else {
None
}
}