69

When I paste code into my Mac OS X terminal window into vim it indents each line. For each line it adds an indent so the text looks like this...

"ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud        
   ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
        reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
             Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
                    deserunt mollit anim id est laborum."

My current workaround is I paste the text first into textmate text editor which keeps the correct formatting. Then I save that file and open it up in vim. Then I use vim yank to paste it.
Is there a setting in my .vimrc that could change this behavior? Or is this a terminal issue?

Sherm Pendley
  • 13,556
  • 3
  • 45
  • 57
eat_a_lemon
  • 3,158
  • 11
  • 34
  • 50
  • 1
    Bracketed paste solves this without the need to call other commands such as `:set paste`. Bracketed paste is available by default in vim 8. But it will only be enabled if vim thinks you are in a Xterm compatible terminal. There are several ways to enable it see [this answer](https://vi.stackexchange.com/a/25315/6671) on vi.stackexchange. – Paul Rougieux May 14 '20 at 16:06

6 Answers6

116

UPDATE: Vim 8 includes native support for Bracketed Paste Mode. It is enabled by default. See Vim’s xterm-bracketed-paste help topic. Users no longer need to do anything to configure Vim to support this.


As of Mac OS X Lion 10.7, Terminal supports “bracketed paste mode,” which enables the terminal emulator to tell the program connected to the tty when the user pastes text, so that the program won’t interpret it as editing commands. Programs that support it send the terminal an escape sequence to enable this mode, in which the terminal surrounds pasted text with a pair of escape sequences that identify the start and end.

To enable this in Vim, put the following code in your ~/.vimrc file:

if &term =~ "xterm.*"
    let &t_ti = &t_ti . "\e[?2004h"
    let &t_te = "\e[?2004l" . &t_te
    function! XTermPasteBegin(ret)
        set pastetoggle=<Esc>[201~
        set paste
        return a:ret
    endfunction
    map <expr> <Esc>[200~ XTermPasteBegin("i")
    imap <expr> <Esc>[200~ XTermPasteBegin("")
    vmap <expr> <Esc>[200~ XTermPasteBegin("c")
    cmap <Esc>[200~ <nop>
    cmap <Esc>[201~ <nop>
endif

This makes it so that when Vim switches the terminal to/from the alternate screen† (t_ti, t_te) it enables/disables bracketed paste mode (ESC [? 2004 h, ESC [? 2004 l). When it receives the escape sequence indicating the start of a paste (ESC [ 200 ~), it enables Paste mode (set paste) and switches to Insert mode if necessary ("i"). When it receives the matching end-of-paste marker (ESC [ 201 ~) it disables Paste mode (pastetoggle) and remains in Insert mode. The cmap commands arrange for the Vim command line to ignore the escape sequences and accept the pasted text as-is.

Note that this only enables bracketed paste mode when the $TERM value starts with "xterm…"; if you're setting $TERM to something else, you may want to revise that test to include your $TERM value. Or, you could omit the test altogether, since it isn’t strictly necessary—it’s just trying to be careful not to do something that might be incompatible with some other terminal type.

In Terminal, this works with all the various Paste commands, as well as drag-and-drop.

† The terminal has a main screen and an "alternate" screen. Each screen has its own contents and state. Text in the alternate screen does not scroll up into the scrollback log. It is typically used by programs that take over control of the whole screen and are therefore referred to as "full screen" programs. This includes vim, emacs, less and top, for example.


As noted by @DenilsonSáMaia this answer has been packaged into a plugin; although, it is obsolete starting in Vim 8: https://github.com/ConradIrwin/vim-bracketed-paste

Chris Page
  • 18,263
  • 4
  • 39
  • 47
  • 2
    You should also add a mapping for command mode (the on you enter with a colon). Otherwise you loose the ability to paste into the command line: `cmap [200~ ` `cmap [201~ ` – raimue Sep 09 '11 at 09:12
  • 4
    This is now supported by iTerm2: http://iterm2.googlecode.com/svn/trunk/appcasts/testing_changes.html – Matt Sep 13 '11 at 20:56
  • @ChrisPage some additions to speed up the esc mapping and make it work in tmux: https://github.com/aaronjensen/vimfiles/blob/master/vimrc#L449-483 – Aaron Jensen Aug 11 '12 at 08:49
  • @AaronJensen do you have a reference to documentation that explains why that’s necessary and how it works? – Chris Page Aug 15 '12 at 02:58
  • @ChrisPage I can't find the docs at the moment, but basically if you map something to XXX whenever you hit vim waits for you to hit something else (:help 'timeout'). The suggested solution is what I posted, to use unused F keys instead. It's in a vim wiki somewhere but I can't find it :/ I believe I found it in the vitality.vim project: https://github.com/sjl/vitality.vim It's easy to test out, just go into visual mode and hit ESC. it should INSTANTLY go back to normal mode. If there's any delay then this can fix it. – Aaron Jensen Aug 16 '12 at 05:20
  • Also since I commented I added a vmap for this. Thanks for this btw, it's great. Also, if your original question is in regard to the tmux wrapping, see the vitality.vim project as well. For documentation see: http://sourceforge.net/mailarchive/forum.php?thread_name=AANLkTinkbdoZ8eNR1X2UobLTeww1jFrvfJxTMfKSq-L%2B%40mail.gmail.com&forum_name=tmux-users – Aaron Jensen Aug 16 '12 at 05:24
  • 7
    This answer has been packaged into a plugin: https://github.com/ConradIrwin/vim-bracketed-paste – Denilson Sá Maia Jul 11 '14 at 13:40
  • 1
    If you don't use the alternate screen, you can enable it in (just) insert mode by modifying `t_SI` and `t_EI` instead of `t_ti` and `t_te` (respectively). – rampion Jun 19 '15 at 02:34
  • @AaronJensen: I tried using and , but I don't see a difference in behavior. It seems to still incur a delay when I type ESC in Visual mode. (Vim 7.4, patches 1-898) – Chris Page Feb 09 '16 at 23:57
  • @ChrisPage then you either have another mapping still that starts w/ esc or your ttimeoutlen is too high. If it's only in visual mode, it's likely another mapping. Try checking `:vmap ` to see if you have anything mapped – Aaron Jensen Feb 10 '16 at 21:35
  • @AaronJensen: I tried this again and I'm not sure I was seeing a delay before. If I map `imap l EL`, when I type `ESC` the `-- INSERT --` indicator goes away immediately. It seems Vim is clever enough to exit Insert mode immediately when it sees `ESC`, but if you then type `l` it returns to Insert mode and inserts `EL`. I only see an obvious delay if I also map `imap lm EM`, in which case typing `ESC` followed by `l` clearly waits the default one-second delay before proceeding. (But still no delay between the `ESC` and `l`.) – Chris Page Nov 23 '16 at 22:32
  • I suppose technically there's a delay, in that typing the following `l` is interpreted as part of the `l` sequence unless you wait for the delay before typing `l`, but in practical terms it seems like users don't experience a delay when typing `ESC` to exit Insert mode. – Chris Page Nov 23 '16 at 22:35
86

Within vim:

:set paste

Put Vim in Paste mode. This is useful if you want to cut or copy some text from one window and paste it in Vim. This will avoid unexpected effects.

John Bachir
  • 22,495
  • 29
  • 154
  • 227
William Pursell
  • 204,365
  • 48
  • 270
  • 300
10

Another way to do this, assuming you have your system clipboard set up properly is to do

"+p

This will paste from the system clipboard.

Denilson Sá Maia
  • 47,466
  • 33
  • 109
  • 111
Aaron Jensen
  • 6,030
  • 1
  • 30
  • 40
  • 3
    `"*p` or `"+p`. The `*` register is the X11 primary selection, and `+` is the clipboard. I don't know if Mac OS X has the same concept as X11. – Denilson Sá Maia Jul 11 '14 at 13:37
9

In addition to the other answers, if you want a quick way to toggle paste mode, add

set pastetoggle=<F2>

to your .vimrc. Now you can toggle paste mode by pressing F2 (or whatever key you choose).

dancavallaro
  • 13,109
  • 8
  • 37
  • 33
  • I also set a pastetoggle to but do so by having F2 call a function. That is because when in paste mode I also want vim to unset "showbreak", so that I can cleaning copy from the editor window. – anthony May 11 '17 at 02:10
  • Note: I also make good use of "listchars" (toggle using set "list") so when not in paste-mode, I can see no-break spaces, tabs, and extra spaces on the end of the line. This normally hidden characters cause me a lot of greif, and listchars lets me know they are their. There are also a number of other hidden unicode space characters vim does not 'show'. – anthony May 11 '17 at 02:10
7

In vim

:set paste

when you want to disable it

:set nopaste

WenbinWu
  • 111
  • 4
5

When working inside a terminal the vim-bracketed-paste vim plugin will automatically handle pastes without needing any keystrokes before or after the paste.

This works in Terminal, iTerm2, and any "modern" x-term compatible terminals that support bracketed paste mode. As an added bonus it works also for tmux sessions. I am using it successfully with iTerm2 on a Mac connecting to a linux server and using tmux.

The plugin is basically a packaged version of the functionality that @Chris Page listed in his answer.

Community
  • 1
  • 1
studgeek
  • 14,272
  • 6
  • 84
  • 96
  • Vim-8 has it built in. BUT also does a insert-paste if you try and past while in command mode. That is you can no longer paste vim commands! Something I have been doing for more than 30 years (from back in 'vi' and 'elvis' days) – anthony May 11 '17 at 02:15
  • Vim 8 has it built-in... from [Patch 8.0.0210](https://github.com/vim/vim/blob/master/runtime/doc/version8.txt) but Debian's current stable, Stretch, doesn't include that patch, only included selected patches past [0197](https://packages.debian.org/stretch/vim). – Martin Dorey Apr 25 '18 at 21:03