@@ -1116,6 +1116,43 @@ fn pipe(
1119+fn run_shell_command(
1120+ cx: &mut compositor::Context,
1122+ _event: PromptEvent,
1123+) -> anyhow::Result<()> {
1124+ let shell = &cx.editor.config().shell;
1125+ let (output, success) = shell_impl(shell, &args.join(" "), None)?;
1127+ cx.editor.set_status("Command succeed");
1129+ cx.editor.set_error("Command failed");
1132+ if !output.is_empty() {
1133+ let callback = async move {
1134+ let call: job::Callback =
1135+ Box::new(move |editor: &mut Editor, compositor: &mut Compositor| {
1136+ let contents = ui::Markdown::new(
1137+ format!("```sh\n{}\n```", output),
1138+ editor.syn_loader.clone(),
1140+ let mut popup = Popup::new("shell", contents);
1141+ popup.set_position(Some(helix_core::Position::new(
1142+ editor.cursor().0.unwrap_or_default().row,
1145+ compositor.replace_or_push("shell", popup);
1150+ cx.jobs.callback(callback);
1119pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
1156pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
1120 TypableCommand {
1157 TypableCommand {
1121 name: "quit",
1158 name: "quit",
@@ -1561,6 +1598,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
1561 fun: pipe,
1598 fun: pipe,
1562 completer: None,
1599 completer: None,
1602+ name: "run-shell-command",
1604+ doc: "Run a shell command",
1605+ fun: run_shell_command,
1606+ completer: Some(completers::directory),
1566pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> =
1610pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> =