'(Vi-Mode Ubiquitous Cursor Indicator)
Audience: programmers
It should be as easy as possible to tell if you’re in normal or insert mode.
Your eye tends to be on your cursor, so you’ll find the cursor to be the best
indicator of your mode. Of course, you’re effectively in Vim when in Zsh
(bindkey -v
, right?), too, so it should have the same cursor indicator.
This recipe has been described scattershot in various places, but never comprehensively. This version will give you a solid block cursor in normal mode, and a blinking, gray underscore cursor in insert mode. I’ve also set it to green block for Zsh, blue for Vim. Change it to whatever you like. It’s big and bright so you can easily find it. Then it’s small and flashing to remind you to get out of insert mode. Whatever colors/styles you choose, rejoice that it now works!
I worked for a couple years without having this working in Tmux and it drove me crazy. Now that it works well, I find myself using Tmux much more often.
This has been battle tested in URxvt, but it also seems to work in Xterm and Termite.
Zsh
~/.zshrc
# Modal cursor color for vi's insert/normal modes. # http://stackoverflow.com/questions/30985436/ # https://bbs.archlinux.org/viewtopic.php?id=95078 # http://unix.stackexchange.com/questions/115009/ zle-line-init () { zle -K viins #echo -ne "\033]12;Grey\007" #echo -n 'grayline1' echo -ne "\033]12;Gray\007" echo -ne "\033[4 q" #print 'did init' >/dev/pts/16 } zle -N zle-line-init zle-keymap-select () { if [[ $KEYMAP == vicmd ]]; then if [[ -z $TMUX ]]; then printf "\033]12;Green\007" printf "\033[2 q" else printf "\033Ptmux;\033\033]12;red\007\033\\" printf "\033Ptmux;\033\033[2 q\033\\" fi else if [[ -z $TMUX ]]; then printf "\033]12;Grey\007" printf "\033[4 q" else printf "\033Ptmux;\033\033]12;grey\007\033\\" printf "\033Ptmux;\033\033[4 q\033\\" fi fi #print 'did select' >/dev/pts/16 } zle -N zle-keymap-select
Vim
~/.vimrc
" http://vim.wikia.com/wiki/Configuring_the_cursor " Tmux details: http://reza.jelveh.me/2011/09/18/zsh-tmux-vi-mode-cursor if &term =~ "xterm\\|rxvt" " Insert let &t_SI = "\<Esc>]12;gray\x7" let &t_SI .= "\<Esc>[3 q" " Normal let &t_EI = "\<Esc>]12;green\x7" let &t_EI .= "\<Esc>[2 q" autocmd VimLeave * silent !echo -ne "\033]112\007" elseif &term =~ "screen-it" " Insert let &t_SI = "\<Esc>Ptmux;\<Esc>\<Esc>]12;gray\x7\<Esc>\\" let &t_SI .= "\<Esc>Ptmux;\<Esc>\<Esc>[3 q\<Esc>\\" " Normal let &t_EI = "\<Esc>Ptmux;\<Esc>\<Esc>]12;blue\x7\<Esc>\\" let &t_EI .= "\<Esc>Ptmux;\<Esc>\<Esc>[2 q\<Esc>\\" autocmd VimLeave * silent !printf "\033Ptmux;\033\033]12;grey\007\033\\" endif
Tmux
I like to keep these lines in my .tmux.conf
so I can easily access the
infocmp
and tic
commands to run on new machines.
Note that TERM
will be auto-set by Tmux now to screen-it
.
~/.tmux.conf
)# One-time setup for italic support (instead of reverse). # http://tmux.svn.sourceforge.net/viewvc/tmux/trunk/FAQ # % infocmp screen-256color | # sed -e 's/^screen[^|]*|[^,]*,/screen-it|screen with italics support,/' \ # -e 's/%?%p1%t;3%/%?%p1%t;7%/' \ # -e 's/smso=[^,]*,/smso=\\E[7m,/' \ # -e 's/rmso=[^,]*,/rmso=\\E[27m,/' \ # -e '$s/$/ sitm=\\E[3m, ritm=\\E[23m,/' \ # >| /tmp/screen.terminfo # Compile and create binary file ~/.terminfo/s/screen-it # % tic /tmp/screen.terminfo # This is actually active. set -g default-terminal "screen-it"
Addendum
There is still an issue where on Tmux pane/window changing, the cursor stays in the mode that its last pane/window was in.