summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--helix-term/src/commands.rs110
-rw-r--r--helix-term/src/ui/prompt.rs2
2 files changed, 103 insertions, 9 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 2fe84162..3f649572 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -954,17 +954,22 @@ mod cmd {
};
}
- fn write(editor: &mut Editor, args: &[&str], event: PromptEvent) {
- let (view, doc) = editor.current();
- if let Some(path) = args.get(0) {
- if let Err(err) = doc.set_path(Path::new(path)) {
- editor.set_error(format!("invalid filepath: {}", err));
- return;
+ fn _write<P: AsRef<Path>>(
+ view: &View,
+ doc: &mut Document,
+ path: Option<P>,
+ ) -> Result<(), anyhow::Error> {
+ use anyhow::anyhow;
+
+ if let Some(path) = path {
+ if let Err(err) = doc.set_path(path.as_ref()) {
+ return Err(anyhow!("invalid filepath: {}", err));
};
}
if doc.path().is_none() {
- editor.set_error("cannot write a buffer without a filename".to_string());
- return;
+ return Err(anyhow!(
+ "cannot write a buffer without a filename".to_string()
+ ));
}
let autofmt = doc
.language_config()
@@ -974,6 +979,14 @@ mod cmd {
doc.format(view.id); // TODO: merge into save
}
tokio::spawn(doc.save());
+ Ok(())
+ }
+
+ fn write(editor: &mut Editor, args: &[&str], event: PromptEvent) {
+ let (view, doc) = editor.current();
+ if let Err(e) = _write(view, doc, args.first()) {
+ editor.set_error(e.to_string());
+ };
}
fn new_file(editor: &mut Editor, args: &[&str], event: PromptEvent) {
@@ -1010,6 +1023,52 @@ mod cmd {
doc.later(view.id, uk)
}
+ fn write_quit(editor: &mut Editor, args: &[&str], event: PromptEvent) {
+ write(editor, args, event.clone());
+ quit(editor, &[], event);
+ }
+
+ fn force_write_quit(editor: &mut Editor, args: &[&str], event: PromptEvent) {
+ write(editor, args, event.clone());
+ force_quit(editor, &[], event);
+ }
+
+ fn _write_all(editor: &mut Editor, args: &[&str], event: PromptEvent, quit: bool, force: bool) {
+ let ids = editor
+ .tree
+ .views()
+ .map(|(view, _)| (view.id, view.doc))
+ .collect::<Vec<_>>();
+
+ for (view_id, doc_id) in ids {
+ if let Some(doc) = editor.documents.get_mut(doc_id) {
+ let view = editor.tree.get(view_id);
+ if let Err(e) = _write(view, doc, None::<&str>) {
+ editor.set_error(e.to_string());
+ } else if quit {
+ editor.close(view_id, false);
+ continue;
+ }
+
+ if force {
+ editor.close(view_id, false);
+ }
+ }
+ }
+ }
+
+ fn write_all(editor: &mut Editor, args: &[&str], event: PromptEvent) {
+ _write_all(editor, args, event, false, false)
+ }
+
+ fn write_all_quit(editor: &mut Editor, args: &[&str], event: PromptEvent) {
+ _write_all(editor, args, event, true, false)
+ }
+
+ fn force_write_all_quit(editor: &mut Editor, args: &[&str], event: PromptEvent) {
+ _write_all(editor, args, event, true, true)
+ }
+
pub const COMMAND_LIST: &[Command] = &[
Command {
name: "quit",
@@ -1067,6 +1126,41 @@ mod cmd {
fun: later,
completer: None,
},
+ Command {
+ name: "write-quit",
+ alias: Some("wq"),
+ doc: "Writes changes to disk and closes the current view. Accepts an optional path (:wq some/path.txt)",
+ fun: write_quit,
+ completer: Some(completers::filename),
+ },
+ Command {
+ name: "write-quit!",
+ alias: Some("wq!"),
+ doc: "Writes changes to disk and closes the current view forcefully. Accepts an optional path (:wq! some/path.txt)",
+ fun: force_write_quit,
+ completer: Some(completers::filename),
+ },
+ Command {
+ name: "write-all",
+ alias: Some("wa"),
+ doc: "Writes changes from all views to disk.",
+ fun: write_all,
+ completer: None,
+ },
+ Command {
+ name: "write-all-quit",
+ alias: Some("waq"),
+ doc: "Writes changes from all views to disk and close all views.",
+ fun: write_all_quit,
+ completer: None,
+ },
+ Command {
+ name: "write-all-quit!",
+ alias: Some("waq!"),
+ doc: "Writes changes from all views to disk and close all views forcefully (ignoring errors).",
+ fun: force_write_all_quit,
+ completer: None,
+ },
];
pub static COMMANDS: Lazy<HashMap<&'static str, &'static Command>> = Lazy::new(|| {
diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs
index 8367b12c..c6429736 100644
--- a/helix-term/src/ui/prompt.rs
+++ b/helix-term/src/ui/prompt.rs
@@ -18,7 +18,7 @@ pub struct Prompt {
pub doc_fn: Box<dyn Fn(&str) -> Option<&'static str>>,
}
-#[derive(PartialEq)]
+#[derive(Clone, PartialEq)]
pub enum PromptEvent {
/// The prompt input has been updated.
Update,