Vim: Indent with one space (not shiftwidth spaces)

Vim

Vim Problem Overview


The default VIM indentation commands indent by shiftwidth spaces

e.g.

>>   Indent line by shiftwidth spaces
<<   De-indent line by shiftwidth spaces

Is there any way to indent with one or n (where n != shiftwidth) space(s)?

One way to do that is to vertically select a column in the block with Ctrl+V then, I to insert vertically and then type a space and <Esc>. But is there a better way?

Vim Solutions


Solution 1 - Vim

I'm not sure that there is a better way. But, there are a few ways that you could do it (that I can think of anyway)...

Your Visual Block Solution

Like you said: press Ctl-V select the lines you want, press I to insert, and enter the number of spaces.

Search

Similar to the above but a little more flexible - you can use with with the 'select paragraph' vip command, or any range really: press v or vip or what have you to select the range, and the type :s/^/{n spaces} where {n spaces} is the number of spaces you want to insert.

Its a little more verbose, but works pretty well for pretty much any range. Heck, if you wanted to do the whole file you could do Ctl-A (OS dependent) and indent the whole file (or just skip the whole visual mode thing and just do it command mode...as in :1,$s/^/{n spaces}

Note that you don't have to include the third slash in s/// since you aren't putting any switches at the end of the search.

Global

Maybe you want to only indent lines that match some pattern. Say...all lines that contain foo. No problem: type :g/foo/s/^/{n spaces}

Global is especially handy if its multi-line sections with a similar pattern. You can just escape into normal mode land and select the lines you want and indent accordingly: :g/foo/norm Vjj:s/^/{n spaces}Ctl-V{Enter}. Little more complicated with that extra Ctl-V{Enter} at the end but useful under certain circumstances.

Use tabstop and shiftwidth

Yes, if your doing it a lot - I'd do :set ts=2 and :set et and :set sw=2 and use >> and << every which way...

Make a Function

Okay, so still not brief enough and for whatever reason you need to do this a lot and you can't abide messing with sw, et and ts settings. No problem, just write up a quick function and give it a localleader mapping:

function! AddSpace(num) range
  let s:counter = 0
  let s:spaces = ''
  while s:counter < a:num
    let s:spaces .= ' '
    let s:counter = s:counter + 1
  endwhile
	execute a:firstline .','. a:lastline .'s/^/'. s:spaces
endfunction

:map <LocalLeader>i :call AddSpace(3)Ctl-V{enter}

Maybe just knowing more than one way to do this is better than only knowing one? After all, sometimes the best solution depends on the problem :)

Solution 2 - Vim

Indent a block of code in vi by three spaces with Visual Block mode:

  1. Select the block of code you want to indent. Do this using Ctrl+V in normal mode and arrowing down to select text. While it is selected, enter ":" to give a command to the block of selected text.

  2. The following will appear in the command line: :'<,'>

  3. To set indent to 3 spaces, type le 3 and press enter. This is what appears: :'<,'>le 3

  4. The selected text is immediately indented to 3 spaces.

Indent a block of code in vi by three spaces with Visual Line mode:

  1. Open your file in VI.

  2. Put your cursor over some code

  3. Be in normal mode press the following keys:

    Vjjjj:le 3
    

Interpretation of what you did:

V means start selecting text.

jjjj arrows down 4 lines, highlighting 4 lines.

: tells vi you will enter an instruction for the highlighted text.

le 3 means indent highlighted text 3 lines.

Solution 3 - Vim

To change the number of space characters inserted for indentation, use the shiftwidth option:

:set shiftwidth = <number>

Have a look here for more details.

You can also add that to your .vimrc file.

Solution 4 - Vim

If I'm understanding correctly, you could use:

ctrl+V, jj then ':le n', where n is the number of spaces to indent.

http://vim.wikia.com/wiki/Shifting_blocks_visually

Solution 5 - Vim

Place marks ('a' and 'b') between the code you want to indent:

<position cursor at top of block>
m a
<position cursor at bottom of block>
m b

Do a replace command such that each newline character between your marks is replaced with the number of spaces desired (in this example, 2 spaces):

:'a,'bs/^/  /g

Solution 6 - Vim

I had to dedent by a given number of spaces, amount, inside a vim script. This worked:

    let sw_setting = &shiftwidth
    set shiftwidth=1
    exe "normal v" . amount . "<"
    let &shiftwidth = sw_setting

A side-effect is that it resets the last visual mode selection. Instead, you may wish to edit the exe... line such that it executes "<<" repeated amount times in normal mode. That is: instead of normal v3<, make it normal <<<<<<, if amount is 3.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrdasxyView Question on Stackoverflow
Solution 1 - VimdsummerslView Answer on Stackoverflow
Solution 2 - VimidnavidView Answer on Stackoverflow
Solution 3 - VimAayush KumarView Answer on Stackoverflow
Solution 4 - VimWarren DavisView Answer on Stackoverflow
Solution 5 - VimmlehmeherView Answer on Stackoverflow
Solution 6 - VimEvgeni SergeevView Answer on Stackoverflow