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 first i 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