Turning off auto indent when pasting text into vim

497,827

Solution 1

Update: Better answer here: https://stackoverflow.com/a/38258720/62202

To turn off autoindent when you paste code, there's a special "paste" mode.

Type

:set paste

Then paste your code. Note that the text in the tooltip now says -- INSERT (paste) --.

After you pasted your code, turn off the paste-mode, so that auto-indenting when you type works correctly again.

:set nopaste

However, I always found that cumbersome. That's why I map <F3> such that it can switch between paste and nopaste modes while editing the text! I add this to .vimrc

set pastetoggle=<F3>

Solution 2

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.

Solution 3

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

No need to enable & disable, direct usage.

Solution 4

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.

Solution 5

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

Share:
497,827
Muhammad Hashir Anwaar
Author by

Muhammad Hashir Anwaar

I am a full stack Software Engineer on the web. Most of my work is remote and based in Australia. Over the course of my career, I have enjoyed working with talented engineering teams on a wide range of applications using different technologies. I have managed simple customer-facing applications and I have been fortunate to work with large teams on complex, high-budget, mission-critical code bases. I focus on delivering quality products that are functional, reliable, intuitive and that meet specifications. I am thorough, methodical in my work. I document, test and check what I do and I communicate effectively. I am creative, very strong in analytical problem-solving and I’m always evaluating my performance. I like mentoring and learning from other people. I believe I can cook a decent curry from scratch and I can bake bread without looking at the recipe.

Updated on July 08, 2022

