Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/src/commands.rs')
| -rw-r--r-- | helix-term/src/commands.rs | 98 |
1 files changed, 49 insertions, 49 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 18f24a63..8edf5944 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -22,7 +22,8 @@ pub use typed::*; use helix_core::{ char_idx_at_visual_offset, chars::char_is_word, - command_line, comment, + command_line::{self, Args}, + comment, doc_formatter::TextFormat, encoding, find_workspace, graphemes::{self, next_grapheme_boundary}, @@ -46,6 +47,7 @@ use helix_core::{ use helix_view::{ document::{FormatterError, Mode, SCRATCH_BUFFER_NAME}, editor::Action, + expansion, info::Info, input::KeyEvent, keyboard::KeyCode, @@ -6256,64 +6258,52 @@ enum ShellBehavior { } fn shell_pipe(cx: &mut Context) { - shell_prompt(cx, "pipe:".into(), ShellBehavior::Replace); + shell_prompt_for_behavior(cx, "pipe:".into(), ShellBehavior::Replace); } fn shell_pipe_to(cx: &mut Context) { - shell_prompt(cx, "pipe-to:".into(), ShellBehavior::Ignore); + shell_prompt_for_behavior(cx, "pipe-to:".into(), ShellBehavior::Ignore); } fn shell_insert_output(cx: &mut Context) { - shell_prompt(cx, "insert-output:".into(), ShellBehavior::Insert); + shell_prompt_for_behavior(cx, "insert-output:".into(), ShellBehavior::Insert); } fn shell_append_output(cx: &mut Context) { - shell_prompt(cx, "append-output:".into(), ShellBehavior::Append); + shell_prompt_for_behavior(cx, "append-output:".into(), ShellBehavior::Append); } fn shell_keep_pipe(cx: &mut Context) { - ui::prompt( - cx, - "keep-pipe:".into(), - Some('|'), - ui::completers::none, - move |cx, input: &str, event: PromptEvent| { - let shell = &cx.editor.config().shell; - if event != PromptEvent::Validate { - return; - } - if input.is_empty() { - return; - } - let (view, doc) = current!(cx.editor); - let selection = doc.selection(view.id); + shell_prompt(cx, "keep-pipe:".into(), |cx, args| { + let shell = &cx.editor.config().shell; + let (view, doc) = current!(cx.editor); + let selection = doc.selection(view.id); - let mut ranges = SmallVec::with_capacity(selection.len()); - let old_index = selection.primary_index(); - let mut index: Option<usize> = None; - let text = doc.text().slice(..); + let mut ranges = SmallVec::with_capacity(selection.len()); + let old_index = selection.primary_index(); + let mut index: Option<usize> = None; + let text = doc.text().slice(..); - for (i, range) in selection.ranges().iter().enumerate() { - let fragment = range.slice(text); - if let Err(err) = shell_impl(shell, input, Some(fragment.into())) { - log::debug!("Shell command failed: {}", err); - } else { - ranges.push(*range); - if i >= old_index && index.is_none() { - index = Some(ranges.len() - 1); - } + for (i, range) in selection.ranges().iter().enumerate() { + let fragment = range.slice(text); + if let Err(err) = shell_impl(shell, args.join(" ").as_str(), Some(fragment.into())) { + log::debug!("Shell command failed: {}", err); + } else { + ranges.push(*range); + if i >= old_index && index.is_none() { + index = Some(ranges.len() - 1); } } + } - if ranges.is_empty() { - cx.editor.set_error("No selections remaining"); - return; - } + if ranges.is_empty() { + cx.editor.set_error("No selections remaining"); + return; + } - let index = index.unwrap_or_else(|| ranges.len() - 1); - doc.set_selection(view.id, Selection::new(ranges, index)); - }, - ); + let index = index.unwrap_or_else(|| ranges.len() - 1); + doc.set_selection(view.id, Selection::new(ranges, index)); + }); } fn shell_impl(shell: &[String], cmd: &str, input: Option<Rope>) -> anyhow::Result<Tendril> { @@ -6468,25 +6458,35 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) { view.ensure_cursor_in_view(doc, config.scrolloff); } -fn shell_prompt(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) { +fn shell_prompt<F>(cx: &mut Context, prompt: Cow<'static, str>, mut callback_fn: F) +where + F: FnMut(&mut compositor::Context, Args) + 'static, +{ ui::prompt( cx, prompt, Some('|'), - ui::completers::shell, - move |cx, input: &str, event: PromptEvent| { - if event != PromptEvent::Validate { + |editor, input| complete_command_args(editor, SHELL_SIGNATURE, &SHELL_COMPLETER, input, 0), + move |cx, input, event| { + if event != PromptEvent::Validate || input.is_empty() { return; } - if input.is_empty() { - return; + match Args::parse(input, SHELL_SIGNATURE, true, |token| { + expansion::expand(cx.editor, token).map_err(|err| err.into()) + }) { + Ok(args) => callback_fn(cx, args), + Err(err) => cx.editor.set_error(err.to_string()), } - - shell(cx, input, &behavior); }, ); } +fn shell_prompt_for_behavior(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) { + shell_prompt(cx, prompt, move |cx, args| { + shell(cx, args.join(" ").as_str(), &behavior) + }) +} + fn suspend(_cx: &mut Context) { #[cfg(not(windows))] { |