mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-25 19:03:30 +04:00
feat: execute helix command from pipe output
This commit is contained in:
parent
237cbe4bca
commit
3c76d750a7
@ -81,6 +81,7 @@
|
||||
| `:append-output` | Run shell command, appending output after each selection. |
|
||||
| `:pipe` | Pipe each selection to the shell command. |
|
||||
| `:pipe-to` | Pipe each selection to the shell command, ignoring output. |
|
||||
| `:pipe-execute` | Pipe each selection to the shell command, execute output as helix command. |
|
||||
| `:run-shell-command`, `:sh` | Run a shell command |
|
||||
| `:reset-diff-change`, `:diffget`, `:diffg` | Reset the diff change at the cursor position. |
|
||||
| `:clear-register` | Clear given register. If no argument is provided, clear all registers. |
|
||||
|
@ -108,6 +108,7 @@ #### Shell
|
||||
| `!` | Run shell command, inserting output before each selection | `shell_insert_output` |
|
||||
| `Alt-!` | Run shell command, appending output after each selection | `shell_append_output` |
|
||||
| `$` | Pipe each selection into shell command, keep selections where command returned 0 | `shell_keep_pipe` |
|
||||
| `Alt-$` | Pipe each selection into shell command, execute output as helix command | `shell_keep_pipe` |
|
||||
|
||||
|
||||
### Selection manipulation
|
||||
|
@ -63,6 +63,7 @@
|
||||
};
|
||||
|
||||
use crate::job::{self, Jobs};
|
||||
use std::str::FromStr;
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::{HashMap, HashSet},
|
||||
@ -555,6 +556,7 @@ pub fn doc(&self) -> &str {
|
||||
dap_disable_exceptions, "Disable exception breakpoints",
|
||||
shell_pipe, "Pipe selections through shell command",
|
||||
shell_pipe_to, "Pipe selections into shell command ignoring output",
|
||||
shell_pipe_execute, "Pipe selections into shell command, execute output as command",
|
||||
shell_insert_output, "Insert shell command output before selections",
|
||||
shell_append_output, "Append shell command output after selections",
|
||||
shell_keep_pipe, "Filter selections with shell predicate",
|
||||
@ -5693,6 +5695,7 @@ enum ShellBehavior {
|
||||
Ignore,
|
||||
Insert,
|
||||
Append,
|
||||
Execute,
|
||||
}
|
||||
|
||||
fn shell_pipe(cx: &mut Context) {
|
||||
@ -5703,6 +5706,10 @@ fn shell_pipe_to(cx: &mut Context) {
|
||||
shell_prompt(cx, "pipe-to:".into(), ShellBehavior::Ignore);
|
||||
}
|
||||
|
||||
fn shell_pipe_execute(cx: &mut Context) {
|
||||
shell_prompt(cx, "pipe-execute:".into(), ShellBehavior::Execute);
|
||||
}
|
||||
|
||||
fn shell_insert_output(cx: &mut Context) {
|
||||
shell_prompt(cx, "insert-output:".into(), ShellBehavior::Insert);
|
||||
}
|
||||
@ -5829,7 +5836,7 @@ async fn shell_impl_async(
|
||||
|
||||
fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {
|
||||
let pipe = match behavior {
|
||||
ShellBehavior::Replace | ShellBehavior::Ignore => true,
|
||||
ShellBehavior::Replace | ShellBehavior::Ignore | ShellBehavior::Execute => true,
|
||||
ShellBehavior::Insert | ShellBehavior::Append => false,
|
||||
};
|
||||
|
||||
@ -5876,6 +5883,7 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {
|
||||
ShellBehavior::Replace => (range.from(), range.to(), range.len()),
|
||||
ShellBehavior::Insert => (range.from(), range.from(), 0),
|
||||
ShellBehavior::Append => (range.to(), range.to(), 0),
|
||||
ShellBehavior::Execute => (range.from(), range.from(), 0),
|
||||
_ => (range.from(), range.from(), 0),
|
||||
};
|
||||
|
||||
@ -5896,16 +5904,43 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {
|
||||
changes.push((from, to, Some(output)));
|
||||
}
|
||||
|
||||
if behavior != &ShellBehavior::Ignore {
|
||||
let transaction = Transaction::change(doc.text(), changes.into_iter())
|
||||
.with_selection(Selection::new(ranges, selection.primary_index()));
|
||||
doc.apply(&transaction, view.id);
|
||||
doc.append_changes_to_history(view);
|
||||
}
|
||||
let mut commands = Vec::with_capacity(changes.len());
|
||||
match behavior {
|
||||
ShellBehavior::Ignore => (),
|
||||
ShellBehavior::Execute => {
|
||||
for (_, _, command_text) in changes {
|
||||
if let Some(command_text) = command_text {
|
||||
if let Ok(command) = MappableCommand::from_str(&command_text[..]) {
|
||||
commands.push(command)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let transaction = Transaction::change(doc.text(), changes.into_iter())
|
||||
.with_selection(Selection::new(ranges, selection.primary_index()));
|
||||
doc.apply(&transaction, view.id);
|
||||
doc.append_changes_to_history(view);
|
||||
}
|
||||
};
|
||||
|
||||
// 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);
|
||||
|
||||
if behavior == &ShellBehavior::Execute {
|
||||
for command in commands {
|
||||
let mut ctx = Context {
|
||||
register: None,
|
||||
count: None,
|
||||
editor: cx.editor,
|
||||
callback: Vec::new(),
|
||||
on_next_key_callback: None,
|
||||
jobs: cx.jobs,
|
||||
};
|
||||
command.execute(&mut ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn shell_prompt(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) {
|
||||
|
@ -2263,6 +2263,14 @@ fn pipe_to(
|
||||
pipe_impl(cx, args, event, &ShellBehavior::Ignore)
|
||||
}
|
||||
|
||||
fn pipe_execute(
|
||||
cx: &mut compositor::Context,
|
||||
args: &[Cow<str>],
|
||||
event: PromptEvent,
|
||||
) -> anyhow::Result<()> {
|
||||
pipe_impl(cx, args, event, &ShellBehavior::Execute)
|
||||
}
|
||||
|
||||
fn pipe(cx: &mut compositor::Context, args: &[Cow<str>], event: PromptEvent) -> anyhow::Result<()> {
|
||||
pipe_impl(cx, args, event, &ShellBehavior::Replace)
|
||||
}
|
||||
@ -3092,6 +3100,13 @@ fn read(cx: &mut compositor::Context, args: &[Cow<str>], event: PromptEvent) ->
|
||||
fun: pipe_to,
|
||||
signature: CommandSignature::none(),
|
||||
},
|
||||
TypableCommand {
|
||||
name: "pipe-execute",
|
||||
aliases: &[],
|
||||
doc: "Pipe each selection to the shell command, execute output as command.",
|
||||
fun: pipe_execute,
|
||||
signature: CommandSignature::none(),
|
||||
},
|
||||
TypableCommand {
|
||||
name: "run-shell-command",
|
||||
aliases: &["sh"],
|
||||
|
@ -328,6 +328,7 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
|
||||
"!" => shell_insert_output,
|
||||
"A-!" => shell_append_output,
|
||||
"$" => shell_keep_pipe,
|
||||
"A-$" => shell_pipe_execute,
|
||||
"C-z" => suspend,
|
||||
|
||||
"C-a" => increment,
|
||||
|
Loading…
Reference in New Issue
Block a user