Skip to content
nobsprompt
Esc
navigateopen⌘Jpreview
On this page

Data and lifecycle

Reference the complete NBSP_DATA schema, asynchronous update lifecycle, safe prompt escaping, and first-refresh behavior.

Update lifecycle

After every precmd, detached mode atomically replaces the global NBSP_DATA associative array with one complete schema. A background Git refresh can later replace it again and ask ZLE to redraw.

Register prompt functions in nbsp_data_update_functions:

my_prompt_update() {
  # Assign PROMPT and/or RPROMPT here.
}

nbsp_data_update_functions+=(my_prompt_update)
my_prompt_update

Callbacks run only after a complete schema has been parsed. Their output is not hidden or redirected.

Data schema

Key Meaning
schema_version Data contract version, currently 1
cwd Full working directory
path Abbreviated display path
status Previous command’s exact exit status
duration_ms Previous command duration in milliseconds
jobs Background job count
node_version Active NVM version, or empty
git_present 1 inside a repository
git_valid 1 when counters came from a valid cache snapshot
git_branch Branch name or short detached commit
git_updated_ms Snapshot wall-clock timestamp in milliseconds
git_staged Staged path count
git_modified Modified path count
git_untracked Untracked path count
git_conflicted Conflicted path count
git_ahead Commits ahead of upstream
git_behind Commits behind upstream
git_stashes Stash count

Consumers should require a schema version they understand, address records by key rather than position, and ignore unknown keys added by a compatible future version.

First repository prompt

On the first prompt in a repository, git_present may be 1 while git_valid is 0. The branch can still be read directly from Git metadata, while detailed counters remain zero. The asynchronous refresh then publishes a complete snapshot and redraws the prompt.

Use git_valid when your presentation needs to distinguish a confirmed zero from counters that have not arrived:

if [[ ${NBSP_DATA[git_valid]} == 0 ]]; then
  git_state=" ..."
fi

Safe prompt text

Zsh treats % and control bytes specially during prompt expansion. Escape dynamic values before inserting them:

nbsp_prompt_escape "${NBSP_DATA[path]}"
local safe_path=$REPLY

nbsp_prompt_escape:

  • writes the escaped value to REPLY;
  • replaces control bytes with ?;
  • doubles %;
  • does not start a process.

Do not insert unescaped raw fields into PROMPT, RPROMPT, or a PROMPT_SUBST expression.

Prompt substitution

Callbacks can prepare escaped values while PROMPT_SUBST performs final expansion on each redraw:

setopt promptsubst

typeset -g MY_PATH MY_BRANCH
prepare_prompt_data() {
  nbsp_prompt_escape "${NBSP_DATA[path]}"
  MY_PATH=$REPLY
  nbsp_prompt_escape "${NBSP_DATA[git_branch]}"
  MY_BRANCH=$REPLY
}

nbsp_data_update_functions+=(prepare_prompt_data)
prepare_prompt_data

PROMPT='${MY_PATH}${MY_BRANCH:+ [${MY_BRANCH}]} %# '

OSC sequences

Detached mode leaves terminal control sequences under your ownership. It updates NBSP_DATA and requests a redraw, but does not replace or interpret OSC wrappers in your prompt.

See Prompt recipes for a complete terminal-title example.