# 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:
:set pasteYou'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:
:set nopasteThe 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:
if has('patch-8.0.0238') || has('nvim')
" Built-in bracketed paste support
let &t_BE = "\e[?2004h"
let &t_BD = "\e[?2004l"
endifIf 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:
"+pThis 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:
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:
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:
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:
:set autoindent?
:set smartindent?
:set cindent?
:set indentexpr?autoindentcopies the indent from the previous linesmartindentadds language-aware indenting for C-like languagescindentprovides more sophisticated C-style indentationindentexprallows custom indentation expressions, often set by filetype plugins
For most programming, you want filetype-based indentation rather than smartindent:
filetype plugin indent onThis 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:
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:
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.