如何自定义 zsh 的 vim 模式?

如何自定义 zsh 的 vim 模式?

好的,我终于做出了重大改变。在我的 .zshenv 中,我更改了我的编辑器:

export EDITOR=vim

我有几个问题太小了,我不想为它们单独提出问题。它们如下:

  1. 如何让 zsh 像在 vim 中一样区分插入模式和命令模式?最好将光标从下划线更改为块,就像在 vim 中一样,但在底部显示文本也可以。

  2. 我如何让它更像 vim?例如,我宁愿它默认处于命令模式,而不是在执行一个命令后退出。

答案1

1.) (看http://zshwiki.org/home/examples/zlewidgetshttp://pthree.org/2009/03/28/add-vim-editing-mode-to-your-zsh-prompt/):

函数 zle-line-init zle-keymap-select {
    RPS1="${${KEYMAP/vicmd/-- 正常 --}/(main|viins)/-- 插入 --}"
    RPS2=$RPS1
    zle 重置提示
}
zle -N zle-line-init
zle -N zle-键映射-选择

在哪里:

2.) 我怀疑您必须编写另一个 zsh-widget 来执行此操作,请从第一个问题的两个链接中的第一个链接中获得启发。

答案2

akira 的解决方案在使用多行提示符时存在以下问题:从 ins 模式切换到 cmd 模式时,提示符重绘会导致从先前的输出中删除几行(并且新提示符显示在几行上方)。有多少行取决于您的提示符中有多少行。

处理该问题的方法是使用zle-line-finish,而不使用zle reset-promptthere 。例如:

# perform parameter expansion/command substitution in prompt
setopt PROMPT_SUBST

vim_ins_mode="[INS]"
vim_cmd_mode="[CMD]"
vim_mode=$vim_ins_mode

function zle-keymap-select {
  vim_mode="${${KEYMAP/vicmd/${vim_cmd_mode}}/(main|viins)/${vim_ins_mode}}"
  zle reset-prompt
}
zle -N zle-keymap-select

function zle-line-finish {
  vim_mode=$vim_ins_mode
}
zle -N zle-line-finish

然后您可以将其添加到您的右提示符中,例如:

RPROMPT='${vim_mode}'

这直接摘自我的博客文章:

答案3

zle-line-init() { zle -K vicmd; }
zle -N zle-line-init

这两行确保它以命令模式启动

答案4

下面将为你设置一个修改后的光标和一个显示你处于哪种模式的提示。你可以更改DEFAULT_VI_MODEviinsvicmd。只需将以下内容粘贴到新窗口中.zshrc即可开始:

# Prefer vi shortcuts
bindkey -v
DEFAULT_VI_MODE=viins
KEYTIMEOUT=1

__set_cursor() {
    local style
    case $1 in
        reset) style=0;; # The terminal emulator's default
        blink-block) style=1;;
        block) style=2;;
        blink-underline) style=3;;
        underline) style=4;;
        blink-vertical-line) style=5;;
        vertical-line) style=6;;
    esac

    [ $style -ge 0 ] && print -n -- "\e[${style} q"
}

# Set your desired cursors here...
__set_vi_mode_cursor() {
    case $KEYMAP in
        vicmd)
          __set_cursor block
          ;;
        main|viins)
          __set_cursor vertical-line
          ;;
    esac
}

__get_vi_mode() {
    local mode
    case $KEYMAP in
        vicmd)
          mode=NORMAL
          ;;
        main|viins)
          mode=INSERT
          ;;
    esac
    print -n -- $mode
}

zle-keymap-select() {
    __set_vi_mode_cursor
    zle reset-prompt
}

zle-line-init() {
    zle -K $DEFAULT_VI_MODE
}

zle -N zle-line-init
zle -N zle-keymap-select

# Optional: allows you to open the in-progress command inside of $EDITOR
autoload -Uz edit-command-line
bindkey -M vicmd 'v' edit-command-line
zle -N edit-command-line

# PROMPT_SUBST enables functions and variables to re-run everytime the prompt
# is rendered
setopt PROMPT_SUBST

# Single quotes are important so that function is not run immediately and saved
# in the variable
RPROMPT='$(__get_vi_mode)'

注意:我仅在 MacOS (10.12.6) 上的 Terminal.app (2.7.3) 中使用 zsh (5.3.1) 测试了此操作。此外,如果您添加,edit-command-line则模式也将正确设置。

相关内容