sjl / vitality.vim

Make Vim play nicely with iTerm 2 and tmux.
http://github.com/sjl/vitality.vim
MIT License
320 stars 30 forks source link

Cursor Visual Movement During Replace #8

Open cmaggard opened 12 years ago

cmaggard commented 12 years ago

I recently switched to using tmux inside iTerm2, and I installed vitality.vim because it was a recommended plugin for this particular trifecta of software. I recently noticed some oddness though- past a certain column, whenever I would hit r to replace a single character, the cursor would visually jump backwards a good bit. It wouldn't affect the replacement but it was still visually jarring. It would jump back even further if I hit ESC instead of doing the replacement. Once again, the cursor didn't actually move, but since I was now in normal mode it was even more off-putting.

(Col 13) r : Cursor changes and stays in place (Col 14+) r: Cursor changes and visually moves back ~13 columns.

There are two workarounds that I've found:

set showcmd works for me in the meantime- just wanted to give you a heads up.

vim - 7.3.462 (same issue with 7.3 and 7.3.333) tmux - 1.6 iTerm2 - 1.0.0.20120203

jtmkrueger commented 12 years ago

I'm having the same issue, and set showcmd worked for me as well

aaronjensen commented 12 years ago

set showcmd has another problem, but only in tmux: open a large file (bigger than your current screen) and hit dd. Wrapping will break and you'll have to force rerender the pane somehow

cmaggard commented 12 years ago

I've run into this as well- it seems to be related to #3. I can reliably reproduce that issue as well, though my test case is just using x.

aaronjensen commented 12 years ago

Note: this is for iterm2 only

Good news everyone, looks like I found a solution thanks to the guys at casecommons...

Add to your .tmux.conf:

set-option -g terminal-overrides '*88col*:colors=88,*256col*:colors=256,xterm*:XT:Ms=\E]52;%p1%s;%p2%s\007:Cc=\E]12;%p1%s\007:Cr=\E]112\007:Cs=\E]50;CursorShape=%?%p1%{3}%<%t%{0}%e%p1%{2}%-%;%d\007'

Add to your .vimrc:

if exists('$TMUX')
  let &t_SI = "\<Esc>[3 q"
  let &t_EI = "\<Esc>[0 q"
endif

https://github.com/Casecommons/casecommons_workstation/blob/master/templates/default/dot_tmux.conf.erb https://raw.github.com/Casecommons/vim-config/7b850c841b464210728ef89b99ae6a29d0ff2c7d/init/tmux.vim

aaronjensen commented 12 years ago

Oh and one more thing, w/ the above solution you do not need vitality.vim for the cursor change, that is all you need.

aaronjensen commented 12 years ago

@slj have you seen this solution? This fixes the problems w/ the cursor change in tmux. I've made some updates since this: https://github.com/aaronjensen/vimfiles/blob/master/vimrc#L438-453

I wonder if you should incorporate this into vitality?

sjl commented 12 years ago

Can you explain what each part of that does? I don't want to just start throwing in random magical numbers without knowing what they do.

aaronjensen commented 12 years ago

Sure.

The escape codes in t_SI and t_SE are standard cursor change escapes. Tmux supports mapping these back to the terminal via terminal-overides:

TERMINFO EXTENSIONS
     tmux understands some extensions to terminfo(5):

     Cc, Cr  Set the cursor colour.  The first takes a single string argument and is used to set the colour; the second takes no arguments and
             restores the default cursor colour.  If set, a sequence such as this may be used to change the cursor colour from inside tmux:

                   $ printf '\033]12;red\033\\'

     Cs, Csr
             Change the cursor style.  If set, a sequence such as this may be used to change the cursor to an underline:

                   $ printf '\033[4 q'

             If Csr is set, it will be used to reset the cursor style instead of Cs.

     Ms      This sequence can be used by tmux to store the current buffer in the host terminal's selection (clipboard).  See the
             set-clipboard option above and the xterm(1) man page.

In order to make these work with tmux, you must override Cs. The terminal-overrides listed above are the default overrides (check yours with show-option -g) plus a modified Cs. The Cs is a bit tricky, but it works like this:

\E]50;CursorShape= # iterm escape sequence to change cursor shape
%?   # if the first param is less than 3 (push the result onto the stack)
  %p1   # push the first param onto the stack (0 or 3)
  %{3}   # push a literal 3 onto the stack
  %<     # return true if the first param is less than 3
%t   # then
  %{0}   # push a literal 0 onto the stack (CursorShape=0)
%e   # else
  %p1   # push the first param onto the stack (3 in this case)
  %{2}   # push a literal 2 onto the stack
  %-   # subtract (pushes 1 onto the stack, CursorShape=1)
%;   # endif
%d   # pops a digit onto the stack (either 0 or 1)
\007   # end the escape sequence

Let me know if you have any other questions, happy to help.

aaronjensen commented 12 years ago

The t_SI and t_SE come from http://invisible-island.net/xterm/ctlseqs/ctlseqs.html

CSI P s SP q

Set cursor style (DECSCUSR, VT520).
P s = 0 → blinking block.
P s = 1 → blinking block (default).
P s = 2 → steady block.
P s = 3 → blinking underline.
P s = 4 → steady underline.
tylerball commented 12 years ago

@aaronjensen your solution doesn't work for me on Ubuntu 10.04 LTS running tmux 1.6 and vim 7.3. For now, I'm using the following, which works fine so far:

au InsertLeave * redraw!
aaronjensen commented 12 years ago

@tylerball no, it wouldn't. it's an iterm specific solution.

tylerball commented 12 years ago

Sorry, Ubuntu is the OS I'm ssh-ing into. I'm using iTerm2 on my 10.6.8 Mac. Does this tmux 'terminal-overrides' solution only work locally?

On Tue, Aug 28, 2012 at 4:46 PM, Aaron Jensen notifications@github.comwrote:

@tylerball https://github.com/tylerball no, it wouldn't. it's an iterm specific solution.

— Reply to this email directly or view it on GitHubhttps://github.com/sjl/vitality.vim/issues/8#issuecomment-8106399.

-Tyler

aaronjensen commented 12 years ago

@tylerball I ssh'd to myself, opened tmux then vim and it worked fine. Some things to check:

xterm*:XT:Ms=\E]50;CopyToClipboard=general\007\E]50;EndCopy\007:Cc=\E]12;%p1%s\007:Cr=\E]112\007:Cs=\E]50;CursorShape=%?%p1%{3}%<%t%{0}%e%p1%{2}%-%;%d\007"
oranki commented 9 years ago

This works for both setting cursor colour and style per window/pane:

set -g terminal-overrides '*88col*:colors=88,*256col*:colors=256,xterm*:XT:Cs=\E]Pl%p1%s\E\\:Ss=\E]50;CursorShape=%d\007'

for setting cursor color:

printf '\033]12;%s\007' "rrggbb"

for setting cursor style:

printf '\033[%s q' "n"

rrggbb is 2-digit hex triplet specifying an RGB value, and n is digit 0, 1 or 2 (block, vertical bar, underline)