[vim] Turning off auto indent when pasting text into vim

I am making the effort to learn Vim.

When I paste code into my document from the clipboard, I get extra spaces at the start of each new line:

line
  line
    line

I know you can turn off auto indent but I can't get it to work because I have some other settings conflicting or something (which look pretty obvious in my .vimrc but don't seem to matter when I take them out).

How do I turn off auto indenting when I paste code but still have vim auto indent when I am writing code? Here is my .vimrc file:

set expandtab  
set tabstop=2  
set shiftwidth=2  
set autoindent  
set smartindent  
set bg=dark  
set nowrap  

This question is related to vim configuration editor indentation auto-indent

The answer is


Stick this in your ~/.vimrc and be happy:

" enables :Paste to just do what you want
command Paste execute 'set noai | insert | set ai'

Edit: on reflection, :r !cat is a far better approach since it's short, semantic, and requires no custom vimrc. Use that instead!


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

It works by detecting bracketed paste mode which is an escape sequence sent by "modern" x-term compatible terminals like iTerm2, gnome-terminal, and other terminals using libvte. 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.


This issue has already been answered, but I though I could also add my own solution:

If you simply want to disable auto-indent system wise, for every file type (basically, disable the auto-indent feature completely), you can do the following:

  1. Backup the indent.vim file:
    sudo mv /usr/share/vim/vim81/indent.vim /usr/share/vim/vim81/indent.vim.orig
  2. Create a new empty indent.vim file:
    sudo touch /usr/share/vim/vim81/indent.vim

Although :pastetoggle or :paste and :nopaste should be working fine (if implemented - they are not always as we can see from the discussion) I highly recomment pasting using the direct approach "+p or "*p and reading with "+r or "*r:

Vim has acess to ten types of registers (:help registers) and the questioner is interested in quotestar and quoteplus from section

  1. Selection and drop registers "*, "+ and "~

Use these registers for storing and retrieving the selected text for the GUI. See quotestar and quoteplus. When the clipboard is not available or not working, the unnamed register is used instead. For Unix systems the clipboard is only available when the +xterm_clipboard feature is present. {not in Vi}

Note that there is only a distinction between "* and "+ for X11 systems.

:help x11-selection further clarifies the difference of * and +:

                                                  quoteplus quote+

There are three documented X selections: PRIMARY (which is expected to represent the current visual selection - as in Vim's Visual mode), SECONDARY (which is ill-defined) and CLIPBOARD (which is expected to be used for cut, copy and paste operations).

Of these three, Vim uses PRIMARY when reading and writing the "* register (hence when the X11 selections are available, Vim sets a default value for 'clipboard' of "autoselect"), and CLIPBOARD when reading and writing the "+ register. Vim does not access the SECONDARY selection.

Examples: (assuming the default option values)

  • Select an URL in Visual mode in Vim. Go to your browser and click the middle mouse button in the URL text field. The selected text will be inserted (hopefully!). Note: in Firefox you can set the middlemouse.contentLoadURL preference to true in about:config, then the selected URL will be used when pressing middle mouse button in most places in the window.

  • Select some text in your browser by dragging with the mouse. Go to Vim and press the middle mouse button: The selected text is inserted.

  • Select some text in Vim and do "+y. Go to your browser, select some text in a textfield by dragging with the mouse. Now use the right mouse button and select "Paste" from the popup menu. The selected text is overwritten by the text from Vim. Note that the text in the "+ register remains available when making a Visual selection, which makes other text available in the "* register. That allows overwriting selected text.

I am a Python user who sometimes copy and paste into Vim. (I switched from Mac to Windows WSL) and this was one of the glitches that bothered me.

If you touch a script.py and then vi script.py, Vi will detect it is a Python script and tried to be helpful, autoindent, paste with extra indents, etc. This won't happen if you don't tell it is a Python script.

However, if that is already happening to you, the default autoindent could be a nightmare when you paste already fully indented code (see the tilted ladder shape below).

I tried three options and here are the results

set paste        # works perfect 
set noai         # still introduced extra whitespace
set noautoindent # still introduced extra whitespace

enter image description here enter image description here


Another answer I did not see until now:

:se paste noai

Another way to paste is via <C-r> in insert mode and dropping the contents of the register (here the global register). See: :h i_ctrl-r and h i_CTRL-R_CTRL-O.

From the vim help documentation:

Insert the contents of a register literally and don't auto-indent. Does the same as pasting with the mouse. Does not replace characters! The '.' register (last inserted text) is still inserted as typed.{not in Vi}

So to paste contents into vim without auto indent, use <C-r><C-o>* in most unix systems.

You can add a mapping in the your vimrc inoremap <C-r> <C-r><C-o> so you can paste the contents of the * register normally without the auto indent by using <C-r>*.

Note: this only works if vim is compiled with clipboard.


From vim: ]p