Comments

  • Muhammad Hashir Anwaar
    Muhammad Hashir Anwaar almost 2 years

    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  
    
  • Leopd
    Leopd about 14 years
    This isn't any easier than :set noai followed by :set ai. The suggestion of :r! cat is shorter.
  • thomasrutter
    thomasrutter over 11 years
    I write this answer ages ago. Nowadays I use :set paste and :set nopaste instead because despite being longer, it's easier to remember and I don't have to look it up every time!
  • Victor Zamanian
    Victor Zamanian over 11 years
    I think set paste is easier, definitely. It is much more semantic than noai or even noautoindent, which is more important when typing "noai" and "paste" take about the same insignificant amount of time when you are proficient enough as a touch typist.
  • MarkHu
    MarkHu about 11 years
    :set noai doesn't always work, depending on how the other indent-related settings are configured as per the OP. :set paste appears to be a shorthand for several settings all at once.
  • imwilsonxu
    imwilsonxu almost 11 years
    Finally! I kept typing :set paste / :set nopaste, how stupid! Thx.
  • jcarballo
    jcarballo almost 11 years
    In some embedded systems (based on busybox mainly) :set paste is not implemented, so :set noai should be used instead.
  • Matt Ryan
    Matt Ryan over 10 years
    Late to the party, but set copyindent will take care of this for you seamlessly.
  • pedromanoel
    pedromanoel about 10 years
    When you have a large text to copy, isn't it faster to use the + register instead?
  • thomasrutter
    thomasrutter about 10 years
    @pedromanoel that only works when working locally. It won't work accessing vim over SSH, for example, if you copied something locally and want to paste it into vim which is in your SSH session.
  • BrightIntelDusk
    BrightIntelDusk about 10 years
    I found that in a telnet session to an embedded system using :set noai works correctly.
  • Manuel Faux
    Manuel Faux almost 10 years
    :set paste also disables other features like braces completion, which is also not wanted when pasting code.
  • Drew Noakes
    Drew Noakes over 9 years
    Is that the case if you include the OP's directives in your .vimrc file?
  • Matt Clark
    Matt Clark over 9 years
    Working in vim on a DD-WRT build, :set paste does not work, however :set noai does. Thanks for that @Leopd, took me forever to figure this out.
  • Lynob
    Lynob over 9 years
    from a practical point of view, your answer is more useful than the accepted answer
  • Chris
    Chris about 9 years
    Another option is to add a macro to your vimrc: nmap <silent> <leader>p :set paste<CR>"*p:set nopaste<CR>
  • jvriesem
    jvriesem over 8 years
    Is there a way to disable autoindent in my .vimrc only when pasting from the system clipboard?
  • LCC
    LCC over 8 years
    @jvriesem: there is a plugin for that: github.com/ConradIrwin/vim-bracketed-paste
  • jvriesem
    jvriesem over 8 years
    I like this direct usage option. I'm still learning how to read vim syntax on web pages, though. What do your steps mean? In particular, supposing I have something on the system clipboard, what do I press to paste it into a document in vim?
  • jvriesem
    jvriesem over 8 years
    This is an awesome response. When I do this, however, it hides the document (it looks like I'm back on the command line), but has the text on my clipboard. It prompts me to press enter, so I do, and it returns me back to my document without any changes. What happened, and how do I do what you are saying?
  • studgeek
    studgeek about 8 years
    Thanks for the tip. I also tracked down a plugin where the person has bundled up similar functionality - stackoverflow.com/a/36512548/255961.
  • K Erlandsson
    K Erlandsson about 8 years
    This answer would be more helpful with information about why and how :r! cat works.
  • Daniel
    Daniel over 7 years
    @KErlandsson, :r inserts the contents of a file into the current document. !cat says, run cat which essentially opens stdin (*nix shells) (shift + insert) or for some terminals, right mouse click will paste the contents of the clipboard to the terminal CTRL+D is end-of-file, so it close the :r !cat session.
  • RichVel
    RichVel over 7 years
    Nice suggestion @Chris - single key sequence to paste without indentation issues!
  • heisian
    heisian over 7 years
    :set paste was the only thing that worked for me. OS X El Capitan / Terminal
  • stdout
    stdout over 7 years
    FYI set noai works in BusyBox's vi whereas :set paste does not.
  • sh1
    sh1 over 7 years
    This answer is out of date. There are better solutions further down that automate this mode switching according to signals from the terminal.
  • helvete
    helvete over 6 years
    @sh1: What solutions do you mean?
  • sh1
    sh1 over 6 years
    @helvete, here for example.
  • 0xc0de
    0xc0de over 6 years
    @Leopd Though the OP just wanted autoindent turned off, setting paste mode is the best and complete option as there can be many other undesired effects (like autocompletion) to avoid. Code golfing approach doesn't suite here. Original/fundamental intentions of those options are different.
  • 0xc0de
    0xc0de over 6 years
    Wait, what, you use 'jk' for this?
  • 0xc0de
    0xc0de over 6 years
    Is this 'direct', really? Than setting an option paste made solely for this purpose? @jvriesem This isn't a 'direct' option, if what I assume of your understanding of that word is correct.
  • 0xc0de
    0xc0de over 6 years
    @sh1 'Outdated', really? How can setting builtin options be outdated by any plugin? It just uses a trick to simplify this task. Besides it says: - Unfortunately, this means that they will also run the contents of the input buffer if there's a newline in anything you paste into the terminal. - I hope you are aware of and understand that.
  • 0xc0de
    0xc0de over 6 years
    Beware of what it also notes further: Unfortunately, this means that they will also run the contents of the input buffer if there's a newline in anything you paste into the terminal.
  • Goblinhack
    Goblinhack over 6 years
    Oh yeah, I'd forgotten to mention that. Just add ":inoremap jk <esc>" to your .vimrc. As to why I use jk, ask Apple and why they felt the need to move and get rid of the physical escape key. 8(
  • Goblinhack
    Goblinhack over 6 years
    BTW it takes some training but after a while jk feels faster and I think I prefer it now over escape... Anyway would be interesting to know if iTerm2 accepts <ESC> here also.
  • 0xc0de
    0xc0de over 6 years
    Way to go Apple!
  • sh1
    sh1 over 6 years
    @0xc0de, that quote is not relevant here. That's talking about what a shell will do when it does not support bracketed paste mode. That's the point in bracketed paste mode -- to stop that from happening.
  • sh1
    sh1 over 6 years
    @0xc0de, I am quite plainly arguing that "[using] a trick to simplify this task" is better. I say "this answer is out of date" because the solutions that I'm saying are better were posted much later than this. I'm sure that when this became the accepted answer it did deserve it and I don't mean to be critical of that decision in the context that it was made.
  • jjj
    jjj over 6 years
    This worked much better for me than the other solutions. Thanks.
  • Paul Rougieux
    Paul Rougieux over 6 years
    You can also use :r! cat then CTRL+SHIFT+V to paste in the terminal (then CTRL+D).
  • maxwell
    maxwell over 6 years
    what if I never want to be in paste mode? is there a way to permanently disable?
  • Dane
    Dane about 6 years
    @thomasrutter but I mapped this to <leader>p.. very useful!
  • SergioAraujo
    SergioAraujo about 6 years
    So, we cand do something like: :inoremap <silent> <C-r>+ <C-o>"+p
  • LightMan
    LightMan almost 6 years
    IMHO, this is the best answer, no need for toggling with F11 (which is preconfigured by default in vim). This works in macs OSX system, I don't know about the others.
  • John Jiang
    John Jiang over 5 years
    This seems to cause a string of 'eeeeeee' when I insert a piece of text from my clipboard.
  • Julius Š.
    Julius Š. over 5 years
    This is briliant. One thing though... With every paste I get a "0" (zero) charracter in the start of every paste. Any tip for that?
  • Daithí
    Daithí over 5 years
    also note in if using tmux then you need to double escape. Code for this is in Coderwall link in answer
  • David
    David almost 5 years
    best and simplest way! Also, Google suggested it in Featured snippet for my search 'paste content no tabs vim', maybe because, I used 'tab' keyword, only in this answer mentioned :)
  • wisbucky
    wisbucky almost 5 years
    @jvriesem, with Vim 8+, it can do "set paste" for you when pasting from the system clipboard. That way you don't have to "set paste" manually, and won't forget to turn it off after. stackoverflow.com/questions/2514445/…
  • k1133
    k1133 almost 5 years
    If you are even lazier and copy pasting above code into your .vimrc, do take care of the indentation of the function XTermPasteBegin().
  • Adiii
    Adiii over 4 years
    shotest and simplest ctrl+d
  • Fuseteam
    Fuseteam over 4 years
    i have noticed using middle click in vim doesn't appear to mess up indentation so that might be an idea
  • PatS
    PatS about 4 years
    If you just type :.!pbpaste, this should work by replacing the current line with the output of the paste buffer. In general, vim allows you to pipe data that is in your current file to another program and replace the text with the output of the command. So :1,3!pbpaste replaces the first three lines of your file with the paste buffer. I use :.!ppjson to take a very long (unformatted JSON string) and format it and replace the long string with the formatted equivalent. ppjson is just a bash script that runs python -m json.tool.
  • PatS
    PatS about 4 years
    I was curious how this worked, and so I searched for Paste Bracketing and found gitlab.com/gnachman/iterm2/-/wikis/Paste-Bracketing which explains that the t_SI and t_EI variables are enabling paste bracketing and disabling it. When paste bracketing is on, pasted text is prefixed by esc[200~ and followed by esc[201~.
  • apaderno
    apaderno almost 4 years
    I added set pastetoggle=<F12> to the .vimrc file, as F10 was showing the terminal menu.
  • aadibajpai
    aadibajpai over 3 years
    same boat—did you end up setting a keyboard shortcut or using a plugin or something that is a viable option? Or just living with it :)
  • Stephen C
    Stephen C over 3 years
    @aadibajpai I put set pastetoggle=<F2> in my .vimrc so pressing F2 toggles paste on and off.
  • Nicolas Martel
    Nicolas Martel over 3 years
    Cheers, this is the best solution so far since I only have this problem with <C-r> for some reason, p in command mode is unaffected by this problem. Ideally it would be nice if <C-r> could simply behave like p, but this will do in the meantime!
  • Take
    Take over 3 years
    Unfortunately, this mapping delays switching from insert mode to normal mode about half a second. Is there a way to reduce this delay?
  • Take
    Take over 3 years
    I just found a plugin which removes the delay: github.com/ConradIrwin/vim-bracketed-paste
  • Jari Turkia
    Jari Turkia over 3 years
    What if I always want to be in paste mode? is there a way to permanently enable? This auto-indent -stuff is hugely annoying.
  • Soren Bjornstad
    Soren Bjornstad over 2 years
    On Linux, xsel --clipboard instead of pbpaste does the same thing.