Rush reads interactive configuration from Rush scripts.
Interactive startup sources these files in order. Later files override earlier ones. Missing files are skipped.
embedded default configuration (ships inside the rush binary) $ENV $sysconfdir/rush/profile.rush (login shells only) $XDG_CONFIG_HOME/rush/profile.rush (login shells only) $sysconfdir/rush/config.rush $XDG_CONFIG_HOME/rush/config.rush
Rush expands $ENV with shell parameter expansion before sourcing it. It does not apply field splitting or pathname expansion.
If $XDG_CONFIG_HOME is unset, user paths use $HOME/.config/rush/. $sysconfdir defaults to etc under the install prefix; packagers can set it with zig build -Dsysconfdir=/etc.
Point $ENV at a trusted file. Rush accepts relative expanded $ENV paths against the current directory and is not designed for setuid/setgid installation.
Interactive command history is stored in $XDG_STATE_HOME/rush/history.sqlite, falling back to $HOME/.local/state/rush/history.sqlite when $XDG_STATE_HOME is unset.
The embedded defaults come from share/rush/config.rush and define the default prompt, style defaults, and ll/la abbreviations. Redefine or abbr --erase them in a later file to opt out.
Rush-mode shells load functions lazily from rush/functions search directories. A file named foo.rush is the autoload source for a function named foo. Rush sources that file the first time foo is used as a command name, instead of sourcing every function during startup.
$XDG_CONFIG_HOME/rush/functions/foo.rush foo() { printf 'hello from foo\n' }
If $XDG_CONFIG_HOME is unset, user function files fall back to $HOME/.config/rush/functions.
Function autoload lookup searches configuration directories before data directories, in this order:
$XDG_CONFIG_HOME/rush/functions $sysconfdir/rush/functions $XDG_DATA_HOME/rush/functions each $XDG_DATA_DIRS entry + /rush/functions $datadir/rush/functions
$XDG_DATA_HOME falls back to $HOME/.local/share. When $XDG_DATA_DIRS is unset, Rush searches /usr/local/share and /usr/share.
If a name exists in more than one directory, the first matching file wins. Shipped autoload functions in share/rush/functions include colorized ls/grep/diff helpers, path_add/path_prepend/path_append/path_remove PATH helpers, and opt-in project environment hooks.
path_prepend $HOME/.local/bin path_append ./node_modules/.bin path_remove /old/toolchain/bin
path_add is the same as path_prepend. The add/prepend/append helpers skip missing directories and keep only one copy of each added path.
Command and function-name completion include autoloadable functions without sourcing them. unset -f foo removes a loaded foo function and suppresses future autoload of foo in the current shell. Defining foo() again clears that suppression. POSIX mode does not autoload Rush functions.
Use abbr for fish-style interactive text expansion in the line editor.
abbr gs 'git status' abbr ga 'git add' abbr gc 'git commit' abbr --list abbr --erase gs
Abbreviations expand only in the interactive editor. Space, Enter, or Tab rewrites a matching command word before execution. Tab expands first, then completes the expanded command.
Use abbr for editor text expansion. Use alias for shell command aliasing in executed code.
Place abbr commands in your Rush configuration file to persist them across interactive sessions.
Configure interactive colors with semantic lowercase shell variables. Values are comma-separated style options.
rush_style() {
if test "$rush_color_scheme" = light; then
accent=blue
flash='fg=white,bg=black'
fallback_bg='#ffffff'
else
accent=cyan
flash='fg=black,bg=white'
fallback_bg='#000000'
fi
directory_color=$(color dim "${rush_color_blue-#0000ff}" 20)
rush_style_directory="fg=$directory_color"
rush_style_selection="fg=$accent,bold"
rush_style_muted="fg=$(color blend "${rush_color_foreground-#c0c0c0}" "${rush_color_background-$fallback_bg}" 45)"
rush_style_flash="$flash"
rush_style_match='fg=yellow,bold'
rush_style_error='ul=curly,ul_color=red'
}
If rush_style exists, Rush calls it at interactive startup and after terminal color changes. Rush reads semantic rush_style_* variables before each prompt, so later assignments apply on the next prompt.
Before each color-scheme call, Rush sets these Rush-owned variables for the hook:
| Variable | Value |
|---|---|
rush_color_scheme | dark, light, or unknown |
rush_color_foreground | Terminal foreground as #rrggbb, when reported |
rush_color_background | Terminal background as #rrggbb, when reported |
rush_color_black | Terminal black palette entry as #rrggbb, when reported |
rush_color_red | Terminal red palette entry as #rrggbb, when reported |
rush_color_green | Terminal green palette entry as #rrggbb, when reported |
rush_color_yellow | Terminal yellow palette entry as #rrggbb, when reported |
rush_color_blue | Terminal blue palette entry as #rrggbb, when reported |
rush_color_magenta | Terminal magenta palette entry as #rrggbb, when reported |
rush_color_cyan | Terminal cyan palette entry as #rrggbb, when reported |
rush_color_white | Terminal white palette entry as #rrggbb, when reported |
RGB variables exist only after the terminal reports them. Use normal shell fallbacks when needed.
Supported options are fg=<color>, bg=<color>, ul=<style>, ul_color=<color>, bold, dim, italic, reverse, and strike. Underline styles are none, single, double, curly, dotted, and dashed.
Colors use the same names as prompt colors: default, black, red, green, yellow, blue, magenta, cyan, white, their bright- variants, index:N or N for 256-color palette entries, and #rrggbb truecolor values.
Use color dim COLOR PERCENT and color blend COLOR COLOR PERCENT to derive truecolor style values. Invalid input exits 2, writes stderr, and writes no stdout.
Available style variables are:
| Variable | Styled role |
|---|---|
rush_style_selection | Selected UI item |
rush_style_command | Command-like text |
rush_style_plain | Plain completion text |
rush_style_directory | Directory paths and directory completion candidates |
rush_style_option | Command options |
rush_style_variable | Shell variables |
rush_style_function | Shell functions |
rush_style_file | File paths and file completion candidates |
rush_style_muted | Secondary text, summaries, descriptions, and autosuggestions |
rush_style_flash | Transient completion flash feedback |
rush_style_match | Search or fuzzy-match highlight |
rush_style_error | Errors and invalid input underline |
rush_style_comment | Input comments |
rush_style_quote | Quoted input |
rush_style_pending | Pending or incomplete input |
rush_style_reserved | Reserved words such as if and for |
rush_style_operator | Control and redirection operators |
Invalid style values are ignored and the default for that role is used.
The default prompt shows the current directory, Git branch, dirty marker, upstream counts, and a status marker. Prompt or completion activity animates the marker. Failed commands turn it red.
Define rush_prompt in your configuration to replace it.
rush_prompt() { prompt segment --fg blue "$(prompt_pwd)" prompt text ' ● ' }
The prompt command is only available while Rush is rendering the prompt.
After you press Enter, Rush redraws the accepted command with rush_prompt_transient when that function exists. The next editable prompt still uses rush_prompt. Use this to keep scrollback compact while leaving the full prompt visible during editing.
rush_prompt_transient() { if test "$?" = 0; then prompt text '● ' else prompt segment --fg red '● ' fi }
Unset rush_prompt_transient to leave accepted prompts unchanged.
Define rush_prompt_right to render text flush-right on the editable input line. Rush hides it automatically when the input would collide with it, and it is not kept in the accepted command line.
rush_prompt_right() { if test "$(prompt_duration)" != ""; then prompt segment --dim "$(prompt_duration)" fi }
prompt text TEXT... prompt segment [OPTIONS] TEXT... prompt async KEY --ttl MS [OPTIONS] [--prefix TEXT] -- COMMAND... prompt newline prompt async-pending
Use prompt text for plain text, prompt segment for styled text, prompt async for cached background prompt data, prompt newline for a new line, and prompt async-pending to test active async prompt work.
--fg COLOR --bg COLOR --bold --dim --italic --underline --reverse --strikethrough
Colors may be named colors, 256-color indexes, or RGB hex values.
blue
bright-blue
index:236
'#7aa2f7'
prompt_pwd [-d N] [-D N] # current directory, with $HOME shortened to ~ prompt_duration # previous command duration
prompt_pwd shortens paths like fish. -d/--dir-length keeps the first N characters of each component. -D/--full-length-dirs keeps the last N components at full length.
prompt_pwd # ~/repos/rush prompt_pwd -d 1 # ~/r/rush prompt_pwd -d 1 -D 2 # ~/repos/rush
Rush ships opt-in helpers for tools that export per-directory environments. They use rush_env so config does not need to evaluate tool-generated shell code.
event add directory.change direnv rush_direnv_hook event add directory.change mise rush_mise_hook
rush_direnv_hook and rush_mise_hook are shipped autoload functions. rush_direnv_hook runs direnv export json. rush_mise_hook runs mise hook-env -s bash --quiet and accepts only environment mutations. Neither helper is registered by default.
Keep prompts fast. Use prompt async for slow data such as Git status. Use timer.tick hooks for values that change while the editor is idle.
prompt async KEY --ttl MS [OPTIONS] [--prefix TEXT] -- COMMAND...
prompt async appends cached stdout immediately, using the same style options as prompt segment. When the cache is missing or stale, Rush starts COMMAND hidden and keeps rendering from the old value, or nothing. When the command exits, Rush redraws the prompt. Cache keys include the current directory and explicit key.
For animations, store the frame in a shell variable and advance it from a timer.tick hook while activity is active.
rush_prompt() { prompt segment --fg bright-blue "$(prompt_pwd)" prompt async git-branch --ttl 5000 --prefix ' ' --fg green -- git branch --show-current prompt text ' ● ' }
Save $? before running other commands in a prompt if you want to display the previous command status.
rush_prompt() { status="$?" if test "$status" != 0; then prompt segment --fg red "status $status" prompt text ' ' fi prompt segment --fg bright-blue "$(prompt_pwd)" prompt text ' ● ' }
Use event for advanced interactive hooks. Hooks preserve the visible $? by default.
prompt.prepare: before each prompt render.directory.change: after cd, and once at startup with an empty $1; receives old and new directories as $1 and $2.timer.tick: while the editor is idle; receives the registration name as $1.$1 and active count as $2.event add EVENT NAME FUNCTION [--priority N] event add timer.tick NAME FUNCTION --every MS [--priority N] event remove EVENT NAME event list [EVENT]
on_prompt_prepare() { # Update cheap prompt variables before rendering. } on_directory_change() { # $1 is the old directory; $2 is the new directory. rush_last_directory="$2" } on_clock() { CLOCK="$(date +%H:%M:%S)" } event add prompt.prepare prompt-vars on_prompt_prepare event add directory.change cwd-repaint on_directory_change event add timer.tick clock on_clock --every 1000
Use event list to inspect hooks. Reusing an event/name pair replaces that hook. Use event remove EVENT NAME to remove it.
event list event list directory.change event remove directory.change cwd-repaint
Common recipes: register project environment hooks on directory.change, precompute prompt variables in prompt.prepare, and use timer.tick for clocks.
Prefer prompt async, timers, and hooks over slow command substitutions in rush_prompt.
If rush_prompt is not defined, Rush uses PS1. Unset the default function to use a plain PS1 prompt.
unset -f rush_prompt PS1='rush● ' PS2='> '
File: $HOME/.config/rush/config.rush
rush_prompt() { prompt segment --fg bright-blue "$(prompt_pwd)" if test "$(prompt_duration)" != ""; then prompt text ' ' prompt segment --dim "$(prompt_duration)" fi prompt text ' ● ' }