mcpField
S
shell-prompt

shell-prompt

github.com/julianobarbosa开发14118 次安装2 天前更新
代码仓库

关于 shell-prompt

shell-prompt 是一份面向 Zsh 用户的 Shell 提示符与 Vi 模式配置指南,涵盖 Powerlevel10k 设置及性能调优。它还整理了插件选择、按模式变化的光标反馈和常见问题排查。

主要功能

  1. 01配置 Powerlevel10k 提示符
  2. 02显示 Git 状态与环境信息
  3. 03设置 Zsh Vi 模式及光标
  4. 04调整按键超时与快捷键
  5. 05排查性能和插件加载问题

适用场景

  1. 01在 Zsh 提示符中查看分支和环境状态
  2. 02为 Vi 编辑模式配置光标反馈
  3. 03缩短提示符启动和更新耗时

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/julianobarbosa/claude-code-skills --skill shell-prompt

安装后在 Claude Code 中输入/shell-prompt确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
performance-tuning.md
powerlevel10k-config.md
starship-config.md
troubleshooting.md
zsh-vim-mode.md
scripts/
benchmark-prompt.zsh

详细介绍

Shell 提示符技能

使用 Powerlevel10k 和 Zsh Vi Mode 配置高性能 Shell 提示符。

概述

现代 Shell 提示符可提供:

  • Git 状态,包括分支、工作区是否有未提交更改以及远程跟踪信息
  • 环境指示器(Python 虚拟环境、Node 版本、K8s 上下文)
  • 长时间运行命令的执行时间
  • 退出代码可视化
  • 异步更新,带来流畅响应的体验
  • Vi 模式指示器和光标变化

Zsh Vi Mode

Zsh 支持 Vi 风格的行编辑,并通过光标变化和模式指示器提供视觉反馈。

快速设置(内置)
# ~/.zshrc
bindkey -v  # Enable vi mode

# Reduce key timeout for faster mode switching (default 400ms)
export KEYTIMEOUT=10  # 100ms - don't go below 10
按模式设置光标样式

根据当前模式更改光标形状:

