在 vi 模式下使我的 zsh 提示显示模式

xen*_*ide 55 shell prompt zsh

我使用bindkey -v(对于 bash-ersset -o vi我认为它也适用于 zsh)或 vi(m) 模式。但是我没有任何视觉提示来告诉我是处于插入模式还是命令模式,这让我很烦恼。有谁知道如何让我的提示显示模式?

xen*_*ide 32

我通过SU找到了这个。这是基本示例,尽管我仍在为自己定制:

function zle-line-init zle-keymap-select {
    RPS1="${${KEYMAP/vicmd/-- NORMAL --}/(main|viins)/-- INSERT --}"
    RPS2=$RPS1
    zle reset-prompt
}

zle -N zle-line-init
zle -N zle-keymap-select
Run Code Online (Sandbox Code Playgroud)

我会解释它,除非我还没有真正理解它

  • `zle reset-prompt` 将在重绘时删除提示上方的 1(或更多)行(如果您的提示是多行):( 这对我来说是一个showstopper。 (2认同)

Gil*_*il' 20

您已经发现zle-keymap-select每当模式改变时都会执行哪个。您可以使用它来设置除提示之外的其他一些视觉指示器,具体取决于您的终端支持它的内容(当然还有您对模式指示器显示的喜好)。

有一个标准的terminfo 能力来改变光标的形状。然而,有些终端在两种模式下都显示相同的光标。Xterm 的不可见光标的概念是使其闪烁(这必须使用-bc命令行参数或cursorBlink资源启用)。

zle-keymap-select () {
  case $KEYMAP in
    vicmd) print -rn -- $terminfo[cvvis];; # block cursor
    viins|main) print -rn -- $terminfo[cnorm];; # less visible cursor
  esac
}
Run Code Online (Sandbox Code Playgroud)

对于某些终端,您还可以使用print -n '\e]12;pink\a'(按颜色名称)或print -n '\e]12;#abcdef\a'(按 RGB 规范)更改光标颜色。这些序列在 xterm 文档的ctlseqs文件中进行了描述;现代终端模拟器通常模拟 xterm,尽管它们可能不支持其所有功能。


Seb*_*ask 10

对于使用带有多行提示的 reset-prompt 有问题的人,这对我有用:http: //zeitlens.com/posts/2014-06-29-howto-zsh-vi-style.html结合https:// stackoverflow.com/questions/3622943/zsh-vi-mode-status-line我最终做了:

terminfo_down_sc=$terminfo[cud1]$terminfo[cuu1]$terminfo[sc]$terminfo[cud1]

function insert-mode () { echo "-- INSERT --" }
function normal-mode () { echo "-- NORMAL --" }

precmd () {
    # yes, I actually like to have a new line, then some stuff and then 
    # the input line
    print -rP "
[%D{%a, %d %b %Y, %H:%M:%S}] %n %{$fg[blue]%}%m%{$reset_color%}"

    # this is required for initial prompt and a problem I had with Ctrl+C or
    # Enter when in normal mode (a new line would come up in insert mode,
    # but normal mode would be indicated)
    PS1="%{$terminfo_down_sc$(insert-mode)$terminfo[rc]%}%~ $ "
}
function set-prompt () {
    case ${KEYMAP} in
      (vicmd)      VI_MODE="$(normal-mode)" ;;
      (main|viins) VI_MODE="$(insert-mode)" ;;
      (*)          VI_MODE="$(insert-mode)" ;;
    esac
    PS1="%{$terminfo_down_sc$VI_MODE$terminfo[rc]%}%~ $ "
}

function zle-line-init zle-keymap-select {
    set-prompt
    zle reset-prompt
}
preexec () { print -rn -- $terminfo[el]; }

zle -N zle-line-init
zle -N zle-keymap-select
Run Code Online (Sandbox Code Playgroud)


Rot*_*eti 8

这是我用来在 zsh 中更改“块”和“梁”形状之间的光标的方法:

(用Termitegnome-terminalmate-terminal 测试

# vim mode config
# ---------------

# Activate vim mode.
bindkey -v

# Remove mode switching delay.
KEYTIMEOUT=5

# Change cursor shape for different vi modes.
function zle-keymap-select {
  if [[ ${KEYMAP} == vicmd ]] ||
     [[ $1 = 'block' ]]; then
    echo -ne '\e[1 q'

  elif [[ ${KEYMAP} == main ]] ||
       [[ ${KEYMAP} == viins ]] ||
       [[ ${KEYMAP} = '' ]] ||
       [[ $1 = 'beam' ]]; then
    echo -ne '\e[5 q'
  fi
}
zle -N zle-keymap-select

# Use beam shape cursor on startup.
echo -ne '\e[5 q'

# Use beam shape cursor for each new prompt.
preexec() {
   echo -ne '\e[5 q'
}
Run Code Online (Sandbox Code Playgroud)


joe*_*lom 7

另一种在 I 型梁和块之间更改光标形状的解决方案(对于下划线,请使用\033[4 q)。将此添加到您的~/.zshrc.

zle-keymap-select () {
if [ $KEYMAP = vicmd ]; then
    printf "\033[2 q"
else
    printf "\033[6 q"
fi
}
zle -N zle-keymap-select
zle-line-init () {
zle -K viins
printf "\033[6 q"
}
zle -N zle-line-init
bindkey -v
Run Code Online (Sandbox Code Playgroud)

修改自https://bbs.archlinux.org/viewtopic.php?id=95078。在 gnome-terminal 3.22 中测试。


更新

可以在此处找到更改光标形状的另一种解决方案。这个显然适用于 iTerm2,我没有办法测试它,但在这里添加它以防它对其他人有用。最后添加到您的~/.zshrc将是

function zle-keymap-select zle-line-init
{
    # change cursor shape in iTerm2
    case $KEYMAP in
        vicmd)      print -n -- "\E]50;CursorShape=0\C-G";;  # block cursor
        viins|main) print -n -- "\E]50;CursorShape=1\C-G";;  # line cursor
    esac

    zle reset-prompt
    zle -R
}

function zle-line-finish
{
    print -n -- "\E]50;CursorShape=0\C-G"  # block cursor
}

zle -N zle-line-init
zle -N zle-line-finish
zle -N zle-keymap-select
Run Code Online (Sandbox Code Playgroud)


Hem*_*ant 6

你可以试试VimMode

  • 我希望有一些不那么链接和更具解释性的东西。我想知道事情是如何运作的。 (4认同)