Learn Vim at your own pace with my self-study Core Vim Course.

Learn more

Learn Vim at your own pace with my self-study Core Vim Course.

Tabs and Spaces


Run time:

Vim offers very granular control over whitespace. This episode explains the purpose of tabstop, softtabstop, shiftwidth and expandtab settings, and illustrates how Vim behaves using various combinations of these.


The following combinations are demonstrated in the video:

set ts=8 sts=0 sw=8 noexpandtab " default settings
set ts=8 sts=0 sw=8 expandtab
set ts=8 sts=8 sw=8 expandtab
set ts=8 sts=4 sw=4 expandtab
set ts=8 sts=4 sw=4 noexpandtab
set ts=4 sts=4 sw=4 noexpandtab

If you prefer to work with tab characters then it is a good idea to ensure that tabstop == softtabstop. This makes it less likely that you’ll end up with a mixture of tabs and spaces for indentation.

If you prefer to work with spaces, then it is preferable to ensure that softtabstop == shiftwidth. This way, you can expect the same number of spaces to be inserted whether you press the tab key in insert mode, or use the indentation commands in normal/visual modes.

The following snippet of vimscript allows you to assign the same value to tabstop, softtabstop and shiftwidth simultaneously:

" Set tabstop, softtabstop and shiftwidth to the same value
command! -nargs=* Stab call Stab()
function! Stab()
  let l:tabstop = 1 * input('set tabstop = softtabstop = shiftwidth = ')
  if l:tabstop > 0
    let &l:sts = l:tabstop
    let &l:ts = l:tabstop
    let &l:sw = l:tabstop
  call SummarizeTabs()

function! SummarizeTabs()
    echohl ModeMsg
    echon 'tabstop='.&l:ts
    echon ' shiftwidth='.&l:sw
    echon ' softtabstop='.&l:sts
    if &l:et
      echon ' expandtab'
      echon ' noexpandtab'
    echohl None

To invoke this command, go into normal mode (by pressing escape) then run:


Then hit enter. You will see this:

set tabstop = softtabstop = shiftwidth = 

Enter the size that you want to assign to those settings, and hit enter. A summary line then shows the value of each setting, as well as showing whether or not expandtab is enabled. If you hit enter without providing a value, then the tab settings are not affected.

You can also call the summary line by itself. I’ve mapped this to ctrl-shift-tab for convenience. Feel free to modify the mappings, and the funcionality to suit your preferences.

Further Reading

When I started researching this episode, I asked a question on StackOverflow.com. The answers that came in seemed to be at odds with each other, which demonstrated to me that there is a lot of confusion over the subject. I’d like to thank toomuchphp for providing the vimscript sample which I have adapted for my preferences. If it proves useful to yourself, why not show your gratitude by upvoting his answer?


Browse similar content

Level-up your Vim


Boost your productivity with a Vim training class. Join a public class, or book a private session for your team.

Drew hosted a private Vim session for the shopify team that was one of the best workshops I have ever attended.

John Duff, Director of Engineering at Shopify


Make yourself a faster and more efficient developer with the help of these publications, including Practical Vim (Pragmatic Bookshelf 2012), which has over 50 five-star reviews on Amazon.

After reading it, I've switched to vim as my default editor on a daily basis with no regrets. ★★★★★

Javier Collado

Learn to use Vim efficiently in your Ruby projects

In association with thoughtbot, one of the most well respected Rails consultancies in the world, I've produced a series of screencasts on how to make navigating your Ruby projects with Vim ultra-efficient. Along the way, you’ll also learn how to make Ruby blocks a first-class text object in Vim. This lets you edit Ruby code at a higher level of abstraction. Available to buy from thoughtbot..