# Vim Paste Messing Up Indentation - Fix Copied Code Formatting

You copy a nicely formatted code block from a browser or another editor, paste it into Vim, and watch in horror as the indentation cascades further and further to the right with each line. What was once readable code becomes a staggered mess that takes minutes to fix manually. This happens because Vim's auto-indent features treat pasted text as if you typed it character by character, triggering indent rules on every line.

The Problem: Auto-Indent Interference

When you paste text using your terminal's paste function (Ctrl+Shift+V, Cmd+V, or middle-click), Vim receives the text as a stream of characters. Each time a newline character arrives, Vim's auto-indent kicks in, adding extra indentation based on the previous line. This compounds with any existing indentation in your pasted code.

Solution 1: Paste Mode

The most reliable solution is Vim's built-in paste mode, which temporarily disables all auto-formatting options:

vim
:set paste

You'll see -- INSERT (paste) -- in the status line when in insert mode. Now paste your code using your terminal's paste command. The text will appear exactly as copied. When done, turn paste mode off:

vim
:set nopaste

The problem with paste mode is that it's a manual toggle. You have to remember to turn it on before pasting and off afterward. Forgetting to turn it off leaves you without auto-indentation while typing, which is equally frustrating.

Solution 2: Bracketed Paste Mode

Modern terminals support bracketed paste mode, which wraps pasted content in special escape sequences. Vim 8 and later versions can detect these sequences and automatically handle pasted text correctly without needing paste mode.

Add this to your .vimrc:

vim
if has('patch-8.0.0238') || has('nvim')
    " Built-in bracketed paste support
    let &t_BE = "\e[?2004h"
    let &t_BD = "\e[?2004l"
endif

If your terminal supports it, this just works. No more paste mode toggling. Check if it's working by pasting code and watching for the p in the status line (indicating paste mode was auto-detected).

Solution 3: Using Vim's Internal Paste Commands

Instead of using your terminal's paste function, use Vim's built-in paste commands. First, copy text to your system clipboard. Then in Vim:

vim
"+p

This pastes from the system clipboard (+ register) without triggering auto-indent. The "+ register connects to the system clipboard on most systems. On Linux without GUI support, you might need "*p instead.

For pasting in insert mode:

vim
Ctrl+R then +

This inserts the contents of the + register at the cursor position.

Solution 4: Toggle Paste Mode with a Key

You can make paste mode less annoying by binding it to a single key:

vim
set pastetoggle=<F2>

Now pressing F2 toggles paste mode. Press F2, paste your code, press F2 again. This is faster than typing the full commands.

Some users prefer a more intuitive mapping:

vim
nnoremap <Leader>p :set paste!<CR>

This toggles paste mode when you press your leader key followed by p. The ! in paste! toggles the option rather than setting it to a specific value.

Checking Your Indentation Settings

Understanding why auto-indent is happening helps prevent issues. Check these settings:

vim
:set autoindent?
:set smartindent?
:set cindent?
:set indentexpr?
  • autoindent copies the indent from the previous line
  • smartindent adds language-aware indenting for C-like languages
  • cindent provides more sophisticated C-style indentation
  • indentexpr allows custom indentation expressions, often set by filetype plugins

For most programming, you want filetype-based indentation rather than smartindent:

vim
filetype plugin indent on

This loads indentation rules specific to each language, which are generally better than the generic smartindent.

Terminal-Specific Configuration

Some terminals need configuration to work with bracketed paste. In iTerm2, check Preferences > Profiles > Terminal > "Enable bracketed paste mode." Most modern terminals enable this by default.

In tmux, bracketed paste might be intercepted. Add to your .tmux.conf:

bash
set -g terminal-overrides ",*256col*:Tc"

And ensure you're running a recent tmux version (2.4+).

Verifying Your Setup

Test your configuration by copying this code block and pasting it into Vim:

python
def example_function():
    if True:
        print("Level 2")
        for i in range(3):
            print(f"Level 3: {i}")
    return "done"

If the indentation stays intact, your setup works correctly. If lines progressively indent more, you need one of the solutions above.

The bracketed paste approach is the best long-term solution because it works automatically. Until all terminals support it well, paste mode remains a reliable fallback that's been working for decades.