4

Edit this issue happens inside a tmux session. The original value of $TERM before starting vim is:

echo $TERM
screen

The issue appears for example when pasting this kind of indented code:

def function(condition):
    if condition:
        print("Hi")
    if not condition:
        print("Bye")

When I press Ctrl+Shift+V in vim's insert mode, auto indentation messes-up the output and this is what appears:

enter image description here

I have to set vim to paste mode :set paste to have the pasted text indented correctly:

enter image description here

I then have to remember to deactivate it with :set nopaste.

This SO answer says that vim can enter and exit automatically from paste mode with bracketed paste mode. It is even supposed to be by default in Vim 8. I have vim 8, how to enable bracketed paste mode for gnome terminal?

7
  • See this answer and also the comments there. If you use export TERM=gnome-256color in your shell before you start Vim, does that make bracketed mode work? Please edit the question to include your original value of $TERM before you change it with this suggestion...
    – filbranden
    May 13, 2020 at 19:16
  • You might also like this answer with some recommendations on how to manage set paste a bit more automatically (particularly disabling it right after pasting and exiting insert mode.)
    – filbranden
    May 13, 2020 at 19:27
  • 1
    The only reason not to migrate this back to SU is to avoid shuffling the question around... but honestly I'm not sure it belongs here if the question is "how to enable bracketed paste in Gnome terminal." (FWIW, my vim uses bracketed paste, but I did have to enable it in ~/.inputrc with set enable-bracketed-paste on)
    – D. Ben Knoble
    May 13, 2020 at 22:26
  • 1
    @PaulRougieux See @user938371's answer! I'm sure that'll be the most comprehensive answer you'll get on this, if anyone knows this stuff @user938271 is the one who does! Follow up on that answer with comments if it's still not working for you. Yeah and apparently you need TERM=xterm-256color, so configure your GNOME Terminal to do that (it might actually be the default.)
    – filbranden
    May 14, 2020 at 15:13
  • 1
    @filbranden adding export TERM=xterm-256color to .bashrc solves the issue. May 14, 2020 at 15:32

2 Answers 2

5

It is even supposed to be by default in Vim 8.

Only if Vim thinks the terminal is xterm-compatible, which is the case if TERM is xterm or some derivative. If TERM is gnome, Vim won't enable the bracketed paste mode automatically; you have to configure it.

I have vim 8, how to enable bracketed paste mode for gnome terminal?

Try this:

if &t_BE == ''
    let &t_BE = "\e[?2004h"
    let &t_BD = "\e[?2004l"
    let &t_PS = "\e[200~"
    let &t_PE = "\e[201~"
endif

t_BE, t_BD, t_PS and t_PE are all terminal options. The first two are sent automatically to the terminal whenever it enters/leaves raw mode; they must be set correctly so that they enable/disable the bracketed paste mode.

The sequences \e?2004h and \e?2004l are documented in xterm's documentation. Look for CSI ? Pm h (or CSI ? Pm l), then for Ps = 2 0 0 4.

Ps = 2 0 0 4 ⇒ Set bracketed paste mode, xterm.
...
Ps = 2 0 0 4 ⇒ Reset bracketed paste mode, xterm.

t_PS and t_PE tell Vim which sequences the terminal will use to surround the pasted text. The values are documented here.


To test the code, start Vim like this:

vim +'let @+ = "clipboard\e:echom \"malicious code injected\"\ri"' +startinsert

Then press C-S-v to insert the contents of the clipboard in the Vim buffer. If the only text which is inserted is clipboard and :mess has logged malicious code injected, then it doesn't work.


