aboutsummaryrefslogtreecommitdiffstats
path: root/src/edit.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-04-18 01:30:07 -0400
committerJesse Luehrs <doy@tozt.net>2020-04-18 01:58:08 -0400
commitdd7ef574e84ca6c1a548422904c6865048ae8e30 (patch)
treedbefd8cd140dd3ace35097f34e0796c31fd3d709 /src/edit.rs
parent777b810db4675305854c373dcd57aedc40061e5d (diff)
downloadrbw-dd7ef574e84ca6c1a548422904c6865048ae8e30.tar.gz
rbw-dd7ef574e84ca6c1a548422904c6865048ae8e30.zip
implement editing a string in a text editor
Diffstat (limited to 'src/edit.rs')
-rw-r--r--src/edit.rs54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/edit.rs b/src/edit.rs
new file mode 100644
index 0000000..8325072
--- /dev/null
+++ b/src/edit.rs
@@ -0,0 +1,54 @@
+use crate::prelude::*;
+
+use std::io::{Read as _, Write as _};
+
+pub fn edit(contents: &str, help: &str) -> Result<String> {
+ let editor =
+ std::env::var_os("EDITOR").unwrap_or_else(|| "/usr/bin/vim".into());
+ let editor = std::path::Path::new(&editor);
+
+ let mut args = vec![];
+ match editor.file_name() {
+ Some(editor) => match editor.to_str() {
+ Some("vim") => {
+ // disable swap files and viminfo for password entry
+ args.push(std::ffi::OsStr::new("-ni"));
+ args.push(std::ffi::OsStr::new("NONE"));
+ }
+ _ => {
+ // other editor support welcomed
+ }
+ },
+ None => {
+ return Err(Error::InvalidEditor {
+ editor: editor.as_os_str().to_os_string(),
+ })
+ }
+ }
+
+ let dir = tempfile::tempdir().unwrap();
+ let file = dir.path().join("rbw");
+ let mut fh = std::fs::File::create(&file).unwrap();
+ fh.write_all(contents.as_bytes()).unwrap();
+ fh.write_all(help.as_bytes()).unwrap();
+ drop(fh);
+
+ args.push(file.as_os_str());
+ let res = std::process::Command::new(&editor)
+ .args(&args)
+ .status()
+ .unwrap();
+ if !res.success() {
+ return Err(Error::FailedToRunEditor {
+ editor: editor.to_owned(),
+ res,
+ });
+ }
+
+ let mut fh = std::fs::File::open(&file).unwrap();
+ let mut contents = String::new();
+ fh.read_to_string(&mut contents).unwrap();
+ drop(fh);
+
+ Ok(contents)
+}