From outside: "*]p or "+]p


Please read this article: Toggle auto-indenting for code paste

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

Sadly I found the vim plugin mentioned not to be working with iTerm2 3.0.15 (to be fair I don't know if this broke on older versions) - but I found this hack instead.

Map command-p to do the paste and using iTerm2 vim keys. Obviously this only works for iTerm2.

How it works. I use "jk" to enter escape mode so you will also need:

:inoremap jk

in your .vimrc.

Then it just invokes P to enter paste mode, "+p to paste from the clipboard and then P to disable paste mode. hth.

enter image description here


I just put set clipboard=unnamed in my .vimrc. That makes the default paste buffer map to X's clipboard.

So, if I mark a bit of text in a terminal, I can simply press p to paste it in vim. Similarly, I can yank things in vim (e.g. YY to yank the current line into the buffer) and middle click in any window to paste it.

I don't know. I find it super convenient.


The following vim plugin handles that automatically through its "Bracketed Paste" mode: https://github.com/wincent/terminus

Sets up "Bracketed Paste" mode, which means you can forget about manually setting the 'paste' option and simply go ahead and paste in any mode.


This works for me ( case for + register, what i use like exchange buffer between aps ):

imap <silent> <S-Insert> <C-O>:set noai<CR><C-R>+<C-O>:set ai<CR>

Native paste / bracketed paste is the best and simplest way since vim 8 (released in 2016). It even works over ssh! (Bracketed paste works on Linux and Mac, but not Windows Git Bash)

  1. Make sure you have vim 8+ (you don't need the +clipboard or +xterm_clipboard options).

    vim --version | head -1

  2. Simply use the OS native paste command (e.g. ctrl+shift+V or cmd+V) in Normal Mode. Do not press i for Insert Mode.


Test

  1. Copy (ctrl+shift+C or cmd+C) the output of this (2 lines with a tab indent) to the system clipboard:

    echo -e '\ta\n\tb'

  2. Launch a clean vim 8+ with autoindent:

    vim -u NONE --noplugin -c 'set autoindent'

  3. Paste from the system clipboard (ctrl+shift+V or cmd+V) in Normal Mode. Do not press i for Insert Mode. The a and b should be aligned with a single tab indent. You can even do this while ssh-ing to a remote machine (the remote machine will need vim 8+).

  4. Now try the old way, which will autoindent the second line with an extra tab: Press i for Insert Mode. Then paste using ctrl+shift+V or cmd+V. The a and b are misaligned now.


Installing Vim 8


The fastest way I’m aware of to quickly go to paste-insert mode for a one-shot paste is tpope’s unimpaired, which features yo and yO, presumably mnemonics for “you open”. They’re only documented in his vimdoc, as:

A toggle has not been provided for 'paste' because the typical use case of wrapping of a solitary insertion is so wasteful: You toggle twice, but you only paste once (YOPO). Instead, press yo or yO to invoke o or O with 'paste' already set. Leaving insert mode sets 'nopaste' automatically.


Mac users can avoid auto formatting by reading directly from the pasteboard with:

:r !pbpaste

To avoid undesired effects while pasting, there is an option that needs to be set:

set paste

A useful command to have in your .vimrc is set pastetoggle=<F10> or some other button, to easily toggle between paste and nopaste.


I usually use :r! cat and then paste ( shift + insert ) the content, and CTRL+D.

No need to enable & disable, direct usage.


If you are on a mac, macvim seems to handle it well without having to toggle paste.

brew install macvim --override-system-vim


If you are working locally, you can paste from the system clipboard with the key sequence:

"+p

This is a proper vim command, so no need to worry about entering an insert mode or switching off autoindent first.

Of course if you are working remotely (console over SSH, for example) then this won't work and you should go the :set noai, insert mode, paste into console, leave insertmode, :set ai route as described elsewhere.


Add this to your ~/.vimrc and you will only have to press F2 before and after pasting:

set pastetoggle=<F2>

While setting the paste mode with paste/nopaste/pastetoggle is perfectly fine, you still have to manually enable paste mode before pasting and disable paste mode after pasting. Being the lazy person that I am, below is the best solution that I've found so far, which automatically toggles the paste mode when you paste.

Here's a little trick that uses terminal's bracketed paste mode to automatically set/unset Vim's paste mode when you paste. Put following in your .vimrc:

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

Now you can paste without explicitly turning paste mode on/off - it is handled automatically for you.

Source: Coderwall

Note: This solution doesn't work in WSL (Windows 10 Subsystem for Linux). If anyone has a solution for WSL, please update this answer or add it in the comments.

Tmux If using tmux, then the declarations need to be double escaped. The code for this is also in Coderwall


Here is a post by someone who figured out how to remap the paste event to automatically turn paste mode on and then back off. Works for me in tmux/iTerm on MacOSX.


Examples related to vim

Why does using from __future__ import print_function breaks Python2-style print? How to run vi on docker container? How can I install MacVim on OS X? Find and replace strings in vim on multiple lines Running Python code in Vim How do I set the default font size in Vim? Move cursor to end of file in vim Set encoding and fileencoding to utf-8 in Vim How to select all and copy in vim? Why I've got no crontab entry on OS X when using vim?

Examples related to configuration

My eclipse won't open, i download the bundle pack it keeps saying error log Getting value from appsettings.json in .net core pgadmin4 : postgresql application server could not be contacted. ASP.NET Core configuration for .NET Core console application Turning off eslint rule for a specific file PHP Warning: Module already loaded in Unknown on line 0 How to read AppSettings values from a .json file in ASP.NET Core How to store Configuration file and read it using React Hadoop cluster setup - java.net.ConnectException: Connection refused Maven Jacoco Configuration - Exclude classes/packages from report not working

Examples related to editor

Select all occurrences of selected word in VSCode Change the Theme in Jupyter Notebook? How to view Plugin Manager in Notepad++ Set language for syntax highlighting in Visual Studio Code Copy text from nano editor to shell How do I duplicate a line or selection within Visual Studio Code? How to set editor theme in IntelliJ Idea How to change background color in the Notepad++ text editor? What is the difference between Sublime text and Github's Atom What are the advantages of Sublime Text over Notepad++ and vice-versa?

Examples related to indentation

How to indent/format a selection of code in Visual Studio Code with Ctrl + Shift + F Python IndentationError unindent does not match any outer indentation level How to change indentation mode in Atom? How to set HTML Auto Indent format on Sublime Text 3? "Expected an indented block" error? Indent starting from the second line of a paragraph with CSS Indentation Error in Python How to fix/convert space indentation in Sublime Text? How to make the tab character 4 spaces instead of 8 spaces in nano? IndentationError: unexpected unindent WHY?

Examples related to auto-indent

Brackets.io: Is there a way to auto indent / format <html> How to auto-indent code in the Atom editor? Sublime Text 3, convert spaces to tabs How to fix/convert space indentation in Sublime Text? How To Auto-Format / Indent XML/HTML in Notepad++ Difference between Ctrl+Shift+F and Ctrl+I in Eclipse Turning off auto indent when pasting text into vim Tab key == 4 spaces and auto-indent after curly braces in Vim