Note that the bracketed paste mode can be bypassed if the pasted text contains \e[201~; the latter sequence may end the bracketed mode prematurely. See the second example on this page. It doesn't work on all terminals though; see this answer for more info.

Also, the bracketed paste mode does not prevent Vim from auto-indenting the text when inserting the contents of a register with C-r.

$ vim -Nu NONE +'set ai' +':let @a = "Level 1\n    Level 2\n    Level 2\nLevel 1"'
" press:  i C-r a

If 'paste' is reset, you'll get:

Level 1
    Level 2
        Level 2
        Level 1

If 'paste' is set, you'll get:

Level 1
    Level 2
    Level 2
Level 1

You can avoid this issue by pasting from normal mode ("ap), or inserting with C-r C-o or C-r C-p.

FWIW, for this reason, I use these mappings:

ino <expr> <c-r> getregtype(v:register) =~# '<c-v>' ? '<c-r>' : '<c-r><c-o>'
ino <c-r><c-p> <c-r><c-p>
ino <c-r><c-o> <c-r><c-o>
ino <c-r><c-r> <c-r><c-r>

If you use tmux, be aware that the latter supports the bracketed paste mode since version 1.7, but it doesn't use it by default. In the key bindings table, ] is bound to the paste-buffer command:

bind-key    -T prefix       ]                     paste-buffer

If you want paste bracket control codes to be inserted around the buffer, you need to pass the -p flag to paste-buffer. FWIW, I use it in these 3 key bindings:

bind C-p paste-buffer -p
bind p choose-buffer -Z -F "#{buffer_sample}" "paste-buffer -p -b '%%'"
bind -T copy-mode-vi p send -X copy-selection-and-cancel \; paste-buffer -p \; delete-buffer

Update: This was changed in 3f6af41.


For more info, see :h xterm-bracketed-paste.

16
  • 1
    Thanks I'd like to accept your answer since it is well documented, but the solution to my question was simply to add export TERM=xterm-256color to my ~/.bash_aliases. After I did that, bracketed paste worked in vim, i.e. vim didn't mess-up with indentation as illustrated in my OP above. May 14, 2020 at 15:26
  • 1
    @PaulRougieux That's actually in the first line of the answer: "Only if Vim thinks the terminal is xterm-compatible, which is the case if TERM is xterm or some derivative."
    – filbranden
    May 14, 2020 at 15:45
  • 2
    @PaulRougieux It was not the solution, but a solution. You can post your solution, and even accept it if you think it's the right one; there's nothing wrong with that. Personally, I prefer setting TERM with the value gnome-256color in a gnome terminal, and setting Vim options rather than lying about the terminal's identity to all applications.
    – user938271
    May 14, 2020 at 15:49
  • 2
    You could argue that the current answer also contains a lie since it sets the options regardless of the terminal's identity, which means it tells Vim that the terminal supports the bracketed paste mode, while maybe it does not. This is true, but: 1. you can make the if &t_BE guard more sophisticated and use various heuristics to guess whether the terminal can truly support bracketed paste mode and if so how; 2. this lie only affects Vim, it does not affect all the applications running in the terminal contrary to TERM.
    – user938271
    May 14, 2020 at 15:49
  • 1
    This answer to the question How to configure gnome-terminal to use xterm-256color by default? suggest putting ` TERM=xterm-256color` inside gnome terminal's profile preference rather than in the .bashrc so I put it there instead. May 14, 2020 at 15:49
1

This was because I was calling vim inside a tmux session and the $TERM environment variable is equal to "screen" in tmux.

Recommended way

As explained in :h xterm-bracketed-paste and in the other answer above, you can add this to your ~/.vimrc:

" Activate bracketed paste in tmux
if &term =~ "screen"
  let &t_BE = "\e[?2004h"
  let &t_BD = "\e[?2004l"
  exec "set t_PS=\e[200~"
  exec "set t_PE=\e[201~"
endif

After that vim bracketed paste mode becomes enabled also when vim is inside tmux.

Not recommended way

According to this answer and the tmux FAQ.

Provided the underlying terminal supports 256 colours, it is usually sufficient to add one of the following to ~/.tmux.conf:

  set -g default-terminal "screen-256color" 

By default, vim doesn't recognize "screen-256color" as a terminal compatible with bracketed paste, so I changed the setting to

set -g default-terminal "xterm-256color"

After that vim recognized the terminal as compatible with bracketed paste mode.

8
  • 2
    Setting 'default-terminal' to anything other than "screen", "tmux" or a derivative of these 2 values is wrong. It may "fix" your issue, but it will create many other issues. See the tmux man page: For tmux to work correctly, this must be set to ‘screen', ‘tmux' or a derivative of them.
    – user938271
    May 15, 2020 at 12:24
  • @user938271 Thanks, I figured out that TERM=xterm-256color is set by default inside gnome terminal. But tmux overwrites it to TERM=screen. If setting 'default-terminal' is frowned upon, what is the recommended way to carry over TERM=xterm-256color to tmux? And with respect to the OP, what is the recommended way to make vim aware that this is an xterm-256color compatible session so that bracketed paste works. May 15, 2020 at 12:30
  • 1
    I’ve had better luck with tmux or tmux-256color (manually compiled) as TERM—tmux requires a screen or tmux variant.
    – D. Ben Knoble
    May 15, 2020 at 12:50
  • 1
    @PaulRougieux But tmux overwrites it to TERM=screen Yes, and that's correct. If setting 'default-terminal' is frowned upon, what is the recommended way to carry over TERM=xterm-256color to tmux? There is no recommended way, because doing so is wrong.
    – user938271
    May 15, 2020 at 13:10
  • 2
    @PaulRougieux And with respect to the OP, what is the recommended way to make vim aware that this is an xterm-256color compatible session so that bracketed paste works. I guess you could try to install a shell alias (alias myvim='TERM=xterm-256color vim'), but I would not do that; I would not lie to Vim about the identity of the terminal. If you want to enable bracketed paste mode in a terminal other than xterm, you need to set terminal options; this is explained at :h xterm-bracketed-paste.
    – user938271
    May 15, 2020 at 13:10

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.