@@ -4150,19 +4150,19 @@ enum ShellBehavior {
4152fn shell_pipe(cx: &mut Context) {
4152fn shell_pipe(cx: &mut Context) {
4153− shell(cx, "pipe:".into(), ShellBehavior::Replace);
4153+ shell_prompt(cx, "pipe:".into(), ShellBehavior::Replace);
4156fn shell_pipe_to(cx: &mut Context) {
4156fn shell_pipe_to(cx: &mut Context) {
4157− shell(cx, "pipe-to:".into(), ShellBehavior::Ignore);
4157+ shell_prompt(cx, "pipe-to:".into(), ShellBehavior::Ignore);
4160fn shell_insert_output(cx: &mut Context) {
4160fn shell_insert_output(cx: &mut Context) {
4161− shell(cx, "insert-output:".into(), ShellBehavior::Insert);
4161+ shell_prompt(cx, "insert-output:".into(), ShellBehavior::Insert);
4164fn shell_append_output(cx: &mut Context) {
4164fn shell_append_output(cx: &mut Context) {
4165− shell(cx, "append-output:".into(), ShellBehavior::Append);
4165+ shell_prompt(cx, "append-output:".into(), ShellBehavior::Append);
4168fn shell_keep_pipe(cx: &mut Context) {
4168fn shell_keep_pipe(cx: &mut Context) {
@@ -4256,65 +4256,69 @@ fn shell_impl(
4256 Ok((tendril, output.status.success()))
4256 Ok((tendril, output.status.success()))
4259−fn shell(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) {
4259+fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {
4260 let pipe = match behavior {
4260 let pipe = match behavior {
4261 ShellBehavior::Replace | ShellBehavior::Ignore => true,
4261 ShellBehavior::Replace | ShellBehavior::Ignore => true,
4262 ShellBehavior::Insert | ShellBehavior::Append => false,
4262 ShellBehavior::Insert | ShellBehavior::Append => false,
4265+ let config = cx.editor.config();
4266+ let shell = &config.shell;
4267+ let (view, doc) = current!(cx.editor);
4268+ let selection = doc.selection(view.id);
4270+ let mut changes = Vec::with_capacity(selection.len());
4271+ let text = doc.text().slice(..);
4273+ for range in selection.ranges() {
4274+ let fragment = range.fragment(text);
4275+ let (output, success) = match shell_impl(shell, cmd, pipe.then(|| fragment.as_bytes())) {
4276+ Ok(result) => result,
4278+ cx.editor.set_error(err.to_string());
4284+ cx.editor.set_error("Command failed");
4288+ let (from, to) = match behavior {
4289+ ShellBehavior::Replace => (range.from(), range.to()),
4290+ ShellBehavior::Insert => (range.from(), range.from()),
4291+ ShellBehavior::Append => (range.to(), range.to()),
4292+ _ => (range.from(), range.from()),
4294+ changes.push((from, to, Some(output)));
4297+ if behavior != &ShellBehavior::Ignore {
4298+ let transaction = Transaction::change(doc.text(), changes.into_iter());
4299+ doc.apply(&transaction, view.id);
4302+ // after replace cursor may be out of bounds, do this to
4303+ // make sure cursor is in view and update scroll as well
4304+ view.ensure_cursor_in_view(doc, config.scrolloff);
4307+fn shell_prompt(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) {
4265 ui::prompt(
4308 ui::prompt(
4268 Some('|'),
4311 Some('|'),
4269 ui::completers::none,
4312 ui::completers::none,
4270 move |cx, input: &str, event: PromptEvent| {
4313 move |cx, input: &str, event: PromptEvent| {
4271− let config = cx.editor.config();
4272− let shell = &config.shell;
4273 if event != PromptEvent::Validate {
4314 if event != PromptEvent::Validate {
4276 if input.is_empty() {
4317 if input.is_empty() {
4279− let (view, doc) = current!(cx.editor);
4280− let selection = doc.selection(view.id);
4282− let mut changes = Vec::with_capacity(selection.len());
4283− let text = doc.text().slice(..);
4285− for range in selection.ranges() {
4286− let fragment = range.fragment(text);
4287− let (output, success) =
4288− match shell_impl(shell, input, pipe.then(|| fragment.as_bytes())) {
4289− Ok(result) => result,
4291− cx.editor.set_error(err.to_string());
4297− cx.editor.set_error("Command failed");
4301− let (from, to) = match behavior {
4302− ShellBehavior::Replace => (range.from(), range.to()),
4303− ShellBehavior::Insert => (range.from(), range.from()),
4304− ShellBehavior::Append => (range.to(), range.to()),
4305− _ => (range.from(), range.from()),
4307− changes.push((from, to, Some(output)));
4310− if behavior != ShellBehavior::Ignore {
4311− let transaction = Transaction::change(doc.text(), changes.into_iter());
4312− doc.apply(&transaction, view.id);
4315− // after replace cursor may be out of bounds, do this to
4321+ shell(cx, input, &behavior);
4316− // make sure cursor is in view and update scroll as well
4317− view.ensure_cursor_in_view(doc, config.scrolloff);