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.rs98
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))]
{