Changing cursor style based on mode in both zsh and vim
I think it's better to use precmd()
instead of preexec()
:
# .zshrc
_fix_cursor() {
echo -ne '\e[5 q'
}
precmd_functions+=(_fix_cursor)
This way:
- you don't have to change
.vimrc
- cursor is fixed also when you create a new prompt without executing a command
- you don't have to write
echo -ne '\e[5 q'
twice in your.zshrc
.
I have found a solution:
I put this in my ~/.vimrc
:
autocmd VimEnter * silent exec "! echo -ne '\e[1 q'"
autocmd VimLeave * silent exec "! echo -ne '\e[5 q'"
This works perfectly for me, it's taken from here: https://gist.github.com/LukeSmithxyz/e62f26e55ea8b0ed41a65912fbebbe52
# vi mode
bindkey -v
export KEYTIMEOUT=1
# 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
zle-line-init() {
zle -K viins # initiate `vi insert` as keymap (can be removed if `bindkey -V` has been set elsewhere)
echo -ne "\e[5 q"
}
zle -N zle-line-init
echo -ne '\e[5 q' # Use beam shape cursor on startup.
preexec() { echo -ne '\e[5 q' ;} # Use beam shape cursor for each new prompt.
You can customise the type of cursor you want (blinking or not, |, rectangle or _) by changing the numbers in the following sequences \e[5 q
(5 is for beam, 1 is for block) as follows:
Set cursor style (DECSCUSR), VT520.
0 ⇒ blinking block.
1 ⇒ blinking block (default).
2 ⇒ steady block.
3 ⇒ blinking underline.
4 ⇒ steady underline.
5 ⇒ blinking bar, xterm.
6 ⇒ steady bar, xterm.