47

When I copy some code from webpages and paste it to Vim, I find it becomes a mess, with a style like a ladder:

xxxxxx
   xxxxxx
      xxxxxx
         xxxxxxxxxx

Since it get messed like this so regularly, I think maybe there's something wrong with my .vimrc, so I've pasted it below:

set number
set nocompatible
set nowritebackup
set noswapfile
syntax on
filetype indent on
filetype plugin on
filetype on
set background=light
set autoindent
set smartindent
set tabstop=4
set shiftwidth=4
set showmatch
set guioptions=T
set fileencodings=utf-8,prc
set ruler
set incsearch
map gs :%s
set t_Co=256
:colorscheme evening
filetype plugin indent on

Usually I write python in Vim, so proper indentation is critical.

1
  • 1
    Thanks. This irked me for years, and I never got around to asking anyone about it. +1.
    – DevSolar
    Apr 26, 2010 at 9:15

5 Answers 5

67

Do this before:

:set paste

Then after:

:set nopaste
6
  • Not needed for gvim; it turns these on and off automatically when pasting. Apr 26, 2010 at 4:49
  • any idea why that is? Apr 26, 2010 at 10:13
  • 1
    Just guessing: Plain vim is command-line only, and doesn't "know" about the clipboard. It takes the "paste" as a input character sequence, and applies auto-indenting. The GUI-aware gvim might "know" that the incoming data is from the clipboard, and thus disable the autoindenting for the purpose.
    – DevSolar
    Apr 26, 2010 at 10:55
  • That's correct. The terminal treats the "paste" operation as raw character input. Apr 26, 2010 at 11:16
  • This isn't purly a vim issue - you can get a similar affect pasting into the old DOS editor in a command prompt. This program seems to be missing in Windows 7 64-bit - presumably because it really is an old 16-bit DOS app and it wasn't worth the hassle of updating it. It's in Windows XP, though, and pasting into that (1) works really slowly, acting out the character-by-character input, and (2) makes a real mess.
    – user31438
    Jul 17, 2012 at 4:17
17

http://vim.wikia.com/wiki/Toggle_auto-indenting_for_code_paste

Toggle auto-indenting for code paste

Background

If you use Vim commands to paste text, nothing unexpected occurs. The problem only arises when pasting from another application, and only when you are not using a GUI version of Vim. In a console or terminal version of Vim, there is no standard procedure to paste text from another application. Instead, the terminal may emulate pasting by inserting text into the keyboard buffer, so Vim thinks the text has been typed by the user. After each line ending, Vim may move the cursor so the next line starts with the same indent as the last. However, that will change the indentation already in the pasted text.

Paste toggle

Put the following in your vimrc (change to whatever key you want):

set pastetoggle=<F2>

To paste from another application:

  • Start insert mode.
  • Press F2 (toggles the 'paste' option on).
  • Use your terminal to paste text from the clipboard.
  • Press F2 (toggles the 'paste' option off).

Then the existing indentation of the pasted text will be retained.

You do not have to start insert mode first, but if you are in normal mode and have a mapping for F2, that mapping will apply, and the 'pastetoggle' function will not operate.

Some people like the visual feedback shown in the status line by the following alternative for your vimrc:

nnoremap <F2> :set invpaste paste?<CR>
set pastetoggle=<F2>
set showmode

The first line sets a mapping so that pressing F2 in normal mode will invert the 'paste' option, and will then show the value of that option. The second line allows you to press F2 when in insert mode, to toggle 'paste' on and off. The third line enables displaying whether 'paste' is turned on in insert mode.

3
  • 1
    +1 for the hotkey solution. For the not-too-firm in VIM (like me) who already have mapped the F-keys to something else (like me), <C-F2> would be Ctrl-F2...
    – DevSolar
    Apr 26, 2010 at 10:53
  • excellent - I am now using this
    – hoju
    Feb 12, 2011 at 0:11
  • why not just map the paste keys to do this automatically, like <S-Insert> or <Ctrl+V>, along with their original functions? Or, write a function that disables paste when more than a few input characters are written to the buffer in the time of a second, its just an idea, of course for me I have almost ALL my keys mapped to other stuff so it's a pain, I even have a keyboard with 12 F keys and + 15 more F keys (G keys), and with that, three levels, which still isn't enough :) but thats just me. The only problem is, the right-click menu, which no esc seqs get sent to signal a start-of-paste op... Oct 27, 2014 at 14:51
2

It is the autoindent that is messing with you.

set autoindent
set smartindent

Try to disable them when you cut and paste your code, and then enable them again when you are done.

0

I learnt this neat automation from coderwall, write the following into your .vimrc file

let &t_SI .= "\<Esc>[?2004h"
let &t_EI .= "\<Esc>[?2004l"

inoremap <special> <expr> <Esc>[200~ XTermPasteBegin()

function! XTermPasteBegin()
  set pastetoggle=<Esc>[201~
  set paste
  return ""
endfunction

and it will switch on and off paste mode for you.

Using vim within tmux can be a little bit tricky, as you may (I use "may" because I do not have to double escape when I am inside tmux) have to double escape using

function! WrapForTmux(s)
  if !exists('$TMUX')
    return a:s
  endif

  let tmux_start = "\<Esc>Ptmux;"
  let tmux_end = "\<Esc>\\"

  return tmux_start . substitute(a:s, "\<Esc>", "\<Esc>\<Esc>", 'g') . tmux_end
endfunction

let &t_SI .= WrapForTmux("\<Esc>[?2004h")
let &t_EI .= WrapForTmux("\<Esc>[?2004l")

function! XTermPasteBegin()
  set pastetoggle=<Esc>[201~
  set paste
  return ""
endfunction

inoremap <special> <expr> <Esc>[200~ XTermPasteBegin()
-2

The lowest amount of effort to achieve this is (can be put into .vimrc):

:set paste

Then paste your code.

2
  • 3
    The 'paste' option was never meant to be permanently set. It disables a lot of things, including mappings and abbreviations. Besides, a previous answer already covers the 'paste' option.
    – Heptite
    Nov 9, 2016 at 5:14
  • 2
    Welcome to Super User! This duplicates an existing answer and adds no new content. Please don't post an answer unless you actually have something new to contribute. Nov 9, 2016 at 9:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .