Open-Source Wikis

/

Starship

/

Subsystems

/

Init scripts

starship/starship

Init scripts

The shell-specific glue that wires starship into the user's shell-redraw hook. The orchestration lives in src/init/mod.rs and the per-shell scripts in src/init/starship.<shell>.

The two-phase init

Why is there a "stub" and a "full init"? Because eval $(...) in many shells evaluates its argument as a single line, so multi-line scripts with comments (which all of these are) need to be sourced from a process substitution. To keep the user-facing snippet short and the full script readable, Starship prints a tiny stub that re-invokes itself with --print-full-init, then sources the result.

sequenceDiagram
    participant RC as ~/.bashrc
    participant Starship as starship
    participant Bash

    RC->>Starship: eval $(starship init bash)
    Starship-->>Bash: eval -- "$(starship init bash --print-full-init)"
    Bash->>Starship: starship init bash --print-full-init
    Starship-->>Bash: full init script (string)
    Bash->>Bash: eval the full script
    Note over Bash: Now PROMPT_COMMAND, DEBUG trap, etc. are set

The stub for each shell is computed in init_stub in src/init/mod.rs. For most shells it is a single line (eval -- "$(starship init bash --print-full-init)"). For zsh, nu, and cmd, the full init is short enough that the stub is the full init.

The full scripts are embedded into the binary at compile time via include_str!:

const BASH_INIT: &str = include_str!("starship.bash");
const ZSH_INIT:  &str = include_str!("starship.zsh");
// ...

StarshipPath resolves the path of the running starship binary (via which::which then current_exe) and quotes it for each shell's syntax (sprint_posix, sprint_pwsh, sprint_elv, sprint_cmdexe). The placeholder ::STARSHIP:: in each init template is replaced with this quoted path before printing.

Supported shells

| Shell | Stub strategy | Full script | | ---------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | Bash | eval -- "$(starship init bash --print-full-init)" | src/init/starship.bash | | Zsh | inline-print ZSH_INIT | src/init/starship.zsh | | Fish | source ($starship init fish --print-full-init | psub) | src/init/starship.fish | | PowerShell | Invoke-Expression (& '...' init powershell --print-full-init | Out-String) | src/init/starship.ps1 | | Ion | eval $(starship init ion --print-full-init) | src/init/starship.ion | | Elvish | eval (starship init elvish --print-full-init | slurp) | src/init/starship.elv | | Tcsh | backtick eval | src/init/starship.tcsh | | Nushell | inline-print NU_INIT | src/init/starship.nu | | Xonsh | execx($(starship init xonsh --print-full-init)) | src/init/starship.xsh | | Cmd | inline starship.lua for Clink | src/init/starship.lua |

What the full scripts do

Every full init does roughly the same five things:

  1. Set STARSHIP_SHELL so the binary's Context::get_shell knows which shell is running.
  2. Hook the redraw cycle — bash uses PROMPT_COMMAND + DEBUG trap; zsh uses precmd + preexec + trap DEBUG; fish uses the built-in fish_prompt/fish_right_prompt functions; PowerShell uses prompt; Nushell sets PROMPT_COMMAND; etc.
  3. Capture state at the start of each command — typically the start time (for cmd_duration).
  4. Capture state at the end of each command and call starship prompt with --status=$?, --pipestatus=…, --cmd-duration=…, --jobs=$#, --keymap=…, --terminal-width=$COLUMNS, --shlvl=$SHLVL, etc.
  5. Render the right prompt and continuation prompt if those are enabled.

Bash specifics

The bash script is the most baroque. It needs:

  • A starship_preexec callback that runs before every pipeline command, even ones inside pipes (the bash DEBUG trap fires per command). A STARSHIP_PREEXEC_READY flag is used to avoid restarting the timer for downstream pipe commands.
  • A _starship_set_return helper because bash does not allow assigning to $?.
  • A workaround for a long-standing bash bug where jobs reports completed background processes as still running inside PROMPT_COMMAND — see issue #5159 and the linked bash bug-list thread.
  • Compatibility with both BLE.sh (BLE_PIPESTATUS, BLE_ATTACHED) and bash-preexec (BP_PIPESTATUS).

Fish specifics

The fish script juggles fish key-binding modes for vi-mode reporting. It also implements two ways to count background jobs:

  • Default: jobs -g (job groups). Avoids overcounting pipelines with terminated producers.
  • Legacy: jobs -p (PIDs). Toggleable via set -g __starship_fish_use_job_groups "false".

It implements transient prompts via the --final-rendering flag plus a starship_transient_prompt_func user hook.

PowerShell specifics

The PowerShell script handles three levels of behavior:

  • A standard prompt function that calls starship prompt.
  • A right-prompt rendering using $PSStyle ANSI escape sequences plus terminal cursor manipulation.
  • Continuation prompt support detected by checking if the previous line ended with backtick or open brace.

Init for completion vs init for prompts

Note that starship init <shell> (init the prompt hook) is different from starship completions <shell> (generate shell completions for the starship binary itself). The latter uses clap_complete and writes a one-off completion file; the former is what the user evals on every shell start.

Entry points for modification

  • Adding a new shell: add a variant to the Shell enum in src/context.rs, dispatch it in Context::get_shell, add a stub branch in init_stub and a full-init branch in init_main (both in src/init/mod.rs), and create src/init/starship.<newshell> with the rendering hook.
  • Tuning the bash bug workarounds: edit src/init/starship.bash. The git log there is full of context (issues #241, #278, #1674, #5020, #5382 are linked from the file itself).
  • Wiring a new flag through the init scripts: add it to Properties (and the --flag clap derive in src/context.rs), then update each src/init/starship.<shell> script to compute and pass it.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Init scripts – Starship wiki | Factory