#[allow(unused_doc_comments)]
use std::env;
use std::error::Error;
use std::io::Result;
use std::io::ErrorKind;
use std::path::{Path, PathBuf};
use std::ffi::OsStr;
#[cfg(target_os = "windows")]
env::set_var("VISUAL", "cmd.exe /C type");
#[cfg(target_os = "windows")]
env::set_var("EDITOR", "cmd.exe /C type");
fn get_full_editor_cmd(s: String) -> Result<(PathBuf, Vec<String>)> {
let (path, args) = string_to_cmd(s);
match get_full_editor_path(&path) {
Ok(result) => Ok((result, args)),
Err(_) if path.exists() => Ok((path, args)),
Err(_) => Err(std::io::Error::from(ErrorKind::NotFound))
}
}
fn get_full_editor_path<T: AsRef<OsStr> + AsRef<Path>>(binary_name: T) -> Result<PathBuf> {
if let Some(paths) = env::var_os("PATH") {
for dir in env::split_paths(&paths) {
if dir.join(&binary_name).is_file() {
return Ok(dir.join(&binary_name));
}
}
}
Err(std::io::Error::from(ErrorKind::NotFound))
}
fn string_to_cmd(s: String) -> (PathBuf, Vec<String>) {
let mut args = s.split_ascii_whitespace();
(
args.next().unwrap().into(),
args.map(String::from).collect(),
)
}
static HARDCODED_NAMES: &[&str] = &[
"code.cmd -n -w", "atom.exe -w", "subl.exe -w",
"notepad.exe",
"cmd.exe /C start",
];
static ENV_VARS: &[&str] = &["VISUAL", "EDITOR"];
let editor = ENV_VARS
.iter()
.filter_map(env::var_os)
.filter(|v| !v.is_empty())
.filter_map(|v| v.into_string().ok()).next();
println!("editor={editor:?}");
let editor_cmd = ENV_VARS
.iter()
.filter_map(env::var_os)
.filter(|v| !v.is_empty())
.filter_map(|v| v.into_string().ok())
.filter_map(|s| get_full_editor_cmd(s).ok())
.next()
.or_else(|| {
HARDCODED_NAMES
.iter()
.map(|s| s.to_string())
.filter_map(|s| get_full_editor_cmd(s).ok())
.next()
});
println!("editor_cmd={editor_cmd:?}");
let template = "Fill in the blank: Hello, _____!";
let edited = edit::edit(template)?;
println!("after editing: '{}'", edited);