devlog/
editor.rs

1//! Open a file using a text editor program (e.g. vim or nano)
2
3use crate::config::Config;
4use crate::error::Error;
5use crate::hook::{execute_hook, HookType};
6use std::io::Write;
7use std::path::Path;
8use std::process::Command;
9
10/// Opens the specified file in a text editor program.
11/// If available, the before-edit and after-edit hooks are invoked.
12pub fn open<W: Write>(w: &mut W, config: &Config, path: &Path) -> Result<(), Error> {
13    execute_hook(w, config, &HookType::BeforeEdit, &[path.as_os_str()])?;
14    open_in_editor(w, config, path)?;
15    execute_hook(w, config, &HookType::AfterEdit, &[path.as_os_str()])?;
16    Ok(())
17}
18
19fn open_in_editor<W: Write>(w: &mut W, config: &Config, path: &Path) -> Result<(), Error> {
20    let prog = config.editor_prog();
21    let status = Command::new(prog).arg(&path).status()?;
22
23    if status.success() {
24        Ok(())
25    } else {
26        match status.code() {
27            Some(code) => write!(
28                w,
29                "Command `{} {}` exited with status {}\n",
30                prog,
31                path.to_string_lossy(),
32                code
33            )
34            .map_err(From::from),
35            None => write!(w, "Process terminated by signal\n").map_err(From::from),
36        }
37    }
38}