shell-prompt

安装量: 39
排名: #18285

安装

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

Configure high-performance shell prompts with Powerlevel10k and Zsh Vi Mode.

Overview

Modern shell prompts provide:

  • Git status with branch, dirty state, and remote tracking

  • Environment indicators (Python venv, Node version, K8s context)

  • Execution time for long-running commands

  • Exit code visualization

  • Async updates for responsive experience

  • Vi mode indicators and cursor changes

Zsh Vi Mode

Zsh supports vi-style line editing with visual feedback through cursor changes and mode indicators.

Quick Setup (Built-in)

# ~/.zshrc
bindkey -v  # Enable vi mode

# Reduce key timeout for faster mode switching (default 400ms)
export KEYTIMEOUT=10  # 100ms - don't go below 10

Cursor Style by Mode

Change cursor shape based on current mode:

# 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

Cursor Escape Codes

| \e[1 q | Blinking block

| \e[2 q | Steady block

| \e[3 q | Blinking underline

| \e[4 q | Steady underline

| \e[5 q | Blinking bar/beam

| \e[6 q | Steady bar/beam

Vi Mode Plugins

Oh My Zsh vi-mode Plugin

# ~/.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

Full-featured vi mode with text objects and surround bindings.

Installation:

# 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

Load order matters: zsh-autosuggestions -> zsh-syntax-highlighting -> zsh-vim-mode

Configuration:

# 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

Features:

  • Text objects: ci", da(, vi[

  • Surround: cs"' (change surrounding " to ')

  • Visual mode selection

  • Emacs bindings in insert mode (Ctrl-A, Ctrl-E)

jeffreytse/zsh-vi-mode

Modern vi mode with operator-pending mode support.

Installation:

# 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

Configuration:

# 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

Key Bindings Reference

Mode Switching

| ESC or Ctrl-[ | Enter Normal mode

| i | Insert before cursor

| a | Append after cursor

| I | Insert at line start

| A | Append at line end

| v | Enter Visual mode

| V | Enter Visual Line mode

| h/l | Left/right

| j/k | Down/up in history

| w/W | Forward word

| b/B | Backward word

| e/E | End of word

| 0 | Start of line

| ^ | First non-blank

| $ | End of line

| f{char} | Find char forward

| F{char} | Find char backward

| t{char} | Till char forward

| T{char} | Till char backward

Editing (Normal Mode)

| x | Delete char

| dd | Delete line

| D | Delete to end

| cc | Change line

| C | Change to end

| yy | Yank line

| p/P | Paste after/before

| u | Undo

| Ctrl-r | Redo

Text Objects

| ciw | Change inner word

| daw | Delete a word (with space)

| ci" | Change inside quotes

| da( | Delete around parens

| vi[ | Select inside brackets

KEYTIMEOUT Considerations

The KEYTIMEOUT variable affects multi-key sequences:

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

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

Workarounds for escape delay:

# 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

Installation

# 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

Instant Prompt Setup

Add at the very top of ~/.zshrc (before anything else):

# 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

Add at the end of ~/.zshrc:

# Source Powerlevel10k config
[[ -f ~/.p10k.zsh ]] && source ~/.p10k.zsh

Configuration Options

Key settings in ~/.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

Performance Tuning

# 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)

Performance Summary

Benchmark Results (zsh-bench)

| First prompt lag | <50ms | 24ms

| Command lag | <10ms | 15ms

| Git status (small) | <30ms | <10ms

| Git status (large) | <100ms | Async/instant

Architecture

Powerlevel10k (gitstatus daemon):

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

Benchmarking Your Setup

Using 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

Manual Timing

# 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)

Troubleshooting

Slow Prompt

# 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 Failed

# Reinstall gitstatusd
rm -rf ~/.cache/gitstatus

# Restart zsh
exec zsh

Vi Mode Not Working

# Verify vi mode is enabled
bindkey -l | grep vi

# Check current keymap
echo $KEYMAP

# Reset bindings
bindkey -v

Cursor Not Changing

  • Verify terminal supports cursor escape codes

  • Check zle-keymap-select is defined: whence -f zle-keymap-select

  • Some terminals (like Apple Terminal) have limited cursor support

  • Try iTerm2 or Alacritty for full support

References

返回排行榜