1191

My current setting assumes 8 spaces; how could I redefine it?

Paul Bellora
  • 51,514
  • 17
  • 127
  • 176
Ricky
  • 30,941
  • 36
  • 85
  • 129
  • 8
    @heinrich5991 I don't get it. I don't need 8 spaces to realize that a line is indented, and more than necessary means limiting the characters you can view on a long line of text (at least before wrapping). But to each his own. :) – weberc2 Apr 20 '14 at 11:25
  • 45
    @heinrich5991 My argument is "use as little as possible to readily identify an indented line". By my estimation, one's ability to easily identify an indentation drops off rapidly at < 3 spaces, and it stops increasing at 4 spaces. Therefore, indentation that exceeds 4 spaces is a waste, in my experience. – weberc2 Apr 21 '14 at 13:40
  • 4
    Better yet, set it to four spaces and enable auto-indent at the same time: [Auto-indent with tabwidth set to 4 spaces](http://stackoverflow.com/questions/234564/tab-key-4-spaces-and-auto-indent-after-curly-braces-in-vim) – solid_liq Sep 11 '13 at 01:55
  • 10
    @weberc2 Couldn't possibly agree more, mate. Which is why I feel so damn claustrophobic reading Ruby or "modern-day JavaScript", each of which use 2-spaces for indentation. It legitimately gives me eye strain when trying to follow heavily-nested structures. Hard tabs for the goddamn win. –  Nov 13 '15 at 06:57
  • Possible duplicate of [Replace Tab with Spaces in VIM](http://stackoverflow.com/questions/426963/replace-tab-with-spaces-in-vim) – rofrol Mar 28 '16 at 20:13

12 Answers12

1745

It depends on what you mean. Do you want actual tab characters in your file to appear 4 spaces wide, or by "tab" do you actually mean an indent, generated by pressing the tab key, which would result in the file literally containing (up to) 4 space characters for each "tab" you type?

Depending on your answer, one of the following sets of settings should work for you:

  • For tab characters that appear 4-spaces-wide:

    set tabstop=4
    

    If you're using actual tab character in your source code you probably also want these settings (these are actually the defaults, but you may want to set them defensively):

    set softtabstop=0 noexpandtab
    

    Finally, if you want an indent to correspond to a single tab, you should also use:

    set shiftwidth=4
    
  • For indents that consist of 4 space characters but are entered with the tab key:

    set tabstop=8 softtabstop=0 expandtab shiftwidth=4 smarttab
    

To make the above settings permanent add these lines to your vimrc.

In case you need to make adjustments, or would simply like to understand what these options all mean, here's a breakdown of what each option means:

tabstop

The width of a hard tabstop measured in "spaces" -- effectively the (maximum) width of an actual tab character.

shiftwidth

The size of an "indent". It's also measured in spaces, so if your code base indents with tab characters then you want shiftwidth to equal the number of tab characters times tabstop. This is also used by things like the =, > and < commands.

softtabstop

Setting this to a non-zero value other than tabstop will make the tab key (in insert mode) insert a combination of spaces (and possibly tabs) to simulate tab stops at this width.

expandtab

Enabling this will make the tab key (in insert mode) insert spaces instead of tab characters. This also affects the behavior of the retab command.

smarttab

Enabling this will make the tab key (in insert mode) insert spaces or tabs to go to the next indent of the next tabstop when the cursor is at the beginning of a line (i.e. the only preceding characters are whitespace).

For more details on any of these see :help 'optionname' in vim (e.g. :help 'tabstop')

Laurence Gonsalves
  • 125,464
  • 31
  • 220
  • 273
  • 20
    It is also important to ensure that Makefiles always use hard tab characters, otherwise builds will fail! I have shown how to, at http://stackoverflow.com/questions/234564/tab-key-4-spaces-and-auto-indent-after-curly-braces-in-vim/21323445#21323445 – Shervin Emami Jan 24 '14 at 02:48
  • 2
    @SethMcClaine mine is in /etc/vim/vimrc. – Undefined May 23 '14 at 09:21
  • 32
    @Undefined That's the system vim settings. `~/.vimrc` is the user's vim settings. Most people leave the system settings alone and just edit the user settings. Note that `~/.vimrc` will not exist until you create it on most systems. – Laurence Gonsalves May 23 '14 at 16:38
  • @LaurenceGonsalves Well, that explains why it didn't exist. Thanks. – Undefined May 24 '14 at 20:02
  • 4
    Vim users take note of the `set softtabstop=4` feature! I am tired of trying to read your code with `less`, or any other editor except `vim`, only to see wacky indenting because you redefined tab to be some arbitrary number of spaces (even though the rest of the system thinks otherwise)! :-) – Ogre Psalm33 Sep 17 '14 at 12:51
  • 3
    @OgrePsalm33 Personally, I always have `tabstop=8` and `expandtab` enabled when editing code. Not everyone feels that way, however. There are some who feel an indent should be a single tab character, so the width is adjustable by the reader. I don't think these people are exclusively (or even mostly) vim users... – Laurence Gonsalves Oct 07 '14 at 00:42
  • 1
    @KrishnadasPC set ts=4's great except if you ever work with (a) anybody who hasn't reconfigured everything they use that displays text, and (b) anybody else who works with (a) people. – jthill Oct 10 '15 at 19:57
  • Setting tabstop with noexpandtab and softtabstop=0 doesn't actually set the size of a tabstop on my OS X Macvim, if that means the number of screen spaces generated by a tab character. Instead, it sets the tabstop column. The difference can be seen by starting a line with a few characters (less than value of tabstop) and then a tab character. The cursor will jump to the tab stop. So the number of screen spaces inserted is a few characters less than the value of tabstop. – user2781942 Mar 09 '16 at 22:43
  • @user2781942 Yes, "the size of a tabstop" refers to the tabstop columns. In reality it is the *maximum* number of space characters a tab character will be as wide as. Vim's own documentation uses similar wording, BTW. For example, `:help 'tabstop'` descibes the option as the "Number of spaces that a in the file counts for". – Laurence Gonsalves Mar 23 '16 at 06:34
  • Thanks, Laurence. Actually, the help text you refer to ("Number of spaces that a in the file counts for") was what threw me. It is apparently incorrect, then. – user2781942 Mar 24 '16 at 17:22
  • 1
    What's the difference between a "tab" and an "indent"? – Niko Bellic Apr 12 '16 at 22:14
  • 1
    @NikoBellic A tab is ASCII/Unicode character number 9, aka "Control-I". This is the character that is normally inserted when you hit the tab key. An indent is the spacing used at the beginning of lines, in code usually used to indicate block structure. Some coding conventions use tabs for indents (usually 1 tab = 1 indent), but many use space characters rather than tabs (4 spaces seems to be most common, but 2 spaces is also fairly popular). – Laurence Gonsalves Apr 12 '16 at 22:51
  • 1
    @NikoBellic I should also add that in vim, at least, tab characters are unusual because they may have variable width (depending on settings). In the default settings, a single tab character appears like one or more spaces up to the next "tab stop" (which is normally every 8 spaces). The `tabstop` option mentioned in the answer adjusts this. The (terribly named) `list` and `listchars` options can also affect how tabs are rendered. – Laurence Gonsalves Apr 12 '16 at 22:55
  • 1
    @LaurenceGonsalves Thanks. So if I wanted to indent with two tabs, I could set tabstop to 4 (which causes each tab character to be displayed visually as a maximum of 4 "spaces") and set shiftwidth to twice that, a.k.a. 8. Right? And if I'd rather my indent be one tab, as is most common, I would set shiftwidth to be idential to tabstop, a.k.a. 4. – Niko Bellic Apr 12 '16 at 23:31
  • 9
    Can someone help me understand why this answer says to use `tabstop=8` for indents that consist of **4** spaces? I couldn't get the reason after reading the descriptions of the various settings. Another answer says to use `tabstop=4` which makes a little bit more sense to me. – Cave Johnson Jan 16 '19 at 01:09
  • 11
    @KodosJohnson The `tabstop` option controls the width of a hard tab character. If you want your indents to consist of 4 space characters, rather than single tab characters that are 4-wide, then the width of your tab character doesn't matter -- *sort of*. In practice, you probably want your tab character width to be *different* from the width of your indents, in order to reduce the chance of tab characters masquerading as proper indents. (`list` + `expandtab` can help here too) Also, 8-char-wide tabs is "the standard" -- your terminal, Python, and many other tools default to 8-char-wide-tabs. – Laurence Gonsalves Jan 16 '19 at 21:04
  • 1
    Thanks for the tabstop explanation, it also didn't make any sense to me. But to catch tab characters in place of spaces, e.g. inserted with another editor, I would think a number not divisible by 4 would be easiert to spot. So I'll try `tabstop=6` for now. – dlaehnemann Apr 12 '19 at 09:52
  • 2
    @dlaehnemann If you want to be able to spot accidental tab characters, you may find the 'list' and 'listchars' option useful. Something like `set list listchars+=ltab:▶┈` will make tabs look different from spaces. You can use the `SpecialKey` highlight group to adjust the appearance further. Another trick which *really* makes them stand out is to do something like `:2match Error /\t/`. – Laurence Gonsalves May 17 '19 at 23:59
  • I just noticed a typo in my previous comment, but SO won't let me edit it. The correct `listchars` line is: `:set list listchars+=tab:▶┈` ("tab", not "ltab") – Laurence Gonsalves Jun 21 '19 at 17:38
773

To define this on a permanent basis for the current user, create (or edit) the .vimrc file:

$ vim ~/.vimrc

Then, paste the configuration below into the file. Once vim is restarted, the tab settings will apply.

set tabstop=4       " The width of a TAB is set to 4.
                    " Still it is a \t. It is just that
                    " Vim will interpret it to be having
                    " a width of 4.

set shiftwidth=4    " Indents will have a width of 4

set softtabstop=4   " Sets the number of columns for a TAB

set expandtab       " Expand TABs to spaces
CJBS
  • 13,354
  • 5
  • 76
  • 124
Alan Haggai Alavi
  • 67,398
  • 19
  • 96
  • 124
  • If you do not have ~/.vimrc, try with /etc/vim/vimrc. In my case on Ubuntu 16.04 the config file is there. But keep in mind that changing this file will cause the configuration to be used globaly. – Todor Todorov Oct 11 '16 at 07:43
  • 5
    One more thing, use `:retab` to convert existing `tab` to `spaces`. http://vim.wikia.com/wiki/Converting_tabs_to_spaces – DawnSong Nov 10 '16 at 14:39
67

or shorthand for vim modeline:

vim :set ts=4 sw=4 sts=4 et :
zen
  • 11,183
  • 4
  • 22
  • 16
42

There are few settings which define whether to use spaces or tabs.

So here are handy functions which can be defined in your ~/.vimrc file:

function! UseTabs()
  set tabstop=4     " Size of a hard tabstop (ts).
  set shiftwidth=4  " Size of an indentation (sw).
  set noexpandtab   " Always uses tabs instead of space characters (noet).
  set autoindent    " Copy indent from current line when starting a new line (ai).
endfunction

function! UseSpaces()
  set tabstop=2     " Size of a hard tabstop (ts).
  set shiftwidth=2  " Size of an indentation (sw).
  set expandtab     " Always uses spaces instead of tab characters (et).
  set softtabstop=0 " Number of spaces a <Tab> counts for. When 0, featuer is off (sts).
  set autoindent    " Copy indent from current line when starting a new line.
  set smarttab      " Inserts blanks on a <Tab> key (as per sw, ts and sts).
endfunction

Usage:

:call UseTabs()
:call UseSpaces()

To use it per file extensions, the following syntax can be used (added to .vimrc):

au! BufWrite,FileWritePre *.module,*.install call UseSpaces()

See also: Converting tabs to spaces.


Here is another snippet from Wikia which can be used to toggle between tabs and spaces:

" virtual tabstops using spaces
set shiftwidth=4
set softtabstop=4
set expandtab
" allow toggling between local and default mode
function TabToggle()
  if &expandtab
    set shiftwidth=8
    set softtabstop=0
    set noexpandtab
  else
    set shiftwidth=4
    set softtabstop=4
    set expandtab
  endif
endfunction
nmap <F9> mz:execute TabToggle()<CR>'z

It enables using 4 spaces for every tab and a mapping to F9 to toggle the settings.

kenorb
  • 118,428
  • 63
  • 588
  • 624
29

I copied and pasted this into my .vimrc file:

" size of a hard tabstop
set tabstop=4

" always uses spaces instead of tab characters
set expandtab

" size of an "indent"
set shiftwidth=4

The first 2 settings mean that when I press Tab I get 4 spaces. The third setting means that when I do V> (i.e. visual and indent) I also get 4 spaces.

Not as comprehensive as the accepted answer but it might help people who just want something to copy and paste.

Snowcrash
  • 66,400
  • 60
  • 203
  • 323
15

Put your desired settings in the ~/.vimrc file -- See below for some guidelines and best practices.

There are four main ways to use tabs in Vim:

  1. Always keep 'tabstop' at 8, set 'softtabstop' and 'shiftwidth' to 4 (or 3 or whatever you prefer) and use 'noexpandtab'. Then Vim will use a mix of tabs and spaces, but typing and will behave like a tab appears every 4 (or 3) characters.

    Note: Setting 'tabstop' to any other value than 8 can make your file appear wrong in many places (e.g., when printing it).

  2. Set 'tabstop' and 'shiftwidth' to whatever you prefer and use 'expandtab'. This way you will always insert spaces. The formatting will never be messed up when 'tabstop' is changed.

  3. Set 'tabstop' and 'shiftwidth' to whatever you prefer and use a |modeline| to set these values when editing the file again. Only works when using Vim to edit the file.

  4. Always set 'tabstop' and 'shiftwidth' to the same value, and 'noexpandtab'. This should then work (for initial indents only) for any tabstop setting that people use. It might be nice to have tabs after the first non-blank inserted as spaces if you do this though. Otherwise aligned comments will be wrong when 'tabstop' ischanged.

Source:

Mateusz Piotrowski
  • 6,087
  • 9
  • 44
  • 71
ElasticThoughts
  • 3,208
  • 6
  • 41
  • 55
11

One more thing, use
:retab
to convert existing tab to spaces http://vim.wikia.com/wiki/Converting_tabs_to_spaces

DawnSong
  • 3,232
  • 1
  • 26
  • 35
9

Add line
set ts=4
in
~/.vimrc file for per user
or
/etc/vimrc file for system wide

Alok Singh Mahor
  • 5,210
  • 5
  • 36
  • 53
7
:set sw=4

See Mastering the VI editor

izstas
  • 4,664
  • 3
  • 43
  • 54
Amarghosh
  • 55,378
  • 11
  • 87
  • 119
6

My basic ~/.vimrc with comment:

set number " show line number                                                                                           
set tabstop=2 " set display width of tab; 1 tab = x space with                                                           
set expandtab " transform tab to x space (x is tabstop)                                                               
set autoindent " auto indent; new line with number of space at the beginning same as previous                                                                      
set shiftwidth=2 " number of space append to lines when type >> 
o0omycomputero0o
  • 2,604
  • 2
  • 27
  • 40
  • great! the autoindent introduces double indentation when copy pasting text that already has indents. bit of caution. paste/nopaste mode might help in such cases – Amit M Sep 21 '20 at 14:06
1

Permanent for all users (when you alone on server):

# echo "set tabstop=4" >> /etc/vim/vimrc

Appends the setting in the config file. Normally on new server apt-get purge nano mc and all other to save your time. Otherwise, you will redefine editor in git, crontab etc.

ego2509
  • 65
  • 1
  • 1
  • 11
Vasilii Suricov
  • 602
  • 10
  • 18
  • 1
    If you set EDITOR, most programs will respect it. – D. Ben Knoble Feb 29 '20 at 16:18
  • @D.BenKnoble you are right. i've tried. for now i prefer to save my time and nerves. can't check what exactly runs with `F10` in `nano` but i always do some tricks with save (maybe `F10` is a solution). or it doesn't work in `screen`? I can't remember, just hate it) – Vasilii Suricov Mar 01 '20 at 14:54
0

Make sure vartabstop is unset

set vartabstop=

Set tabstop to 4

set tabstop=4
Vivian De Smedt
  • 922
  • 2
  • 12
  • 23