run-shell.hx
A blocking version of :run-shell-command for Helix
- Stars: 4
- Last commit:
- Created:
A blocking version of :run-shell-command for Helix
A synchronous :run-shell-command for Helix, built on
run-command.scm.
Helix’s own :run-shell-command hands the command to a background job and
returns immediately. Nothing comes back to the caller, the exit code is
invisible, and the popup shows one stream only: on failure stderr replaces
stdout, and a command that warns while succeeding has its stdout thrown away.
:run-shell-command-sync blocks until the command exits, then shows both
captured streams and the real exit status.
Install with forge, Steel’s package manager:
forge pkg install --git https://github.com/waddie/run-shell.hx
Then in ~/.config/helix/init.scm:
(require "run-shell.hx/run-shell.scm")
| command | effect |
|---|---|
:run-shell-command-sync <cmd...> | run cmd under /bin/sh -c and wait for it |
:run-shell-timeout <milliseconds> | set the timeout for the rest of the session |
Arguments are joined with a single space before being handed to the shell,
which is what Helix does with its own :run-shell-command.
%{...} expansions work, resolved by
expansions.hx:
:run-shell-command-sync wc -l %{file_path_absolute}
:run-shell-command-sync git log --oneline -5 -- %{buffer_name}
Helix expands these for its own commands only, so a Steel command has to do it
itself. The full upstream syntax is supported, %sh{} and %reg{} included,
and a malformed or unknown expansion reports on the status line without running
anything. As upstream, a bare % is an error: printf format strings need
their percents doubled.
Values are inserted raw, as Helix inserts them, so quote what might contain
spaces: wc -l "%{file_path_absolute}".
The result overlay is read-only and owns every keypress while it is open:
| key | effect |
|---|---|
Escape, q, Ret | close |
j, k, ↓, ↑ | scroll a line |
C-d, C-u | scroll ten lines |
g, G, Home,End | top, bottom |
Both streams are shown in one block, stderr under a --- stderr --- marker.
With both empty there is no overlay, only the status line. Exit status lands on
the status line: run-shell: exit 0 for success, the code as an error
otherwise, and a distinct message when the timeout fired.
show-command-result! takes a run-command result hash and reports it the way
the command does, for plugins that run their own subprocesses:
(require "run-shell.hx/run-shell.scm")
(require "run-command/run-command.scm")
(show-command-result! (run-argv "git" (list "status" "--short")))
The pure formatting layer is tested headlessly. Requires steel-test and ui-utils.hx installed.
steel test/format-test.scm
The overlay itself needs a running Helix, so it is not covered.
Copyright © 2026 Tom Waddington
Distributed under the MIT License. See LICENSE file for details.