Vim is very accommodating when it comes to tab Vs. space preferences. As I understand it, the tabstop
setting indicates the width of a tab character. The
This is my first attempt at writing VimScript, but here goes:
function! Stab(value)
let &shiftwidth = a:value
let &softtabstop = a:value
let &tabstop = a:value
endfunc
If I put this in my .vimrc file, I can call it by running :call Stab(X)
, where X is the desired tab width. This is an adequate solution for now, but if anyone can suggest a way of making it easier to call I would be grateful.
I've also created a function that quickly summarizes the current settings, which I have mapped to ctrl-Tab:
nmap <C-Tab> :call TabParams()<CR>
function! TabParams()
echo "tabstop: ".&tabstop
echo "shiftwidth: ".&shiftwidth
echo "softtabstop: ".&softtabstop
endfunc
Well, I put up a 100 point bounty for this answer, and now I've half solved it myself. Not sure if I can accept my own answer...
Creating a stab
option in Vim itself would not be easy, but I've whipped up this command/function that you can drop in your .vimrc
(or a plugin file if you're super-organized). Use :Stab
and you will be prompted for an indent level and whether or not to use expandtab
. If you hit enter without giving it a new indent level, it will just print the current settings.
" put all this in your .vimrc or a plugin file command! -nargs=* Stab call Stab() function! Stab() let l:tabstop = 1 * input('set shiftwidth=') if l:tabstop > 0 " do we want expandtab as well? let l:expandtab = confirm('set expandtab?', "&Yes\n&No\n&Cancel") if l:expandtab == 3 " abort? return endif let &l:sts = l:tabstop let &l:ts = l:tabstop let &l:sw = l:tabstop if l:expandtab == 1 setlocal expandtab else setlocal noexpandtab endif endif " show the selected options try echohl ModeMsg echon 'set tabstop=' echohl Question echon &l:ts echohl ModeMsg echon ' shiftwidth=' echohl Question echon &l:sw echohl ModeMsg echon ' sts=' echohl Question echon &l:sts . ' ' . (&l:et ? ' ' : 'no') echohl ModeMsg echon 'expandtab' finally echohl None endtry endfunction
One useful option is softtabstop=-1
which will set it to the value of shiftwidth
.
You can also set shiftwidth
to 0, in which case the tabstop
value will be used.
If expandtab
is set then (as too much php points out), softtabstop
becomes redundant. The only reason you might set shiftwidth
differently from tabstop
would be to cater to an odd habit; for instance, you use four-space indents but you prefer tab to insert eight spaces.
If expandtab
is unset then things get fuzzier. If you want your code to look the same in with cat
and non-vim editors as it does in vim, then tabstop
should always be set at 8; in this case you would set softtabstop
and shiftwidth
both to your preferred indent level. If you instead prefer that every "physical tab" in the file represents one indent level, you would set tabstop
and shiftwidth
to your preferred indent level and leave softtabstop
at zero (setting it equal to tabstop
is equivalent except that if you change tabstop
it will get out of sync, while zero just means "ignore this please").
You can in edit mode also use Ctrl-T to indent and Ctrl-D to deindent to the next indentation level as set by shiftwidth
, regardless of the tabstop
, softtabstop
or expandtab
settings. Vim will automatically add/remove spaces or tabs to bring you to the right column.
If you use these commands to control indentation instead of Tab/Backspace you don't have to worry about all these tab settings fitting together and always get to the correct indentation level.
Your understanding of softtabstop
and expandtab
is wrong - so the stab
option you suggest wouldn't be very useful.
expandtab
is for when you want to use spaces instead of tabs for everything. If you set expandtab
, then Vim ignores the softtabstop
option and uses tabstop
and shiftwidth
to work out how many spaces to insert.
softtabstop
is only for when you would like to use a mix of tabs and spaces, allowing you to indent with fine control (2 or 4 spaces), while keeping tab width at a higher value (usually 8) so that text appears in the other applications. Setting softtabstop=tabstop
doesn't accomplish anything because Vim will always use tabs for indenting.
Update: As kaizer.se has pointed out, if you are using expandtab
, then you still need to set softtabstop
if you want Vim to backspace multiple spaces as though they are a tab.