Configuration

Rush reads interactive configuration from Rush scripts.

Files

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.

Autoloaded functions

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.

Abbreviations

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.

UI styles

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:

VariableValue
rush_color_schemedark, light, or unknown
rush_color_foregroundTerminal foreground as #rrggbb, when reported
rush_color_backgroundTerminal background as #rrggbb, when reported
rush_color_blackTerminal black palette entry as #rrggbb, when reported
rush_color_redTerminal red palette entry as #rrggbb, when reported
rush_color_greenTerminal green palette entry as #rrggbb, when reported
rush_color_yellowTerminal yellow palette entry as #rrggbb, when reported
rush_color_blueTerminal blue palette entry as #rrggbb, when reported
rush_color_magentaTerminal magenta palette entry as #rrggbb, when reported
rush_color_cyanTerminal cyan palette entry as #rrggbb, when reported
rush_color_whiteTerminal 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:

VariableStyled role
rush_style_selectionSelected UI item
rush_style_commandCommand-like text
rush_style_plainPlain completion text
rush_style_directoryDirectory paths and directory completion candidates
rush_style_optionCommand options
rush_style_variableShell variables
rush_style_functionShell functions
rush_style_fileFile paths and file completion candidates
rush_style_mutedSecondary text, summaries, descriptions, and autosuggestions
rush_style_flashTransient completion flash feedback
rush_style_matchSearch or fuzzy-match highlight
rush_style_errorErrors and invalid input underline
rush_style_commentInput comments
rush_style_quoteQuoted input
rush_style_pendingPending or incomplete input
rush_style_reservedReserved words such as if and for
rush_style_operatorControl and redirection operators

Invalid style values are ignored and the default for that role is used.

Prompt

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.

Transient 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.

Right prompt

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 commands

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.

Segment options

--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'

Helpers

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

Project environments

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.

Async prompt updates

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 ' ● '
}

Hooks and intervals

Use event for advanced interactive hooks. Hooks preserve the visible $? by default.

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.

PS1 fallback

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='> '

Example

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 ' ● '
}