term: Fallback to common editors

When `EDITOR` or `VISUAL` are not set, we fallback to the most common
editors. It turns out many users don't have these variables set.

We also check if an editor has been configured with `git`.
This commit is contained in:
cloudhead 2023-08-31 14:02:56 +02:00
parent 3f592e23d4
commit 27e2f47280
No known key found for this signature in database
3 changed files with 40 additions and 1 deletions

1
Cargo.lock generated
View File

@ -2040,6 +2040,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anstyle-query", "anstyle-query",
"anyhow", "anyhow",
"git2",
"inquire", "inquire",
"libc", "libc",
"once_cell", "once_cell",

View File

@ -8,6 +8,9 @@ version = "0.1.0"
authors = ["cloudhead <cloudhead@radicle.xyz>"] authors = ["cloudhead <cloudhead@radicle.xyz>"]
edition = "2021" edition = "2021"
[features]
default = ["git2"]
[dependencies] [dependencies]
anyhow = { version = "1" } anyhow = { version = "1" }
anstyle-query = { version = "1.0.0" } anstyle-query = { version = "1.0.0" }
@ -19,6 +22,12 @@ unicode-width = { version = "0.1.10", default-features = false }
unicode-segmentation = { version = "1.7.1" } unicode-segmentation = { version = "1.7.1" }
zeroize = { version = "1.1" } zeroize = { version = "1.1" }
[dependencies.git2]
version = "0.17.0"
default-features = false
features = ["vendored-libgit2"]
optional = true
[dev-dependencies] [dev-dependencies]
pretty_assertions = { version = "1.3.0" } pretty_assertions = { version = "1.3.0" }
tempfile = { version = "3.3.0" } tempfile = { version = "3.3.0" }

View File

@ -2,11 +2,13 @@ use std::ffi::OsString;
use std::io::IsTerminal; use std::io::IsTerminal;
use std::io::Write; use std::io::Write;
use std::os::fd::{AsRawFd, FromRawFd}; use std::os::fd::{AsRawFd, FromRawFd};
use std::path::PathBuf; use std::path::{Path, PathBuf};
use std::process; use std::process;
use std::{env, fs, io}; use std::{env, fs, io};
pub const COMMENT_FILE: &str = "RAD_COMMENT"; pub const COMMENT_FILE: &str = "RAD_COMMENT";
/// Some common paths where system-installed binaries are found.
pub const PATHS: &[&str] = &["/usr/local/bin", "/usr/bin", "/bin"];
/// Allows for text input in the configured editor. /// Allows for text input in the configured editor.
pub struct Editor { pub struct Editor {
@ -101,6 +103,7 @@ impl Editor {
/// Get the default editor command. /// Get the default editor command.
pub fn default_editor() -> Option<OsString> { pub fn default_editor() -> Option<OsString> {
// First check the standard environment variables.
if let Ok(visual) = env::var("VISUAL") { if let Ok(visual) = env::var("VISUAL") {
if !visual.is_empty() { if !visual.is_empty() {
return Some(visual.into()); return Some(visual.into());
@ -111,5 +114,31 @@ pub fn default_editor() -> Option<OsString> {
return Some(editor.into()); return Some(editor.into());
} }
} }
// Check Git. The user might have configured their editor there.
#[cfg(feature = "git2")]
if let Ok(path) = git2::Config::open_default().and_then(|cfg| cfg.get_path("core.editor")) {
return Some(path.into_os_string());
}
// On macOS, `nano` is installed by default and it's what most users are used to
// in the terminal.
if cfg!(target_os = "macos") && exists("nano") {
return Some("nano".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 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
/// and prefer not to make this too complex.
fn exists(cmd: &str) -> bool {
for dir in PATHS {
if Path::new(dir).join(cmd).exists() {
return true;
}
}
false
}