Answers:
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
我会解释,除非我还不太了解
zle reset-prompt
将在重绘时删除提示上方的1(或更多)行(如果您的提示是多行):(这对我来说是个好
您已经找到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
}
在某些终端上,您还可以使用print -n '\e]12;pink\a'
(按颜色名称)或print -n '\e]12;#abcdef\a'
(按RGB规格)更改光标颜色。这些序列在xterm文档中的ctlseqs
文件中进行了描述;现代终端仿真器通常会仿真xterm,尽管它们可能不支持其所有功能。
main
的KEYMAP
不是viins
,不知道为什么。
main
是zsh的别名,viins
或者emacs
取决于zsh在启动时是否以为您最喜欢的编辑器是vi。我以为viins
从模式切换回模式时会用到它vicmd
,但似乎使用了它main
。更新。
zle-line-init
(或其他选择),因为zle-keymap-select
如果按回车键更改键盘映射不会被调用。
对于使用多行提示使用重置提示时遇到问题的人,这对我有用: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
这就是我用来在zsh中的“块”和“光束”形状之间更改光标的方法:
(用白蚁,侏儒末端和伴侣末端测试)
# 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'
}
add-zsh-hook
例如:gist.github.com/MatrixManAtYrService/…–
更改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
从https://bbs.archlinux.org/viewtopic.php?id=95078修改。在gnome终端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
我目前正在将Zsh与Bullet Train主题一起使用。按照塞巴斯蒂安·布拉斯克(Sebastian Blask)答案给出的示例,我最终得到了下面的代码
bindkey -v
KEYTIMEOUT=1
function zle-line-init zle-keymap-select {
case ${KEYMAP} in
(vicmd) BULLETTRAIN_PROMPT_CHAR="N" ;;
(main|viins) BULLETTRAIN_PROMPT_CHAR="I" ;;
(*) BULLETTRAIN_PROMPT_CHAR="I" ;;
esac
zle reset-prompt
}
zle -N zle-line-init
zle -N zle-keymap-select
这只会将默认$更改为字母N,将其更改为普通模式,将I更改为插入模式。
此图片是在正常模式下按Ctrl+ 的示例C:
这是来自塞巴斯蒂安·布拉斯克(Sebastian Blask)的帖子的另一个版本。这样做的目的是尽可能避免干扰,因为我可以找到的所有其他解决方案都使用额外的行,右侧的状态或添加的字符。
$
当启用正常模式时,这只是将颜色从白色更改为红色。根据您的喜好编辑提示
bindkey -v
function zle-line-init zle-keymap-select {
case ${KEYMAP} in
(vicmd) PROMPT=$'%{\e[0;32m%}%~%{\e[0m%} %{\e[0;31m%}$%{\e[0m%} ' ;;
(main|viins) PROMPT=$'%{\e[0;32m%}%~%{\e[0m%} $ ' ;;
(*) PROMPT=$'%{\e[0;32m%}%~%{\e[0m%} $ ' ;;
esac
zle reset-prompt
}
zle -N zle-line-init
zle -N zle-keymap-select
oh-my-zsh
用户版本有一个oh-my-zsh
名为的插件vi-mode
,可以在这里找到:
robbyrussell / oh-my-zsh / plugins / vi-mode
我使用Antigen来管理我的插件,因此包含它就像将其添加到我的插件一样简单.zshrc
:
antigen bundle vi-mode
所述的zsh-VIM-模式插件能够显示为插入,命令,搜索,替换,和视觉模式的指示符。它使用其他答案的基本技术来挂钩各种ZLE挂钩(zle-keymap-select,zle-isearch-update等)。它检查[[ $ZLE_STATE = *overwrite* ]]
替换模式。它检查$REGION_ACTIVE
以识别视觉模式。
离开isearch模式时ZSH如何触发事件的一些怪癖使逻辑变得复杂。
该模块的另一个不错的功能是能够根据模式更改光标形状和颜色。例如,您可以在INSERT模式下使用竖线,而在SEARCH模式下使用闪烁的下划线。
CTRL+C
在vi命令模式下执行类似操作,则提示会重置,但是当您真正处于插入模式时,请在命令模式下指示您。zle-line-init
应始终将指示器更改为插入模式。由于某些原因,$KEYMAP
调用zle-line-init时未正确更新。