Autosuggestions
Use recent-history ghost text and point-in-time, path-aware directory suggestions without blocking foreground filesystem work.
The recommended setup enables autosuggestions with either prompt mode:
eval "$(nbsp init zsh --autosuggest)"
This is intentionally smaller than fish completion. It predicts one complete line; it does not generate option descriptions, parse command grammars, or replace Tab completion.
Selection order
At initialization, nobsprompt snapshots up to 4,096 nonempty history values
while examining at most 8,192 descending Zsh event numbers. It updates that
snapshot at each precmd, including the newest command when Zsh’s history ring
is full. Ordinary commands search the snapshot for an exact, case-sensitive
prefix. A chosen candidate can be reused while subsequent input still matches
it, but all redraw eligibility checks - including the queued-input check - run
before either cached reuse or a fresh search.
Safely parseable cd paths use a different rule: a validated point-in-time
directory snapshot gates candidates and history is only a ranking signal.
Nobsprompt:
- resolves the parent implied by the typed path;
- asynchronously reads that parent’s immediate child directories;
- offers the single captured prefix match; or
- when several captured children match, chooses the newest one also represented
by matching
cdhistory.
A historical directory missing when the parent snapshot is captured is not
offered from that snapshot. For example, if history contains
cd ~/Desktop/programming/work but only web/ exists, typing
cd ~/Desktop/programming/w suggests eb/, not ork.
cd al stays empty when both alpha/ and alpine/ exist and neither has a
matching history rank. Ordinary Tab completion remains available for every
ambiguous or unsupported case.
Suggestions are suppressed for multiline input, leading whitespace, selections, a cursor before the end of the buffer, prefixes longer than 256 characters, complete results longer than 4,096 characters, and queued input. The engine does not separately label a buffer as typed versus recalled from history.
Supported directory paths
Path-aware suggestions accept one static operand in cd PATH or cd -- PATH.
They support:
- immediate and nested relative paths such as
cd src/n; - explicit
./and../parents; - absolute paths;
~/paths;- closed quotes and backslash-escaped spaces.
The parser performs Zsh lexical splitting and quote removal only. It never
evaluates the command. It rejects operands whose source contains $,
backticks, *, ?, [, ], {, }, (, ), <, >, |, &, ;,
^, or #, including quoted or backslash-escaped forms. Named directories
such as ~user, an unquoted operand source beginning with =, unmatched
quotes, multiple operands, and a leading - without cd -- also remain
ordinary history or Tab-completion territory.
Explicit ., .., ./…, and ../… operands resolve from $PWD and bypass
cdpath, as they do in Zsh. For other relative operands, nobsprompt scans
$PWD only when it can prove that Zsh will try the current directory first.
With POSIX_CD unset, that is true
when cdpath is empty, when it contains no . or empty component (Zsh then
tries $PWD implicitly first), or when its first component is . or empty. If
a nonlocal component precedes an explicit . or empty component, nobsprompt
does not guess. With POSIX_CD set, cdpath must be empty or its first
component must be . or empty; otherwise cdpath is searched before the
implicit current directory.
This is the search order documented for Zsh cd
and POSIX_CD.
The engine does not scan multiple CDPATH roots. If it cannot prove that its
single $PWD snapshot describes the directory Zsh would choose, it leaves the
case to history and Tab completion. Explicit dot-relative, absolute, and ~/
paths do not use CDPATH. A bare path without the cd command is ordinary
command history because Zsh would try to execute it.
Directory cost and safety
The filesystem is not traversed on each keypress. The first eligible path
starts one asynchronous nbsp dirs process for its resolved parent. Nested
input such as ~/Desktop/programming/w still reads only the immediate children
of ~/Desktop/programming; it does not walk from the home directory. The result
is published only after a complete NUL-framed snapshot arrives. The worker has
hard limits of:
- 50 ms;
- 1,024 immediate child directories;
- 64 KiB of records.
It reads one level only, includes directory symlinks, and performs no recursive
walk. A timeout, malformed frame, changed working directory, changed typed
parent, closed descriptor, or exceeded limit discards the partial snapshot and
shows no cd suggestion. It never falls back to an unvalidated history path.
A valid snapshot is sorted once and keyed by its parent. Prefix and history
membership checks use binary search without filesystem syscalls. The snapshot
is reused while the parent remains unchanged, replaced when input moves to a
different parent, and invalidated at precmd and chpwd boundaries. It is not
continuously revalidated: a child created or removed after capture may remain
absent or present until invalidation, and a suggested path can disappear before
acceptance. Appended directory text is shell-quoted before display or
insertion; names are data, never evaluated as Zsh source.
Accepting and controlling suggestions
Right Arrow accepts ghost text in Zsh’s native Emacs and Vi insert keymaps.
Nobsprompt claims a terminal sequence only when it is still bound to the
keymap’s built-in forward-char or vi-forward-char widget during
initialization. Existing user or plugin bindings are preserved.
The widgets are public for explicit bindings:
bindkey '^F' nbsp-autosuggest-accept
bindkey '^X^A' nbsp-autosuggest-toggle
Acceptance is ownership-checked: it inserts text only when the current
POSTDISPLAY still equals the suffix produced by nobsprompt. Otherwise it
falls back to the keymap’s original character-movement widget. Highlight
ownership is similarly narrow, so unrelated ZLE integrations keep their
display state.
Tab remains Zsh completion; it does not accept nobsprompt ghost text. An
ambiguous completion can print a candidate list below the prompt, and Zsh’s
default ALWAYS_LAST_PROMPT behavior leaves that list visible while returning
the cursor to the command line. This is native completion output. To stop Zsh
from listing ambiguous candidates automatically, add this separately to your
shell configuration:
unsetopt AUTO_LIST
Nobsprompt deliberately does not clear completion lists or wrap completion widgets, so command-specific completions and completion plugins keep control.
Set the ghost-text style before initialization if the default fg=8 does not
fit the terminal palette:
typeset -g NBSP_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=242'
eval "$(nbsp init zsh --autosuggest)"
Plugin compatibility
If another engine is already loaded, nobsprompt reports the conflict and skips
its own engine without setting its initialization guard. After removing that
early conflict, re-sourcing nbsp init zsh --autosuggest can initialize the
engine; repeated successful sourcing does not duplicate its hooks. If a
conflicting engine appears later, nobsprompt disables itself and warns once at
the next safe precmd boundary. Redraw-time detection remains silent and
fail-closed so a warning cannot corrupt the active command line.
Nobsprompt does not wrap every widget or overwrite custom Right Arrow bindings.
Unknown integrations that also own ZLE POSTDISPLAY are not guaranteed to be
compatible, so configure only one ghost-text provider.
Without --autosuggest, the emitted Zsh integration and prompt behavior are
unchanged.