Starship 高级配置实战:Transient Prompt、右侧提示符、Shell 钩子与 Claude Code Statusline 完全指南
【免费下载链接】starship☄🌌️ The minimal, blazing-fast, and infinitely customizable prompt for any shell!项目地址: https://gitcode.com/GitHub_Trending/st/starship
Starship 的日常定制大多在starship.toml中完成,但很多进阶需求——把上一行提示符替换成极简符号、在提示符渲染前后注入自定义逻辑、让提示符内容出现在输入行右侧、甚至把 Starship 用作 Claude Code 的状态栏——都无法仅靠一个配置文件实现。本文基于 Starship 仓库的官方高级配置文档(docs/ar-SA/advanced-config/README.md)并结合 init 脚本 与 配置模块 源码,系统讲解这些高级配置技术的原理、完整操作与注意事项,帮助你把 Starship 从"好看"推进到"深度融入工作流"。
警告:本节涉及的高级配置方式属于"非核心 API",未来版本的 Starship 可能会对其做出变更,升级前建议核对最新文档。
一、Trans Prompt(瞬态提示符)
1. 什么是 Transient Prompt
瞬态提示符(Transient Prompt)指:命令执行后,把上一行完整打印的提示符替换为一行极简字符串(如仅保留一个❯)。这样长提示符(含 Git 状态、运行时版本等)只在渲染时出现一次,历史滚动区则保持干净,特别适合提示符信息冗余但并非每刻都需要的场景。
Starship 目前支持四个环境的瞬态提示符:PowerShell、Cmd(依赖 Clink)、Fish 和 Bash(依赖 Ble.sh 框架)。
2. PowerShell 中的 Transient Prompt
在 Shell 会话中执行Enable-TransientPrompt即可启用;写入$PROFILE可持久化;执行Disable-TransientPrompt可临时关闭。默认情况下,输入行左侧会被替换为>。若要自定义(例如显示 Starship 的character模块),需定义名为Invoke-Starship-TransientFunction的函数:
function Invoke-Starship-TransientFunction { &starship module character } Invoke-Expression (&starship init powershell) Enable-TransientPrompt从源码看,src/init/starship.ps1 中确实生成了Enable-TransientPrompt/Disable-TransientPrompt两个函数,并维护一个$script:TransientPrompt开关:当开关为真且下一轮渲染时,脚本检测function:Invoke-Starship-TransientFunction是否存在,存在则调用其返回值作为替换提示符,随后把开关复位——这解释了为什么自定义函数必须用这个精确的命名。
3. Cmd 中的 Transient Prompt(Clink)
Cmd 需要安装 Clink 生态下的 Clink 框架。启用方式是执行一次:
clink set prompt.transient <value><value>取值:
always:总是替换上一行提示符;same_dir:仅当工作目录与上一行相同时替换;off:不替换(即关闭瞬态行为)。
自定义左右两侧显示内容需修改starship.lua:
- 默认左侧被替换为
>。定义starship_transient_prompt_func函数可自定义,该函数接收当前提示符字符串作为参数。例如显示character模块:
function starship_transient_prompt_func(prompt) return io.popen("starship module character" .." --keymap="..rl.getvariable('keymap') ):read("*a") end load(io.popen('starship init cmd'):read("*a"))()- 默认右侧为空。定义
starship_transient_rprompt_func可自定义右侧,例如显示上一条命令的开始时间:
function starship_transient_rprompt_func(prompt) return io.popen("starship module time"):read("*a") end load(io.popen('starship init cmd'):read("*a"))()实现侧的证据在 src/init/starship.lua:脚本在检测到用户定义了starship_transient_prompt_func后,将其挂到 Clink 提示符对象的transientfilter方法上;starship_transient_rprompt_func则挂到transientrightfilter上。即这两个 Lua 全局函数是 Starship 与 Clink 瞬态机制之间的约定接口。
4. Fish 中的 Transient Prompt
在会话中执行enable_transience启用,写入~/.config/fish/config.fish持久化,执行disable_transience临时关闭。
注意:Fish 中瞬态提示符仅在命令行非空且语法正确时才会打印。
- 默认左侧被替换为加粗绿色的
❯。自定义方式为定义starship_transient_prompt_func函数,例如显示character模块:
function starship_transient_prompt_func starship module character end starship init fish | source enable_transience- 默认右侧为空。自定义方式为定义
starship_transient_rprompt_func函数,例如显示上一条命令的开始时间:
function starship_transient_rprompt_func starship module time end starship init fish | source enable_transience从 src/init/starship.fish 的实现可以看到:enable_transience函数会优先检测 Fish 4.1+ 内置的瞬态支持(设置fish_transient_prompt变量),否则回退为绑定回车键(bind --user \r __starship_transient_execute)的自实现方案;渲染时脚本通过type -q starship_transient_prompt_func检查用户函数是否存在,并把--terminal-width、--status、--pipestatus、--keymap、--cmd-duration、--jobs等上下文参数一并传入,因此该函数内调用starship module时能拿到完整的环境变量。
5. Bash 中的 Transient Prompt(Ble.sh)
Bash 依赖 Ble.sh 框架 v0.4+。在~/.bashrc中加入:
bleopt prompt_ps1_transient=<value><value>是冒号分隔的always、same-dir、trim列表,语义为:
- 当
prompt_ps1_final为空且prompt_ps1_transient非空时,离开当前命令行时PS1指定的提示符会被擦除; - 若包含
trim字段,多行PS1仅保留最后一行,其余行擦除;不包含trim时命令行会像PS1=(空)一样重绘; - 若包含
same-dir且当前工作目录与上一命令行最终目录不同,则忽略prompt_ps1_transient。
在~/.blerc(或~/.config/blesh/init.sh)中自定义左右两侧:
- 左侧由
prompt_ps1_final选项控制,例如显示character模块:
bleopt prompt_ps1_final='$(starship module character)'- 右侧由
prompt_rps1_final选项控制,例如显示上一条命令的开始时间:
bleopt prompt_rps1_final='$(starship module time)'二、自定义 pre-prompt 与 pre-execution 命令
这一类钩子让你在提示符绘制前(pre-prompt / precmd)或命令执行前(pre-execution / preexec)插入自己的逻辑,例如打印日志、改标题、调用通知脚本。
1. Cmd(Clink)
Clink 提供了非常灵活的 API。按需修改starship.lua:
- 提示符绘制前运行自定义函数:定义
starship_preprompt_user_func,参数为当前提示符字符串。例如在提示符前画一枚火箭:
function starship_preprompt_user_func(prompt) print("🚀") end load(io.popen('starship init cmd'):read("*a"))()- 命令执行前运行自定义函数:定义
starship_precmd_user_func,参数为当前命令行字符串。例如打印即将执行的命令:
function starship_precmd_user_func(line) print("Executing: "..line) end load(io.popen('starship init cmd'):read("*a"))()2. Bash
Bash 没有像其他 Shell 那样正式的 preexec/precmd 框架,因此 Starship 只能提供有限的钩子插入点:
- pre-prompt:定义任意函数后,把函数名赋值给
starship_precmd_user_func。例如在提示符前打印火箭:
function blastoff(){ echo "🚀" } starship_precmd_user_func="blastoff"- pre-execution:利用 Bash 的
DEBUGtrap 机制。必须在初始化 Starship之前设置 DEBUG trap!Starship 会保存启动时的 DEBUG trap 值,如果启动后再覆盖它,部分功能会失效。正确写法:
function blastoff(){ echo "🚀" } trap blastoff DEBUG # Trap DEBUG *before* running starship set -o functrace eval $(starship init bash) set +o functrace其中functrace(functopts/extdebug相关)用于保证 DEBUG trap 在函数调用上下文中也能触发。
3. PowerShell
PowerShell 同样缺乏正式的 preexec/precmd 框架,Starship 提供的有限插入点是:创建名为Invoke-Starship-PreCommand的函数,它在每次渲染提示符前被调用:
function Invoke-Starship-PreCommand { $host.ui.Write("🚀") }三、修改终端窗口标题
部分 Shell 会替你自动改窗口标题(例如反映当前工作目录),Fish 甚至默认如此。Starship 本身不做这件事,但可以非常方便地为bash、zsh、cmd、powershell补上。
先定义改标题函数(bash 与 zsh 相同):
function set_win_title(){ echo -ne "\033]0; YOUR_WINDOW_TITLE_HERE \007" }标题中可以使用变量($USER、$HOSTNAME、$PWD是常见选择)。
- bash:把函数设为 Starship 的 precmd 钩子:
starship_precmd_user_func="set_win_title"- zsh:加入
precmd_functions数组:
precmd_functions+=(set_win_title)效果满意后,把上述行写入~/.bashrc或~/.zshrc持久化。例如想在终端标签页标题中显示当前目录名:
function set_win_title(){ echo -ne "\033]0; $(basename "$PWD") \007" } starship_precmd_user_func="set_win_title"- Cmd:通过
starship_preprompt_user_func修改窗口标题:
function starship_preprompt_user_func(prompt) console.settitle(os.getenv('USERNAME').."@"..os.getenv('COMPUTERNAME')..": "..os.getcwd()) end load(io.popen('starship init cmd'):read("*a"))()- PowerShell:创建
Invoke-Starship-PreCommand函数实现类似效果(编辑$PROFILE):
function Invoke-Starship-PreCommand { $host.ui.RawUI.WindowTitle = "$env:USERNAME@$env:COMPUTERNAME`: $pwd `a" } Invoke-Expression (&starship init powershell)四、启用右侧提示符(Right Prompt)
部分 Shell 支持渲染在输入行同一行的右侧提示符。Starship 通过right_format选项设置其内容:凡是能用在format里的模块,都可以用在right_format里;$all变量将只包含未被format或right_format显式使用的模块。
注意:右侧提示符是跟随输入位置的一行。若要在多行提示符中让模块在输入行上方右对齐,请参考 fill 模块。
right_format当前支持的 Shell:elvish、fish、zsh、xonsh、cmd、nushell、bash。其中bash 需要安装 Ble.sh v0.4+才能使用右侧提示符。
示例
# ~/.config/starship.toml # A minimal left prompt format = """$character""" # move the rest of the prompt to the right right_format = """$all"""效果类似于:
▶ starship on rprompt [!] is 📦 v0.57.0 via 🦀 v1.54.0 took 17szsh 对齐修正:zsh(v5.0.5+)会给右侧提示符追加默认尾随空格,在配合$fill模块使用时会产生对齐问题。在.zshrc中加入以下设置即可消除该间隙:
ZLE_RPROMPT_INDENT=0五、继续行提示符(Continuation Prompt)
部分 Shell 支持继续行提示符:当用户输入了不完整语句(例如只有一个左括号或引号)时,换行显示的提示符会替代普通提示符。
Starship 使用continuation_prompt选项设置它,默认值为'∙ '(可在 src/configs/starship_root.rs 中确认该默认值)。
注意:
continuation_prompt应设置为不含任何变量的字面字符串;- 继续行提示符仅在以下 Shell 中可用:
bash、zsh、PowerShell。
示例
# ~/.config/starship.toml # A continuation prompt that displays two filled-in arrows continuation_prompt = '▶▶ '六、Claude Code Statusline
Starship 支持在 Claude Code(Anthropic 的交互式编码 CLI 工具)内显示自定义状态栏,实时展示当前会话使用的模型、上下文窗口占用与会话费用。
1. 配置步骤
- 在 Claude Code 中执行
/statusline并让它配置 Starship,或者手动在.claude/settings.json中加入:
{ "statusLine": { "type": "command", "command": "starship statusline claude-code" } }- 在
~/.config/starship.toml中自定义状态栏外观(见下文)。
2. 工作原理
当以starship statusline claude-code调用时,Claude Code 通过stdin传入会话 JSON 数据,Starship 读取它并使用名为claude-code的专用 profile 渲染状态栏。
从源码可以印证这条调用链:src/main.rs 中Commands::Statusline分支在 provider 为ClaudeCode且未显式指定 profile 时,默认取claude-code作为 profile 名,然后进入print::prompt_with_claude_code渲染。而 stdin 的 JSON 由 src/utils/statusline.rs 中的ClaudeCodeData结构反序列化——它包含model(id/display_name)、context_window(窗口尺寸、总输入/输出 token、已用百分比、当前调用 token 明细)、cost(总费用、总时长、API 时长、增删行数)等字段,并且对显式null字段做了与缺失字段相同的默认值处理(deserialize_null_default),文件内附带的单元测试覆盖了会话刚开始时字段全为null的 payload 场景。
该 profile 包含三个专用模块:
claude_model:显示当前使用的 Claude 模型;claude_context:以可视化仪表显示上下文窗口占用;claude_cost:显示会话费用与统计。
默认 profile 格式:
[profiles] claude-code = "$claude_model$git_branch$claude_context$claude_cost"3. 整体配置
在~/.config/starship.toml中修改claude-codeprofile 与各模块配置:
# ~/.config/starship.toml # Customize the claude-code profile [profiles] claude-code = "$claude_model$claude_context$claude_cost" # Configure individual modules [claude_model] format = "$symbol$model " symbol = "🤖 " style = "bold blue" [claude_context] format = "$gauge $percentage " gauge_width = 10 [claude_cost] format = "$symbol$cost " symbol = "💰 "4. claude_model 模块
显示当前会话使用的 Claude 模型。
选项(默认值与 src/configs/claude_model.rs 中的Default实现一致):
| 选项 | 默认值 | 说明 |
|---|---|---|
format | '$symbol$model ' | 模块的格式字符串 |
symbol | '🤖 ' | 模型名前显示的符号 |
style | 'bold blue' | 模块的样式 |
model_aliases | {} | 模型 ID 或显示名到短别名的映射;先按 ID 查找,再按显示名查找 |
disabled | false | 禁用claude_model模块 |
变量:
| 变量 | 示例 | 说明 |
|---|---|---|
model | Claude 3.5 Sonnet | 当前模型的显示名 |
model_id | claude-3-5-sonnet | 模型 ID |
symbol | 镜像选项symbol的值 | |
style* | 镜像选项style的值 |
*:该变量只能作为样式字符串的一部分使用。
示例:
# ~/.config/starship.toml # Basic customization [claude_model] format = "on $symbol$model " symbol = "🧠 " style = "bold cyan" # Using model aliases for vendor-specific model names # You can alias by model ID or display name [claude_model.model_aliases] # Alias by vendor model ID (e.g. AWS Bedrock) "global.anthropic.claude-sonnet-4-5-20250929-v1:0" = "Sonnet 4.5" # Alias by display name "Claude Sonnet 4.5 (Vendor Proxy)" = "Sonnet"5. claude_context 模块
以百分比和可视化仪表显示上下文窗口占用,样式根据可配置的阈值自动变化。
选项(默认值与 src/configs/claude_context.rs 一致):
| 选项 | 默认值 | 说明 |
|---|---|---|
format | '$gauge $percentage ' | 模块的格式字符串 |
symbol | '' | 仪表前显示的符号 |
gauge_width | 5 | 仪表的字符宽度 |
gauge_full_symbol | '█' | 仪表满格段使用的符号 |
gauge_partial_symbol | '▒' | 仪表半格段使用的符号 |
gauge_empty_symbol | '░' | 仪表空段使用的符号 |
display | 见下文 Display | 阈值与样式配置数组 |
disabled | false | 禁用claude_context模块 |
Display 子项:display是对象数组,为不同占用水平定义阈值与样式。模块使用最高匹配阈值的样式;若匹配项的hidden为true则隐藏模块。
| 选项 | 默认值 | 说明 |
|---|---|---|
threshold | 0.0 | 匹配该配置所需的最低上下文占用百分比 |
style | bold green | 匹配该显示配置时的style值 |
hidden | false | 匹配该配置时隐藏模块 |
[[claude_context.display]] threshold = 0 hidden = true [[claude_context.display]] threshold = 30 style = "bold green" [[claude_context.display]] threshold = 60 style = "bold yellow" [[claude_context.display]] threshold = 80 style = "bold red"变量:
| 变量 | 示例 | 说明 |
|---|---|---|
gauge | ██▒░░ | 上下文占用的可视化表示 |
percentage | 65% | 上下文占用百分比 |
input_tokens | 45.2k | 会话累计输入 token |
output_tokens | 12.3k | 会话累计输出 token |
curr_input_tokens | 5.1k | 最近一次 API 调用的输入 token |
curr_output_tokens | 1.2k | 最近一次 API 调用的输出 token |
curr_cache_creation_tokens | 1.5k | 最近一次 API 调用的缓存创建 token |
curr_cache_read_tokens | 23.4k | 最近一次 API 调用的缓存读取 token |
total_tokens | 200k | 上下文窗口总大小 |
symbol | 镜像选项symbol的值 | |
style* | 镜像匹配阈值对应的样式 |
*:该变量只能作为样式字符串的一部分使用。
示例:
仅显示仪表(最小化):
[claude_context] format = "$gauge " gauge_width = 10详细 token 信息:
[claude_context] format = "$percentage ($input_tokens in / $output_tokens out) "自定义仪表符号:
[claude_context] gauge_full_symbol = "▰" gauge_partial_symbol = "" gauge_empty_symbol = "▱" gauge_width = 10 format = "$gauge "自定义阈值:
[[claude_context.display]] threshold = 0 style = "bold green" [[claude_context.display]] threshold = 50 style = "bold yellow" [[claude_context.display]] threshold = 75 style = "bold orange" [[claude_context.display]] threshold = 90 style = "bold red"6. claude_cost 模块
以美元显示当前 Claude Code 会话的总费用,与claude_context一样支持基于阈值的样式。
选项(默认值与 src/configs/claude_cost.rs 一致):
| 选项 | 默认值 | 说明 |
|---|---|---|
format | '$symbol(\\$$cost) ' | 模块的格式字符串 |
symbol | '💰 ' | 费用前显示的符号 |
display | 见下文 Display | 阈值与样式配置数组 |
disabled | false | 禁用claude_cost模块 |
Display 子项:display数组定义费用阈值与样式,模块采用最高匹配阈值的样式,匹配项hidden = true时隐藏模块。
| 选项 | 默认值 | 说明 |
|---|---|---|
threshold | 0.0 | 匹配该配置所需的最低费用(USD) |
style | bold green | 匹配该显示配置时的style值 |
hidden | false | 匹配该配置时隐藏模块 |
默认配置:
[[claude_cost.display]] threshold = 0.0 hidden = true [[claude_cost.display]] threshold = 1.0 style = "bold yellow" [[claude_cost.display]] threshold = 5.0 style = "bold red"变量:
| 变量 | 示例 | 说明 |
|---|---|---|
cost | 1.23 | 会话总费用(USD,保留两位小数) |
duration | 1m 30s | 会话总时长 |
api_duration | 45s | API 调用总时长 |
lines_added | 1.2k | 累计新增代码行数 |
lines_removed | 500 | 累计删除代码行数 |
symbol | 镜像选项symbol的值 | |
style* | 镜像匹配阈值对应的样式 |
*:该变量只能作为样式字符串的一部分使用。
示例:
# ~/.config/starship.toml # Cost with code change statistics [claude_cost] format = "$symbol$cost (+$lines_added -$lines_removed) " # Hide module until cost exceeds $0.10 [[claude_cost.display]] threshold = 0.0 hidden = true [[claude_cost.display]] threshold = 0.10 style = "bold yellow" [[claude_cost.display]] threshold = 2.0 style = "bold red" # Show duration information [claude_cost] format = "$symbol$cost ($duration) "七、样式字符串(Style Strings)
Starship 中所有模块的style选项以及格式串里的样式片段都使用统一的"样式字符串"语法:
样式字符串是由空白分隔的词列表,不区分大小写(bold与BoLd等价)。每个词可以是以下之一:
bolditalicunderlinedimmedinvertedblinkhiddenstrikethroughbg:<color>fg:<color><color>none
其中<color>是颜色指示符(见下)。当前fg:<color>与<color>作用相同(未来可能变更)。<color>还可取prev_fg或prev_bg,分别解析为前一个项的前景色/背景色(若可获得,否则为none)。inverted交换前景与背景色。词在字符串中的顺序无关紧要。
none的覆盖语义:只要none不是bg:指示符的一部分,它就会覆盖字符串中所有其他 token——例如fg:red none fg:blue最终产生无样式的字符串。bg:none把背景设为默认色,因此fg:red bg:none等价于red或fg:red;bg:green fg:red bg:none也等价于fg:red。未来none与其他 token 连用可能会直接报错。
颜色指示符可以是:
- 标准终端色之一:
black、red、green、blue、yellow、purple、cyan、white。可加bright-前缀取亮色版本(例如bright-white); #后跟六位十六进制数,即 RGB 十六进制颜色码;- 0–255 之间的数字,即 8-bit ANSI 颜色码。
若对前景/背景指定了多个颜色,字符串中最后一个生效。
终端兼容性怪癖:并非每种终端都能正确显示所有样式,已知问题包括:
- 许多终端默认禁用
blink; - iTerm 不支持
hidden; - macOS 默认 Terminal.app 不支持
strikethrough。
小结
Starship 的高级配置能力可以归纳为四条主线:瞬态提示符(PowerShell / Clink / Fish / Ble.sh 四种机制,均以约定命名的用户函数为扩展点)、pre-prompt 与 pre-execution 钩子(starship_preprompt_user_func、starship_precmd_user_func、starship_precmd_user_func变量、Invoke-Starship-PreCommand、Bash DEBUG trap)、布局增强(right_format右提示符与continuation_prompt继续行提示符)以及Claude Code statusline(starship statusline claude-code+claude-codeprofile + 三个 claude_* 模块)。这些扩展点与 src/init/ 目录下各 Shell 的 init 脚本及 src/configs/ 下的配置默认值一一对应,当你需要超越starship.toml本身时,可以对照本文与对应源码逐层深入。
【免费下载链接】starship☄🌌️ The minimal, blazing-fast, and infinitely customizable prompt for any shell!项目地址: https://gitcode.com/GitHub_Trending/st/starship
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考