-
The REPL is powered by Rustyline (default build).
-
It starts in vi mode and provides history, file completion, and lightweight highlighting.
-
When output is captured (non-tty stdout), the REPL inserts an inverted
$marker if the previous command did not end with a newline. -
When stdout is a tty, the REPL preserves tty semantics for interactive apps and does not capture output.
- default build includes the REPL
./install.sh --no-replbuilds a minimal stdin loop
Resolution order:
USH_HISTFILEHISTFILEXDG_DATA_HOME/unshell/histfile$HOME/.local/share/histfile
- The REPL appends new entries to the history file so multiple sessions can share the same file without clobbering each other's updates.
-
Startup sourcing applies to both REPL and script runs.
-
See
docs/spec.mdfor the order and flags. -
The default installer will drop a starter init at
/etc/unshell/initif missing. -
It only prints a message when
USH_MODE=repl.
-
default:
fzfif present, list completion otherwise -
list completion:
set repl.completion.mode list -
disable completion:
set repl.completion.mode off -
use fzf:
set repl.completion.mode fzf -
prompt command:
set repl.prompt.command 'echo "unshell> "'(runs once per line) -
The REPL passes file, command, or variable candidates to
fzfon stdin. -
It expects the same output shape as
fzf --print-query --expect=...(key line, query line, then selected lines). -
fzf runs with multi-select enabled; toggle selections with
ctrl-m/alt-m. -
tab/btabmove the cursor down/up without toggling selection. -
ctrl-y/alt-yselect all current matches and accept. -
ctrl-a/alt-aaccept selections and insert aPREFIX*wildcard when multiple entries share a prefix. -
ctrl-s/alt-saccept selections and insert a*SUFFIXwildcard when multiple entries share a suffix. -
List mode uses prefix matching and auto-completes when there is a single candidate.
-
If
fzfexits with status 1 (no matches with--exit-0), completion is treated as cancelled and does not fall back to list mode. -
Shift-Tab (
btab) triggers completion with the fzf cursor starting on the last match. -
Hidden entries (names starting with
.) are excluded unless the completion fragment includes a.segment (for example./,../, or.config). -
When completing inside quotes, the quoted fragment is used as the completion input.
-
If the quote is still open, file completions close the quote and add a trailing space; directory completions keep the quote open.
-
Variable completion triggers when the fragment starts with
$, using the current shell/environment variable names. -
Command completion triggers in command position (first word of a pipeline segment) and looks at builtins, functions, aliases, and
$PATH.
- strings (
'...'/"...") - built-ins and control keywords (
if,for,foreach,set, etc.) - comments starting with
#when preceded by whitespace
set repl.mode vi
set repl.mode emacs
set repl.completion.mode fzf
set repl.completion.mode list
set repl.completion.mode off
set repl.history.file default
set repl.history.file /tmp/ush-history
set repl.prompt.command 'echo "unshell> "'
set repl.prompt.command off
set repl.bracketed_paste on
set repl.bracketed_paste off
set repl.bind ctrl-e end-of-line
set repl.bind alt-f forward-word
set repl.bind tab complete
set repl.bind btab complete
set repl.bind left backward-word
set repl.bind right forward-word
set repl.bind ctrl-k kill-line
set repl.bind ctrl-a beginning-of-line
set repl.bind ctrl-e end-of-line
set repl.bind esc accept-line-
In vi mode,
#defaults tocomment-acceptunless overridden by a custom binding. -
set repl.history.file defaultrecomputes the history path using the resolution order above, even if it was already using the default path.
- If a function named
unshell_after_command_inputis defined, the REPL calls it after history is updated and before the command executes. - The raw input line is passed as
$1.
- letters with modifiers:
ctrl-a,alt-f - arrows:
left,right,up,down tab,btab,enter,esc,backspace
backward-wordforward-wordbeginning-of-lineend-of-linekill-lineaccept-linehistory-search-backwardhistory-search-forwardcompletecomment-accept(submit line with#prepended when in vi normal mode)insert:TEXTorinsert TEXT
To remove a binding:
set repl.bind ctrl-e offBracketed paste defaults to off in vi mode and on in emacs mode; use set repl.bracketed_paste on|off to override.