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 setThe 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:
- Set
STARSHIP_SHELLso the binary'sContext::get_shellknows which shell is running. - Hook the redraw cycle — bash uses
PROMPT_COMMAND+DEBUGtrap; zsh usesprecmd+preexec+trap DEBUG; fish uses the built-infish_prompt/fish_right_promptfunctions; PowerShell usesprompt; Nushell setsPROMPT_COMMAND; etc. - Capture state at the start of each command — typically the start time (for
cmd_duration). - Capture state at the end of each command and call
starship promptwith--status=$?,--pipestatus=…,--cmd-duration=…,--jobs=$#,--keymap=…,--terminal-width=$COLUMNS,--shlvl=$SHLVL, etc. - Render the right prompt and continuation prompt if those are enabled.
Bash specifics
The bash script is the most baroque. It needs:
- A
starship_preexeccallback that runs before every pipeline command, even ones inside pipes (the bashDEBUGtrap fires per command). ASTARSHIP_PREEXEC_READYflag is used to avoid restarting the timer for downstream pipe commands. - A
_starship_set_returnhelper because bash does not allow assigning to$?. - A workaround for a long-standing bash bug where
jobsreports completed background processes as still running insidePROMPT_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 viaset -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
promptfunction that callsstarship prompt. - A right-prompt rendering using
$PSStyleANSI 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
Shellenum insrc/context.rs, dispatch it inContext::get_shell, add a stub branch ininit_stuband a full-init branch ininit_main(both insrc/init/mod.rs), and createsrc/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--flagclap derive insrc/context.rs), then update eachsrc/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.