# Add to ~/.zshrc
cursor_mode() {
    # Beam cursor for insert mode
    cursor_beam='\e[6 q'
    # Block cursor for normal mode
    cursor_block='\e[2 q'

    function zle-keymap-select {
        if [[ ${KEYMAP} == vicmd ]] ||
           [[ $1 = 'block' ]]; then
            echo -ne $cursor_block
        elif [[ ${KEYMAP} == main ]] ||
             [[ ${KEYMAP} == viins ]] ||
             [[ ${KEYMAP} = '' ]] ||
             [[ $1 = 'beam' ]]; then
            echo -ne $cursor_beam
        fi
    }

    zle-line-init() {
        echo -ne $cursor_beam
    }

    zle -N zle-keymap-select
    zle -N zle-line-init
}
cursor_mode
光标转义码
代码样式
\e[1 q闪烁块状光标
\e[2 q稳定块状光标
\e[3 q闪烁下划线
\e[4 q稳定下划线
\e[5 q闪烁竖线/光束
\e[6 q稳定竖线/光束

Vi 模式插件

Oh My Zsh vi-mode 插件
# ~/.zshrc
plugins=(... vi-mode)

# Configuration (before sourcing oh-my-zsh.sh)
VI_MODE_SET_CURSOR=true
VI_MODE_RESET_PROMPT_ON_MODE_CHANGE=true

# Cursor styles (0-6)
VI_MODE_CURSOR_NORMAL=2   # Solid block
VI_MODE_CURSOR_INSERT=6   # Solid beam
VI_MODE_CURSOR_VISUAL=6   # Solid beam
VI_MODE_CURSOR_OPPEND=0   # Blinking block

# Mode indicators
MODE_INDICATOR="%F{red}<<<NORMAL%f"
INSERT_MODE_INDICATOR="%F{green}<<<INSERT%f"
softmoth/zsh-vim-mode

功能全面的 Vi 模式,支持文本对象和环绕绑定。

安装:

# Clone
git clone https://github.com/softmoth/zsh-vim-mode.git ~/.zsh/zsh-vim-mode

# Source in .zshrc (after other plugins)
source ~/.zsh/zsh-vim-mode/zsh-vim-mode.plugin.zsh

加载顺序很重要: zsh-autosuggestions -> zsh-syntax-highlighting -> zsh-vim-mode

配置:

# Cursor styles (supports colors!)
MODE_CURSOR_VIINS="#00ff00 blinking bar"
MODE_CURSOR_VICMD="green block"
MODE_CURSOR_REPLACE="red block"
MODE_CURSOR_SEARCH="#ff00ff steady underline"
MODE_CURSOR_VISUAL="$MODE_CURSOR_VICMD steady bar"
MODE_CURSOR_VLINE="$MODE_CURSOR_VISUAL #00ffff"

# Mode indicators (auto-added to RPS1 if unset)
MODE_INDICATOR_VIINS='%F{15}<%F{8}INSERT>%f'
MODE_INDICATOR_VICMD='%F{10}<%F{2}NORMAL>%f'
MODE_INDICATOR_REPLACE='%F{9}<%F{1}REPLACE>%f'
MODE_INDICATOR_SEARCH='%F{13}<%F{5}SEARCH>%f'
MODE_INDICATOR_VISUAL='%F{12}<%F{4}VISUAL>%f'
MODE_INDICATOR_VLINE='%F{12}<%F{4}V-LINE>%f'

# Other options
VIM_MODE_VICMD_KEY='^['          # Default escape key
VIM_MODE_TRACK_KEYMAP=true       # Enable mode tracking
VIM_MODE_INITIAL_KEYMAP=viins    # Start in insert mode

功能:

  • 文本对象:ci"、da(、vi[
  • 环绕:cs"'(将外围的 " 改为 ')
  • 可视模式选择
  • 插入模式下的 Emacs 绑定(Ctrl-A、Ctrl-E)
jeffreytse/zsh-vi-mode

支持运算符待定模式的现代 Vi 模式。

安装:

# With zinit
zinit ice depth=1
zinit light jeffreytse/zsh-vi-mode

# Manual
git clone https://github.com/jeffreytse/zsh-vi-mode.git ~/.zsh/zsh-vi-mode
source ~/.zsh/zsh-vi-mode/zsh-vi-mode.plugin.zsh

配置:

# Cursor styles
ZVM_NORMAL_MODE_CURSOR=$ZVM_CURSOR_BLOCK
ZVM_INSERT_MODE_CURSOR=$ZVM_CURSOR_BEAM
ZVM_VISUAL_MODE_CURSOR=$ZVM_CURSOR_BLOCK
ZVM_VISUAL_LINE_MODE_CURSOR=$ZVM_CURSOR_BLOCK
ZVM_OPPEND_MODE_CURSOR=$ZVM_CURSOR_UNDERLINE

# Mode indicator in prompt
function zvm_after_select_vi_mode() {
  case $ZVM_MODE in
    $ZVM_MODE_NORMAL)
      # Update prompt for normal mode
      ;;
    $ZVM_MODE_INSERT)
      # Update prompt for insert mode
      ;;
    $ZVM_MODE_VISUAL)
      # Update prompt for visual mode
      ;;
  esac
}

# Disable cursor style changes (if using another method)
ZVM_CURSOR_STYLE_ENABLED=false

按键绑定参考

模式切换
按键操作
ESC 或 Ctrl-[进入普通模式
i在光标前插入
a在光标后追加
I在行首插入
A在行尾追加
v进入可视模式
V进入可视行模式
导航(普通模式)
按键操作
h/l左/右
j/k在历史记录中向下/向上
w/W向前移动一个单词
b/B向后移动一个单词
e/E移至单词末尾
0移至行首
^移至首个非空白字符
$移至行尾
f{char}向前查找字符
F{char}向后查找字符
t{char}向前移至字符前
T{char}向后移至字符前
编辑(普通模式)
按键操作
x删除字符
dd删除整行
D删除至行尾
cc修改整行
C修改至行尾
yy复制整行
p/P在后方/前方粘贴
u撤销
Ctrl-r重做
文本对象
按键操作
ciw修改单词内部
daw删除一个单词(包括空格)
ci"修改引号内的内容
da(删除括号及其内容
vi[选择方括号内的内容

KEYTIMEOUT 注意事项

KEYTIMEOUT 变量会影响多键序列:

# Default is 40 (400ms)
export KEYTIMEOUT=10  # 100ms - good balance

# Too low (<10) breaks multi-key bindings
# Too high (>40) feels sluggish on ESC

消除转义延迟的方法:

# Option 1: Use Ctrl-[ instead of Escape
# (Ctrl-[ sends ESC immediately)

# Option 2: Bind jk or jj to escape
bindkey -M viins 'jk' vi-cmd-mode
bindkey -M viins 'jj' vi-cmd-mode

Powerlevel10k

安装
# With Oh My Zsh
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
  ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k

# Set in .zshrc
ZSH_THEME="powerlevel10k/powerlevel10k"

# Run configuration wizard
p10k configure
即时提示设置

在 ~/.zshrc 的最顶部(其他任何内容之前)添加:

# Enable Powerlevel10k instant prompt
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi

在 ~/.zshrc 的末尾添加:

# Source Powerlevel10k config
[[ -f ~/.p10k.zsh ]] && source ~/.p10k.zsh
配置选项

~/.p10k.zsh 中的关键设置:

# Left prompt segments
typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
  os_icon
  dir
  vcs
  newline
  prompt_char
)

# Right prompt segments
typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(
  status
  command_execution_time
  background_jobs
  virtualenv
  kubecontext
  azure
  aws
  vi_mode      # Show vi mode indicator!
  context
  time
)

# Transient prompt (clean up previous prompts)
typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=always

# Directory truncation
typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique
typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=3

# Vi mode indicator styling
typeset -g POWERLEVEL9K_VI_INSERT_MODE_STRING=''
typeset -g POWERLEVEL9K_VI_COMMAND_MODE_STRING='NORMAL'
typeset -g POWERLEVEL9K_VI_MODE_NORMAL_FOREGROUND=0
typeset -g POWERLEVEL9K_VI_MODE_NORMAL_BACKGROUND=2
性能调优
# Disable slow segments
typeset -g POWERLEVEL9K_DISABLE_GITSTATUS=false  # Keep enabled!

# Large repo optimization
typeset -g POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=1000

# Async git status (default, don't change)
typeset -g POWERLEVEL9K_VCS_BACKENDS=(git)

# Reduce segment count for speed
typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(status command_execution_time vi_mode)

性能总结

基准测试结果(zsh-bench)
指标目标Powerlevel10k
首次提示延迟<50ms24ms
命令延迟<10ms15ms
Git 状态(小型)<30ms<10ms
Git 状态(大型)<100ms异步/即时
架构

Powerlevel10k(gitstatus 守护进程):

┌─────────────┐     pipes      ┌─────────────┐
│    Zsh      │ <============> │  gitstatusd │
│  (prompt)   │                │   (C++ daemon)
└─────────────┘                └─────────────┘
       │                              │
       │ async                        │ keeps state
       │ never blocks                 │ in memory
       ▼                              ▼
   Instant prompt              Fast git queries

对设置进行基准测试

使用 zsh-bench
# Install
git clone https://github.com/romkatv/zsh-bench ~/zsh-bench

# Run benchmark
~/zsh-bench/zsh-bench

# Key metrics to watch:
# - first_prompt_lag_ms: <50ms ideal
# - command_lag_ms: <10ms ideal
手动计时
# Zsh startup time
time zsh -i -c exit

# Per-command timing
TIMEFMT='%*E seconds'
time (for i in {1..10}; do zsh -i -c 'print -P "$PROMPT"' >/dev/null; done)

故障排除

提示符缓慢
# Check segment timing
zsh -xv  # Verbose trace

# Common culprits:
# - git_status in large repos
# - python/node version detection
# - cloud context (aws/azure/gcloud)
P10k:gitstatus 失败
# Reinstall gitstatusd
rm -rf ~/.cache/gitstatus

# Restart zsh
exec zsh
Vi 模式无法使用
# Verify vi mode is enabled
bindkey -l | grep vi

# Check current keymap
echo $KEYMAP

# Reset bindings
bindkey -v
光标未变化
  1. 确认终端支持光标转义码
  2. 检查是否定义了 zle-keymap-select:whence -f zle-keymap-select
  3. 某些终端(如 Apple Terminal)对光标的支持有限
  4. 尝试使用 iTerm2 或 Alacritty,以获得完整支持

参考资料

外部链接


注意事项

  • P10k 即时提示必须放在 .zshrc 的最顶部,且前面不能有任何输出: 即使是 echo 或未加保护的 command -v 也会产生警告并禁用即时提示。将所有会输出到 stdout 的代码移到即时提示代码块之后,或用 &>/dev/null 包裹。
  • KEYTIMEOUT=1 会导致 jk 这类多键绑定无法触发退出模式: 小于 10(100ms)时,zsh 无法区分先后输入的 j、k 和多字节 ESC 序列。表现为:在普通模式下,提示符会将 j 和 k 作为普通字符输入。
  • bindkey -v 会重置所有之前的绑定: 在 bindkey -v 之前创建的自定义绑定会被静默清除。应先设置 vi 模式,再调用所有自定义 bindkey。
  • 在 tmux 中,光标转义码(\e[6 q)必须启用透传才能生效: tmux 默认会剥除 DECSCUSR——在 .tmux.conf 中添加 set -ga terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[ q',否则光标会一直显示为块状。
  • gitstatusd 会按仓库缓存:在 zsh 外运行 git reset --hard 会导致提示符显示过期信息: P10k 的守护进程尚未检测到变更。等待约 2 秒、手动运行 git status,或运行 p10k reload 强制刷新。
  • 插件加载顺序:zsh-vim-mode 应在 autosuggestions 和 syntax-highlighting 之后加载: 顺序颠倒会导致 vim-mode 覆盖 zle 小部件——表现可能包括光标变更失效或 ESC 无法使用。使用 zle -lL | grep widget-name 检查。

评论

支持 Markdown