term/editor: Implement `exists` for Windows

The paths checked by `fn exists` are well-known Unix locations, and not
meaningful to check on Windows.

Provide an implementation of `fn exists` for Windows, which uses
`which.exe` to look for binaries, and use that to provide sane defaults
for Windows.
This commit is contained in:
Lorenz Leutgeb 2026-02-10 14:45:57 +01:00
parent 450b664ad8
commit 50fb228ae4
No known key found for this signature in database
1 changed files with 31 additions and 2 deletions

View File

@ -227,16 +227,31 @@ fn default_editor() -> Option<OsString> {
if exists("nano") {
return Some("nano".into());
}
// On Windows, `edit` is available by default, see <https://learn.microsoft.com/windows/edit>.
#[cfg(windows)]
if exists("edit.exe") {
return Some("edit.exe".into());
}
// On Windows, `notepad` is commonly available for decades, see <https://apps.microsoft.com/detail/9msmlrh6lzf3>.
#[cfg(windows)]
if exists("notepad.exe") {
return Some("notepad.exe".into());
}
// If all else fails, we try `vi`. It's usually installed on most unix-based systems.
if exists("vi") {
return Some("vi".into());
}
None
}
/// Check whether a binary can be found in the most common paths.
/// We don't bother checking the $PATH variable, as we're only looking for very standard tools
/// Check whether a binary can be found in the most common paths on Unix-like systems.
/// We don't bother checking the `$PATH` variable, as we're only looking for very standard tools
/// and prefer not to make this too complex.
#[cfg(unix)]
fn exists(cmd: &str) -> bool {
// Some common paths where system-installed binaries are found.
const PATHS: &[&str] = &["/usr/local/bin", "/usr/bin", "/bin"];
@ -248,3 +263,17 @@ fn exists(cmd: &str) -> bool {
}
false
}
/// Check whether a binary can be found on `$PATH`.
/// See:
/// - <https://devblogs.microsoft.com/scripting/weekend-scripter-where-exethe-what-why-and-how/>
/// - <https://learn.microsoft.com/windows-server/administration/windows-commands/where>
#[cfg(windows)]
fn exists(cmd: &str) -> bool {
std::process::Command::new("where.exe")
.arg("/q")
.arg("$PATH:".to_owned() + cmd)
.output()
.map(|output| output.status.success())
.unwrap_or_default()
}