Indent multiple lines quickly in vi

877,340

Solution 1

Use the > command. To indent five lines, 5>>. To mark a block of lines and indent it, Vjj> to indent three lines (Vim only). To indent a curly-braces block, put your cursor on one of the curly braces and use >% or from anywhere inside block use >iB.

If you’re copying blocks of text around and need to align the indent of a block in its new location, use ]p instead of just p. This aligns the pasted block with the surrounding text.

Also, the shiftwidth setting allows you to control how many spaces to indent.

Solution 2

This answer summarises the other answers and comments of this question, and it adds extra information based on the Vim documentation and the Vim wiki. For conciseness, this answer doesn't distinguish between Vi and Vim-specific commands.

In the commands below, "re-indent" means "indent lines according to your indentation settings." shiftwidth is the primary variable that controls indentation.

General Commands

>>   Indent line by shiftwidth spaces
<<   De-indent line by shiftwidth spaces
5>>  Indent 5 lines
5==  Re-indent 5 lines

>%   Increase indent of a braced or bracketed block (place cursor on brace first)
=%   Reindent a braced or bracketed block (cursor on brace)
<%   Decrease indent of a braced or bracketed block (cursor on brace)
]p   Paste text, aligning indentation with surroundings

=i{  Re-indent the 'inner block', i.e. the contents of the block
=a{  Re-indent 'a block', i.e. block and containing braces
=2a{ Re-indent '2 blocks', i.e. this block and containing block

>i{  Increase inner block indent
<i{  Decrease inner block indent

You can replace { with } or B, e.g. =iB is a valid block indent command. Take a look at "Indent a Code Block" for a nice example to try these commands out on.

Also, remember that

.    Repeat last command

, so indentation commands can be easily and conveniently repeated.

Re-indenting complete files

Another common situation is requiring indentation to be fixed throughout a source file:

gg=G  Re-indent entire buffer

You can extend this idea to multiple files:

" Re-indent all your C source code:
:args *.c
:argdo normal gg=G
:wall

Or multiple buffers:

" Re-indent all open buffers:
:bufdo normal gg=G:wall

In Visual Mode

Vjj> Visually mark and then indent three lines

In insert mode

These commands apply to the current line:

CTRL-t   insert indent at start of line
CTRL-d   remove indent at start of line
0 CTRL-d remove all indentation from line

Ex commands

These are useful when you want to indent a specific range of lines, without moving your cursor.

:< and :> Given a range, apply indentation e.g.
:4,8>   indent lines 4 to 8, inclusive

Indenting using markers

Another approach is via markers:

ma     Mark top of block to indent as marker 'a'

...move cursor to end location

>'a    Indent from marker 'a' to current location

Variables that govern indentation

You can set these in your .vimrc file.

set expandtab       "Use softtabstop spaces instead of tab characters for indentation
set shiftwidth=4    "Indent by 4 spaces when using >>, <<, == etc.
set softtabstop=4   "Indent by 4 spaces when pressing <TAB>

set autoindent      "Keep indentation from previous line
set smartindent     "Automatically inserts indentation in some cases
set cindent         "Like smartindent, but stricter and more customisable

Vim has intelligent indentation based on filetype. Try adding this to your .vimrc:

if has ("autocmd")
    " File type detection. Indent based on filetype. Recommended.
    filetype plugin indent on
endif

References

Solution 3

A big selection would be:

gg=G

It is really fast, and everything gets indented ;-)

Solution 4

Also try this for C-indenting indentation. Do :help = for more information:

={

That will auto-indent the current code block you're in.

Or just:

==

to auto-indent the current line.

Solution 5

Key presses for more visual people:

  1. Enter Command Mode:
    Escape

  2. Move around to the start of the area to indent:
    hjkl

  3. Start a block:
    v

  4. Move around to the end of the area to indent:
    hjkl

  5. (Optional) Type the number of indentation levels you want
    0..9

  6. Execute the indentation on the block:
    >

Share:
877,340
Allain Lalonde
Author by

Allain Lalonde

I'm a Software Developer working on Alternative User Interfaces for business projects. I love working on things that make you "Why?".

Updated on August 04, 2022

Comments

  • Allain Lalonde
    Allain Lalonde almost 2 years

    It should be trivial, and it might even be in the help, but I can't figure out how to navigate it. How do I indent multiple lines quickly in vi?

  • Jonathan Leffler
    Jonathan Leffler over 15 years
    @akdom: interesting; that ('V') was always a key that I used for maps because it had no other use (v and g were two others).
  • R. Martinho Fernandes
    R. Martinho Fernandes over 15 years
    I use >i} (indent inner {} block). Works in vim. Not sure it works in vi.
  • RomanM
    RomanM about 15 years
    @Greg: consider adding to your answer that using set shiftwidth=' ' you can define the indentation size (default is 8) when using < or >
  • Sundar R
    Sundar R over 14 years
    To indent the selection multiple times, you can simply press . to repeat the previous command.
  • gravitation
    gravitation over 14 years
    I had been using control-v to indent by navigating to the front of the line but this is clearly much better.
  • jamessan
    jamessan over 14 years
    @Martinho: text objects, like i} are Vim-specific. Then again, so is visual mode.
  • Kamran Bigdely
    Kamran Bigdely about 13 years
    My problem(in gVim) is that the command > indents much more than 2 blanks (I want just two blanks but > indent something like 5 blanks)
  • Greg Hewgill
    Greg Hewgill about 13 years
    @Kamran: See the shiftwidth setting for the way to change that.
  • Shane Reustle
    Shane Reustle about 13 years
    This is great, but it uses spaces and not tabs. Any possible way to fix this?
  • Kent Fredric
    Kent Fredric about 13 years
    If its using spaces instead of tabs, then its probably because you have indentation set to use spaces. =).
  • Kent Fredric
    Kent Fredric about 13 years
    When the 'expandtab' option is off (this is the default) Vim uses <Tab>s as much as possible to make the indent. ( :help :> )
  • user606723
    user606723 about 13 years
    This is really useful. I am going to have to look up what all works with this. I know d'a and y'a, what else?
  • Amit
    Amit almost 13 years
    Both this answer and the one above it were great. But I +1'd this because it reminded me of the 'dot' operator, which repeats the last command. This is extremely useful when needing to indent an entire block several shiftspaces (or indentations) without needing to keep pressing >}. Thanks a long
  • Wipqozn
    Wipqozn over 12 years
    5>> Indent 5 lines : This command indents the fifth line, not 5 lines. Could this be due to my VIM settings, or is your wording incorrect?
  • ire_and_curses
    ire_and_curses over 12 years
    @Wipqozn - That's strange. It definitely indents the next five lines for me, tested on Vim 7.2.330.
  • Steve
    Steve over 12 years
    >42gg Indent from where you are to line 42.
  • Pif
    Pif over 12 years
    You can also use marks in normal mode to delimit the block, as in 'a'b> or patterns in the command line, as in :/begin/,/end/>
  • Shane Reustle
    Shane Reustle over 11 years
    The only tab/space related vim setting I've changed is :set tabstop=3. It's actually inserting this every time I use >>: "<tab><space><space>". Same with indenting a block. Any ideas?
  • Kent Fredric
    Kent Fredric over 11 years
    The three settings you want to look at for "spaces vs tabs" are 1. tabstop 2. shiftwidth 3. expandtab. You probably have "shiftwidth=5 noexpandtab", so a "tab" is 3 spaces, and an indentation level is "5" spaces, so it makes up the 5 with 1 tab, and 2 spaces.
  • Kent Fredric
    Kent Fredric over 11 years
    in essence, it makes up the distance of "Shiftwidth" using tabs and spaces combined, where "tabstop" is "how many spaces is 1 tab". Here is a more visual guide that may explain: gist.github.com/4189922
  • Kent Fredric
    Kent Fredric over 11 years
    generally, I see people set "shiftwidth" and "tabstop" to the same value, as its less confusing. sw=8 ts=8 noet > tab inserts an 8-space-wide tab. sw=8 ts=8 et > tab inserts 8 characters.
  • Greg Hewgill
    Greg Hewgill about 11 years
    @MattStevens: You can find extended discussion about this phenomenon here: meta.stackexchange.com/questions/9731/…
  • aqn
    aqn about 11 years
    I would say that vi/vim is mostly consistent. For instance, D does not behave the same as S and Y! :)
  • aqn
    aqn about 11 years
    Great summary! Also note that the "indent inside block" and "indent all block" (<i{ >a{ etc.) also works with parentheses and brackets: >a( <i] etc. (And while I'm at it, in addition to <>'s, they also work with d,c,y etc.)
  • aqn
    aqn about 11 years
    Yup, and this is why one of my big peeves is white spaces on an otherwise empty line: they messes up vim's notion of a "paragraph".
  • masukomi
    masukomi over 10 years
    The problem with . in this situation is that you have to move your fingers. With @mike's solution (same one i use) you've already got your fingers on the indent key and can just keep whacking it to keep indenting rather than switching and doing something else. Using period takes longer because you have to move your hands and it requires more thought because it's a second, different, operation.
  • asgs
    asgs over 10 years
    I've an XML file and turned on syntax highlighting. Typing gg=G just puts every line starting from position 1. All the white spaces have been removed. Is there anything else specific to XML?
  • David Mann
    David Mann about 10 years
    I often indent visual blocks multiple times in a row, such as fixing some tags pasted in to an XML file. Rather than re-select the block in visual mode each time, one can use 'gv' to reuse the last visual block. Reference superuser.com/questions/220666/…
  • rojomoke
    rojomoke almost 10 years
    This is just in vim, not vi.
  • rojomoke
    rojomoke almost 10 years
    Not on my Solaris or AIX boxes it doesn't. The equals key has always been one of my standard ad hoc macro assignments. Are you sure you're not looking at a vim that's been linked to as vi?
  • Sagar Jain
    Sagar Jain almost 10 years
    I am damn sure!! After seeing your comment, I just opened 'vi' and tried all the commands in my answer and got the result as expected.
  • rojomoke
    rojomoke almost 10 years
    Yeah, on Linux, vi is almost always a link to vim. Try running the :ve command inside vi.
  • ziggy
    ziggy over 9 years
    This is very useful as it avoids the need to count how many lines you want to indent.
  • Amanuel Nega
    Amanuel Nega almost 9 years
    I think set cindent should be in vimrc or should run :set cindent before running that command
  • Amanuel Nega
    Amanuel Nega almost 9 years
    I think cindent must be set first. and @asgs i think this only works for cstyle programming languages.
  • underscore_d
    underscore_d over 8 years
    ...what? 'indent by 4 spaces'? No, this jumps to line 4 and then indents everything from there to the end of the file, using the currently selected indent mode (if any).
  • underscore_d
    underscore_d over 8 years
    doesn't work for me, just dumps my cursor to the line above the opening brace of 'the current code block i'm in'.
  • Will Hardwick-Smith
    Will Hardwick-Smith over 8 years
    If you lose your selection, use gv to re-select
  • digitai
    digitai over 8 years
    I love this kind of answers: clear, precise and succinct. Worked for me in Debian Jessie. Thanks, @SJain
  • Eliethesaiyan
    Eliethesaiyan almost 8 years
    this starts from the left side of the file...not the the current position of the block
  • wilson
    wilson over 7 years
    I've started using the vim-pasta plugin for indent-aware pasting. Works like a charm!
  • Subfuzion
    Subfuzion almost 7 years
    Awesome, just what I was looking for (a way to insert a specific number of spaces -- 4 spaces for markdown code -- to override my normal indent). In my case I wanted to indent a specific number of lines in visual mode, so shift-v to highlight the lines, then :'<,'>le4 to insert the spaces. Thanks!
  • Dan Nissenbaum
    Dan Nissenbaum over 6 years
    Since I use vim, not vi, pretty psyched this answer is here. Thanks.
  • HoldOffHunger
    HoldOffHunger over 6 years
    There are clearly a lot of ways to solve this, but this is the easiest to implement, as line numbers show by default in vim and it doesn't require math.
  • oligofren
    oligofren about 6 years
    This is cumbersome, but is the way to go if you do formatting outside of core VIM (for instance, using vim-prettier instead of the default indenting engine). Using > will otherwise royally scew up the formatting done by Prettier.
  • falsePockets
    falsePockets about 6 years
    "To indent 5 lines, 5>>" I just tried that. It indents the fifth line, not 5 different lines starting at the cursor.
  • Greg Hewgill
    Greg Hewgill about 6 years
    @falsePockets: Which version of vim are you using? The 5>> command indents 5 lines for me. Be sure you aren't pressing Enter after the 5.
  • falsePockets
    falsePockets about 6 years
    I'm using version 8.0. The issue was that I was trying to type it in command mode (esc :5>>) instead of no mode. (esc 5>>)
  • sqqqrly
    sqqqrly almost 6 years
    Funny, I find it anything but cumbersome. This is not a uni-tasker! Learning this method has many uses beyond indenting.
  • user4052054
    user4052054 almost 6 years
    I find it better than the accepted answer, as I can see what is happening, the lines I'm selecting and the action I'm doing, and not just type some sort of vim incantation.
  • Dmitry
    Dmitry about 5 years
    On Mac In visual mode make sure to use arrows that are between M and ? keys.
  • Pryftan
    Pryftan about 4 years
    You might consider pointing out that the repeat command is a dot/full stop because depending on the font, the person's visions (which might be made worse if they're tired) it could look like something else. When I first saw it in your answer I was initially thrown off since I could have sworn it was a single quote. Just a thought that might or might not be worth considering.
  • DryLabRebel
    DryLabRebel about 4 years
    @HoldOffHunger Line numbers do not show by default. You need to use :set number to toggle line numbers (they are off by default), or put set number in your vimrc.
  • jimmont
    jimmont almost 3 years
    was able to use this to fix a regex range: :g/^@.\{-}{\n/,/^}\n}/norm >> reindenting specific pattern blocks (css file), had a hard time figuring this out and was a huge help, thanks
  • Frederic Leitenberger
    Frederic Leitenberger over 2 years
    Very nice! Worked perfectly even on a German keyboard. Note: On a German keyboard Shift+. = : which has other functions. So the other solutions don't work.
  • Frederic Leitenberger
    Frederic Leitenberger over 2 years
    How can this setting be made persistent? It seems to reset once vi(m) is closed.
  • Mamrezo
    Mamrezo over 2 years
    @FredericLeitenberger You can simply add these lines to your vimrc file. for more information execute this command: :h vimrc .
  • Mamrezo
    Mamrezo over 2 years
    @FredericLeitenberger, also the point of Shift+. is the > character which you can find in your keyboard...
  • windmaomao
    windmaomao over 2 years
    I didn't expect i'll learn a lot more than the indent here. So >* would do a interesting thing, <header>ddd</header>, it'll indent the entire block because * goes to the next header.