mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 09:26:19 +04:00
Pipe typable command (#1972)
Co-authored-by: DeviousStoat <devious@stoat.com>
This commit is contained in:
parent
dc8fef5dd3
commit
2eca2901f3
@ -61,3 +61,4 @@
|
||||
| `:tree-sitter-subtree`, `:ts-subtree` | Display tree sitter subtree under cursor, primarily for debugging queries. |
|
||||
| `:config-reload` | Refreshes helix's config. |
|
||||
| `:config-open` | Open the helix config.toml file. |
|
||||
| `:pipe` | Pipe each selection to the shell command. |
|
||||
|
@ -4150,19 +4150,19 @@ enum ShellBehavior {
|
||||
}
|
||||
|
||||
fn shell_pipe(cx: &mut Context) {
|
||||
shell(cx, "pipe:".into(), ShellBehavior::Replace);
|
||||
shell_prompt(cx, "pipe:".into(), ShellBehavior::Replace);
|
||||
}
|
||||
|
||||
fn shell_pipe_to(cx: &mut Context) {
|
||||
shell(cx, "pipe-to:".into(), ShellBehavior::Ignore);
|
||||
shell_prompt(cx, "pipe-to:".into(), ShellBehavior::Ignore);
|
||||
}
|
||||
|
||||
fn shell_insert_output(cx: &mut Context) {
|
||||
shell(cx, "insert-output:".into(), ShellBehavior::Insert);
|
||||
shell_prompt(cx, "insert-output:".into(), ShellBehavior::Insert);
|
||||
}
|
||||
|
||||
fn shell_append_output(cx: &mut Context) {
|
||||
shell(cx, "append-output:".into(), ShellBehavior::Append);
|
||||
shell_prompt(cx, "append-output:".into(), ShellBehavior::Append);
|
||||
}
|
||||
|
||||
fn shell_keep_pipe(cx: &mut Context) {
|
||||
@ -4256,26 +4256,14 @@ fn shell_impl(
|
||||
Ok((tendril, output.status.success()))
|
||||
}
|
||||
|
||||
fn shell(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) {
|
||||
fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {
|
||||
let pipe = match behavior {
|
||||
ShellBehavior::Replace | ShellBehavior::Ignore => true,
|
||||
ShellBehavior::Insert | ShellBehavior::Append => false,
|
||||
};
|
||||
|
||||
ui::prompt(
|
||||
cx,
|
||||
prompt,
|
||||
Some('|'),
|
||||
ui::completers::none,
|
||||
move |cx, input: &str, event: PromptEvent| {
|
||||
let config = cx.editor.config();
|
||||
let shell = &config.shell;
|
||||
if event != PromptEvent::Validate {
|
||||
return;
|
||||
}
|
||||
if input.is_empty() {
|
||||
return;
|
||||
}
|
||||
let (view, doc) = current!(cx.editor);
|
||||
let selection = doc.selection(view.id);
|
||||
|
||||
@ -4284,8 +4272,7 @@ fn shell(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) {
|
||||
|
||||
for range in selection.ranges() {
|
||||
let fragment = range.fragment(text);
|
||||
let (output, success) =
|
||||
match shell_impl(shell, input, pipe.then(|| fragment.as_bytes())) {
|
||||
let (output, success) = match shell_impl(shell, cmd, pipe.then(|| fragment.as_bytes())) {
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
cx.editor.set_error(err.to_string());
|
||||
@ -4307,7 +4294,7 @@ fn shell(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) {
|
||||
changes.push((from, to, Some(output)));
|
||||
}
|
||||
|
||||
if behavior != ShellBehavior::Ignore {
|
||||
if behavior != &ShellBehavior::Ignore {
|
||||
let transaction = Transaction::change(doc.text(), changes.into_iter());
|
||||
doc.apply(&transaction, view.id);
|
||||
}
|
||||
@ -4315,6 +4302,23 @@ fn shell(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) {
|
||||
// after replace cursor may be out of bounds, do this to
|
||||
// make sure cursor is in view and update scroll as well
|
||||
view.ensure_cursor_in_view(doc, config.scrolloff);
|
||||
}
|
||||
|
||||
fn shell_prompt(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) {
|
||||
ui::prompt(
|
||||
cx,
|
||||
prompt,
|
||||
Some('|'),
|
||||
ui::completers::none,
|
||||
move |cx, input: &str, event: PromptEvent| {
|
||||
if event != PromptEvent::Validate {
|
||||
return;
|
||||
}
|
||||
if input.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
shell(cx, input, &behavior);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -1067,6 +1067,16 @@ fn refresh_config(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn pipe(
|
||||
cx: &mut compositor::Context,
|
||||
args: &[Cow<str>],
|
||||
_event: PromptEvent,
|
||||
) -> anyhow::Result<()> {
|
||||
ensure!(!args.is_empty(), "Shell command required");
|
||||
shell(cx, &args.join(" "), &ShellBehavior::Replace);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
|
||||
TypableCommand {
|
||||
name: "quit",
|
||||
@ -1495,6 +1505,13 @@ fn refresh_config(
|
||||
fun: open_config,
|
||||
completer: None,
|
||||
},
|
||||
TypableCommand {
|
||||
name: "pipe",
|
||||
aliases: &[],
|
||||
doc: "Pipe each selection to the shell command.",
|
||||
fun: pipe,
|
||||
completer: None,
|
||||
},
|
||||
];
|
||||
|
||||
pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> =
|
||||
|
Loading…
Reference in New Issue
Block a user