15

I use vim in a few different contexts; typically, I like to put this in my .vimrc:

let &t_ti.="\<Esc>[1 q"
let &t_SI.="\<Esc>[5 q"
let &t_EI.="\<Esc>[1 q"
let &t_te.="\<Esc>[0 q"

This makes it so that insert and normal mode use different cursors (normal mode is a block cursor and insert mode is a vertical line). This works for me in mintty with cygwin, xterm, and also rvxt just fine. However, whenever I use GNU screen, my cursor no longer changes. I've seen references to fixing this for tmux (for instance here: Cursor shape under vim + tmux), but nothing I've tried for Screen has worked. For now, I'm using this in my .vimrc:

"Underline currently edited line
if !has("gui_running")
    :autocmd InsertEnter * set cul
    :autocmd InsertLeave * set nocul
endif

That makes it so that when in insert mode the current line is underlined (the :has("gui_running") prevents it from taking effect in gvim). I also use set laststatus=2 to keep the status bar on the bottom, which also helps. I just wish it worked a bit more like gvim. Has anyone found a fix for this?

1

1 Answer 1

12

I think I figured it out, although I don't totally understand the fix. This appears to work for mintty, xterm, and rxvt:

" Set up vertical vs block cursor for insert/normal mode
if &term =~ "screen."
    let &t_ti.="\eP\e[1 q\e\\"
    let &t_SI.="\eP\e[5 q\e\\"
    let &t_EI.="\eP\e[1 q\e\\"
    let &t_te.="\eP\e[0 q\e\\"
else
    let &t_ti.="\<Esc>[1 q"
    let &t_SI.="\<Esc>[5 q"
    let &t_EI.="\<Esc>[1 q"
    let &t_te.="\<Esc>[0 q"
endif

This leans on your screenrc having something like "term screen" or "term screen-256color" so that the vimrc file can identify which terminal you're on. The only remaining terminal I use regularly where this doesn't work is PuTTY, but I think it literally doesn't support terminal commands to change the cursor shape. Mintty was forked from PuTTY a while back, and I saw here (https://www.cygwin.com/ml/cygwin-announce/2009-07/msg00011.html) that DECSCUSR support was added to mintty after that fork.

This is good enough for me - if I'm ssh'ing into a machine where I really want my block cursor in Vim, I guess I can either cygwin/ssh or PuTTY/XMing/rxvt my way through it instead of PuTTY.

5
  • 2
    For me, echo &term outputs screen so I changed the regexp in the line starting if &term ... to screen.*. Jun 27, 2016 at 14:42
  • 1
    @KennyEvitt same for me on MacOS. Good catch! Oct 28, 2017 at 21:21
  • Thanks! Your code works for me! Windows 10, mintty 3.4.7 (x86_64-pc-cygwin)
    – kohane15
    Mar 21, 2021 at 4:23
  • This seems to work! It looks like it uses the "Device Control String; Outputs a string directly to the host" to output the usual escape codes per gnu.org/software/screen/manual/html_node/Control-Sequences.html Jan 24 at 14:01
  • 1
    Still saving my sanity, eight years later!
    – Ti Strga
    Mar 6 at 19:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.