t_fe and t_fd in tmux corrupts split with ^[[O

20 views
Skip to first unread message

Enan Ajmain

unread,
Jun 19, 2023, 12:20:35 PM6/19/23
to vim...@googlegroups.com
I have this in my vimrc according to ":h xterm-focus-event":

if &term =~ '\v^(screen|tmux)'
let &t_fe = "\<Esc>[?1004h"
let &t_fd = "\<Esc>[?1004l"
endif

With it in tmux, when I switch panes, the pane with Vim running shows a
control sequence "^[[O" where "^[" is Esc. I had to add this autocmd to
circumvent this:

if &term =~ '\v^(screen|tmux)'
augroup autoread
au!
au FocusLost * :redraw!
augroup END
endif

It works well enough in local machine, but over ssh, it causes annoying
flickering. Did anyone face this before (or does now) and solved it?


In .tmux.conf, I have:

set -g escape-time 10 # wait 10ms after Esc key
set -g repeat-time 500 # wait 100ms for repeating command
set -g focus-events on
set -g set-clipboard on
set -g history-limit 5000

set -g default-terminal "tmux-256color"
set -ga terminal-overrides ',xterm-256color*:Tc'
set -as terminal-overrides ',st-256color:Ms=\E]52;%p1%s;%p2%s\007'
set -ga terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[ q'

is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"

bind-key -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L"
bind-key -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D"
bind-key -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U"
bind-key -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R"
bind-key -n C-\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l"

The later part of the tmux config lets me switch tmux panes and vim
splits with the same keys. The if-shell syntax is straight-forward but
let me know if it's confusing and I can explain.

The versions of Vim and Tmux I'm using is postscripted.

--
Enan

$ tmux -V
tmux 3.2a

$ vim --version
VIM - Vi IMproved 9.0 (2022 Jun 28, compiled Apr 14 2023 03:28:41)
Included patches: 1-1403
Modified by <amazon-li...@amazon.com>
Compiled by <amazon-li...@amazon.com>
Huge version without GUI. Features included (+) or not (-):
+acl +file_in_path +mouse_urxvt -tag_any_white
+arabic +find_in_path +mouse_xterm -tcl
+autocmd +float +multi_byte +termguicolors
+autochdir +folding +multi_lang +terminal
-autoservername -footer -mzscheme +terminfo
-balloon_eval +fork() +netbeans_intg +termresponse
+balloon_eval_term +gettext +num64 +textobjects
-browse -hangul_input +packages +textprop
++builtin_terms +iconv +path_extra +timers
+byte_offset +insert_expand +perl/dyn +title
+channel +ipv6 +persistent_undo -toolbar
+cindent +job +popupwin +user_commands
-clientserver +jumplist +postscript +vartabs
-clipboard +keymap +printer +vertsplit
+cmdline_compl +lambda +profile +vim9script
+cmdline_hist +langmap -python +viminfo
+cmdline_info +libcall +python3/dyn +virtualedit
+comments +linebreak +quickfix +visual
+conceal +lispindent +reltime +visualextra
+cryptv +listcmds +rightleft +vreplace
+cscope +localmap +ruby/dyn +wildignore
+cursorbind +lua/dyn +scrollbind +wildmenu
+cursorshape +menu +signs +windows
+dialog_con +mksession +smartindent +writebackup
+diff +modify_fname -sodium -X11
+digraphs +mouse -sound -xfontset
-dnd -mouseshape +spell -xim
-ebcdic +mouse_dec +startuptime -xpm
+emacs_tags +mouse_gpm +statusline -xsmp
+eval -mouse_jsbterm -sun_workshop -xterm_clipboard
+ex_extra +mouse_netterm +syntax -xterm_save
+extra_search +mouse_sgr +tag_binary
-farsi -mouse_sysmouse -tag_old_static
system vimrc file: "/etc/vimrc"
user vimrc file: "$HOME/.vimrc"
2nd user vimrc file: "~/.vim/vimrc"
user exrc file: "$HOME/.exrc"
defaults file: "$VIMRUNTIME/defaults.vim"
fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -O2 -g -pipe -Wall -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -DSYS_VIMRC_FILE=/etc/vimrc -D_REENTRANT -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
Linking: gcc -Wl,--enable-new-dtags -Wl,-rpath,/usr/lib64/perl5/CORE -Wl,-z,relro -L/usr/local/lib -Wl,--as-needed -o vim -lm -lselinux -lncurses -lrt -lacl -lattr -lgpm -ldl -Wl,--enable-new-dtags -Wl,-rpath,/usr/lib64/perl5/CORE -fstack-protector -L/usr/lib64/perl5/CORE -lperl -lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc

Enan Ajmain

unread,
Jun 19, 2023, 12:55:29 PM6/19/23
to vim...@googlegroups.com
I forgot to add a vital piece of info. I also have vim-tmux-navigator.
Not the Vim plugin, but the minimal necessary code stolen from it.

function! TmuxOrSplitSwitch(wincmd, tmuxdir) abort
let previous_winnr = winnr()
silent! execute "wincmd " . a:wincmd
if previous_winnr == winnr()
call system("tmux list-panes -F '#F' | grep -q Z
\|| tmux select-pane -" . a:tmuxdir)
endif
endfunction

let previous_title = substitute(system("tmux display-message -p
\ '#{pane_title}'"), '\n', '', '')
let &t_ti = "\<Esc>]2;vim\<Esc>\\" . &t_ti
let &t_te = "\<Esc>]2;". previous_title . "\<Esc>\\" . &t_te

nnoremap <silent> <C-h> :call TmuxOrSplitSwitch('h', 'L')<CR>
nnoremap <silent> <C-j> :call TmuxOrSplitSwitch('j', 'D')<CR>
nnoremap <silent> <C-k> :call TmuxOrSplitSwitch('k', 'U')<CR>
nnoremap <silent> <C-l> :call TmuxOrSplitSwitch('l', 'R')<CR>

Turns out, the control code "^[[O" was emitted from TmuxOrSplitSwitch().
All I had to do was prepend a ":h :silent" (not ":h map-<silent>; that
was already there) to the keymap. Now Vim corrupt the window with that
control code.

--
Enan

Bram Moolenaar

unread,
Jun 24, 2023, 2:35:56 PM6/24/23
to vim...@googlegroups.com, Enan Ajmain

Enan Ajmain wrote:

> I have this in my vimrc according to ":h xterm-focus-event":
>
> if &term =~ '\v^(screen|tmux)'
> let &t_fe = "\<Esc>[?1004h"
> let &t_fd = "\<Esc>[?1004l"
> endif
>
> With it in tmux, when I switch panes, the pane with Vim running shows a
> control sequence "^[[O" where "^[" is Esc.

You need to tell Vim to recognize these escape sequences:

execute "set <FocusGained>=\<Esc>[I"
execute "set <FocusLost>=\<Esc>[O"

Since this is quite common it was made the default in patch 9.0.1619.
You only need to define the escape sequences for older Vim versions.


--
hundred-and-one symptoms of being an internet addict:
231. You sprinkle Carpet Fresh on the rugs and put your vacuum cleaner
in the front doorway permanently so it always looks like you are
actually attempting to do something about that mess that has amassed
since you discovered the Internet.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Enan Ajmain

unread,
Jun 25, 2023, 12:06:29 AM6/25/23
to Bram Moolenaar, vim...@googlegroups.com
On Sat, 24 Jun 2023 19:35:47 +0100
Bram Moolenaar <Br...@moolenaar.net> wrote:
> You need to tell Vim to recognize these escape sequences:
>
> execute "set <FocusGained>=\<Esc>[I"
> execute "set <FocusLost>=\<Esc>[O"
>
> Since this is quite common it was made the default in patch 9.0.1619.
> You only need to define the escape sequences for older Vim versions.

Interesting. I wondered why it was there in the help doc but Vim didn't
seem to need it. Thank you for the clarification.


By the way, in my second email, I wrote what the solution to my problem
was:
> [...]
> Turns out, the control code "^[[O" was emitted from TmuxOrSplitSwitch().
> All I had to do was prepend a ":h :silent" (not ":h map-<silent>; that
> was already there) to the keymap. Now Vim corrupt the window with that
> control code.

But I forgot "doesn't" in there. The last line should've said: Now Vim
_doesn't_ corrupt the window with that control code.

--
Enan

Bram Moolenaar

unread,
Jun 26, 2023, 11:35:59 AM6/26/23
to vim...@googlegroups.com, Enan Ajmain

> On Sat, 24 Jun 2023 19:35:47 +0100
> Bram Moolenaar <Br...@moolenaar.net> wrote:
> > You need to tell Vim to recognize these escape sequences:
> >
> > execute "set <FocusGained>=\<Esc>[I"
> > execute "set <FocusLost>=\<Esc>[O"
> >
> > Since this is quite common it was made the default in patch 9.0.1619.
> > You only need to define the escape sequences for older Vim versions.
>
> Interesting. I wondered why it was there in the help doc but Vim didn't
> seem to need it. Thank you for the clarification.

I have been working on the terminal configuration support, removing
built-in hard coded values and depending more on termcap/terminfo.
Unfortunately, the latter has not been kept up-to-date for recently added
terminal features. Partly to blame on Vim's built-in support for xterm
and terminals declaring themselves to be xterm-compatible (even though
that's not 100% true). Result is that there was hardly any motivation
to make termcap/terminfo work better.

I'm trying to make support for various terminals work "properly", but it
is quite a struggle, it will take time. I hope terminal emulator
authors will cooperate, but there is a tendency of having a different
opinion of what "properly" is. This can lead to very long discussions
without a clear outcome. To avoid getting stuck I may sometimes pull
the "dictator" card and decide what is best for Vim.

For example, for supporting modifiers on special keys there is the
"modifyOtherKeys" protocol (supported by xterm and a few others). But
for some this was considered insufficient and the Kitty keyboard
protocol was added (which for a large part does the same thing, but with
some differences that helps some users and makes it complicated for
others).

The first step is to agree on how to make it work, then convince enough
people to implement it that way. Hopefully we then have enough traction
that others will follow.

For the keyboard protocol support I didn't see a way to convince all
terminal authors to support modifyOtherKeys or Kitty, thus I chose to
support both. It's a bit tricky, but it looks like it is working OK
now.

--
hundred-and-one symptoms of being an internet addict:
240. You think Webster's Dictionary is a directory of WEB sites.
Reply all
Reply to author
Forward
0 new messages