Fixing paste in vim running under tmux (bracketed paste)
Writing this mostly as a reference for myself should I run into this problem in the future.
Pasting into vim
running under tmux
was producing weird results. For
example pasting wiwiw
would actually produce Wiw
.
This looked as if inserted characters were being wrapped into something that:
- told
vim
to leave the insert mode (notice how text gets inserted after the firsti
in the pasted text) - sent the paste to
vim
which started to interpret it as commands - exited the insert mode and sent some more commands (jump to the start of
line and change the case of first
w
)
Turns out this exactly was the case and this behaviour is called bracketed
paste mode. In this mode
terminal emulator intentionally marks pasted text for an application to be able
to adjust behaviour if needed. For example vim
can automatically enable paste
mode and preserve indentation of the pasted text.
Unfortunately something breaks with detection of this mode when vim
is
running under tmux
and terminal emulator keeps using this mode while vim
does not expect it. As a result vim
interprets control characters as normal
input and corrupts the pasted text.
This mode (including the problem with vim
and tmux
combination) is well
described in Vim's :help xterm-bracketed-paste
section of the Vim reference
manual (at least the one for Vim version 9.1). At the moment I'm running vim
with the recommended configuration which solves the pasted text corruption
issue for me:
Specific part that handles bracketed paste mode is this:
" Enable bracketed paste mode, see :help xterm-bracketed-paste
let &t_BE = "\<Esc>[?2004h"
let &t_BD = "\<Esc>[?2004l"
let &t_PS = "\<Esc>[200~"
let &t_PE = "\<Esc>[201~"
Currently evaluating the larger block suggested in the manual:
if !has('gui_running') && &term =~ '^\%(screen\|tmux\)'
" Better mouse support, see :help 'ttymouse'
set ttymouse=sgr
" Enable true colors, see :help xterm-true-color
let &termguicolors = v:true
let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
" Enable bracketed paste mode, see :help xterm-bracketed-paste
let &t_BE = "\<Esc>[?2004h"
let &t_BD = "\<Esc>[?2004l"
let &t_PS = "\<Esc>[200~"
let &t_PE = "\<Esc>[201~"
" Enable focus event tracking, see :help xterm-focus-event
let &t_fe = "\<Esc>[?1004h"
let &t_fd = "\<Esc>[?1004l"
execute "set <FocusGained>=\<Esc>[I"
execute "set <FocusLost>=\<Esc>[O"
" Enable modified arrow keys, see :help arrow_modifiers
execute "silent! set <xUp>=\<Esc>[@;*A"
execute "silent! set <xDown>=\<Esc>[@;*B"
execute "silent! set <xRight>=\<Esc>[@;*C"
execute "silent! set <xLeft>=\<Esc>[@;*D"
endif