Indent multiple lines quickly in vi
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:
Enter Command Mode:
EscapeMove around to the start of the area to indent:
hjkl↑↓←→Start a block:
vMove around to the end of the area to indent:
hjkl↑↓←→(Optional) Type the number of indentation levels you want
0..9Execute the indentation on the block:
>
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, 2022Comments
-
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 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 over 15 yearsI use >i} (indent inner {} block). Works in vim. Not sure it works in vi.
-
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 over 14 yearsTo indent the selection multiple times, you can simply press . to repeat the previous command.
-
gravitation over 14 yearsI had been using control-v to indent by navigating to the front of the line but this is clearly much better.
-
jamessan over 14 years@Martinho: text objects, like i} are Vim-specific. Then again, so is visual mode.
-
Kamran Bigdely about 13 yearsMy 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 about 13 years@Kamran: See the
shiftwidth
setting for the way to change that. -
Shane Reustle about 13 yearsThis is great, but it uses spaces and not tabs. Any possible way to fix this?
-
Kent Fredric about 13 yearsIf its using spaces instead of tabs, then its probably because you have indentation set to use spaces. =).
-
Kent Fredric about 13 yearsWhen the 'expandtab' option is off (this is the default) Vim uses <Tab>s as much as possible to make the indent. ( :help :> )
-
user606723 about 13 yearsThis 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 almost 13 yearsBoth 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 over 12 years5>> 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 over 12 years@Wipqozn - That's strange. It definitely indents the next five lines for me, tested on Vim 7.2.330.
-
Steve over 12 years>42gg Indent from where you are to line 42.
-
Pif over 12 yearsYou 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 over 11 yearsThe 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 over 11 yearsThe 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 over 11 yearsin 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 over 11 yearsgenerally, 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 about 11 years@MattStevens: You can find extended discussion about this phenomenon here: meta.stackexchange.com/questions/9731/…
-
aqn about 11 yearsI would say that vi/vim is mostly consistent. For instance, D does not behave the same as S and Y! :)
-
aqn about 11 yearsGreat 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 about 11 yearsYup, 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 over 10 yearsThe 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 over 10 yearsI'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 about 10 yearsI 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 almost 10 yearsThis is just in
vim
, notvi
. -
rojomoke almost 10 yearsNot 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 asvi
? -
Sagar Jain almost 10 yearsI 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 almost 10 yearsYeah, on Linux, vi is almost always a link to vim. Try running the :ve command inside vi.
-
ziggy over 9 yearsThis is very useful as it avoids the need to count how many lines you want to indent.
-
Amanuel Nega almost 9 yearsI think
set cindent
should be in vimrc or should run:set cindent
before running that command -
Amanuel Nega almost 9 yearsI think cindent must be set first. and @asgs i think this only works for cstyle programming languages.
-
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 over 8 yearsdoesn'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 over 8 yearsIf you lose your selection, use gv to re-select
-
digitai over 8 yearsI love this kind of answers: clear, precise and succinct. Worked for me in Debian Jessie. Thanks, @SJain
-
Eliethesaiyan almost 8 yearsthis starts from the left side of the file...not the the current position of the block
-
wilson over 7 yearsI've started using the vim-pasta plugin for indent-aware pasting. Works like a charm!
-
Subfuzion almost 7 yearsAwesome, 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 over 6 yearsSince I use vim, not vi, pretty psyched this answer is here. Thanks.
-
HoldOffHunger over 6 yearsThere 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 about 6 yearsThis 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 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 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 about 6 yearsI'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 almost 6 yearsFunny, I find it anything but cumbersome. This is not a uni-tasker! Learning this method has many uses beyond indenting.
-
user4052054 almost 6 yearsI 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 about 5 yearsOn Mac In visual mode make sure to use arrows that are between
M
and?
keys. -
Pryftan about 4 yearsYou 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 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 putset number
in your vimrc. -
jimmont almost 3 yearswas 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 over 2 yearsVery 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 over 2 yearsHow can this setting be made persistent? It seems to reset once vi(m) is closed.
-
Mamrezo over 2 years@FredericLeitenberger You can simply add these lines to your
vimrc
file. for more information execute this command::h vimrc
. -
Mamrezo over 2 years@FredericLeitenberger, also the point of
Shift
+.
is the>
character which you can find in your keyboard... -
windmaomao over 2 yearsI 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 nextheader
.