Tab key == 4 spaces and auto-indent after curly braces in Vim

974,339

Solution 1

As has been pointed out in a couple of other answers, the preferred method now is NOT to use smartindent, but instead use the following (in your .vimrc):

filetype plugin indent on
" show existing tab with 4 spaces width
set tabstop=4
" when indenting with '>', use 4 spaces width
set shiftwidth=4
" On pressing tab, insert 4 spaces
set expandtab

In your [.vimrc:][1] file:
set smartindent
set tabstop=4
set shiftwidth=4
set expandtab

The help files take a bit of time to get used to, but the more you read, the better Vim gets:

:help smartindent

Even better, you can embed these settings in your source for portability:

:help auto-setting

To see your current settings:

:set all

As graywh points out in the comments, smartindent has been replaced by cindent which "Works more cleverly", although still mainly for languages with C-like syntax:

:help C-indenting

Solution 2

Related, if you open a file that uses both tabs and spaces, assuming you've got

set expandtab ts=4 sw=4 ai

You can replace all the tabs with spaces in the entire file with

:%retab

Solution 3

The best way to get filetype-specific indentation is to use filetype plugin indent on in your vimrc. Then you can specify things like set sw=4 sts=4 et in .vim/ftplugin/c.vim, for example, without having to make those global for all files being edited and other non-C type syntaxes will get indented correctly, too (even lisps).

Solution 4

To have 4-space tabs in most files, real 8-wide tab char in Makefiles, and automatic indenting in various files including C/C++, put this in your ~/.vimrc file:

" Only do this part when compiled with support for autocommands.
if has("autocmd")
    " Use filetype detection and file-based automatic indenting.
    filetype plugin indent on

    " Use actual tab chars in Makefiles.
    autocmd FileType make set tabstop=8 shiftwidth=8 softtabstop=0 noexpandtab
endif

" For everything else, use a tab width of 4 space chars.
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.

Solution 5

On many Linux systems, like Ubuntu, the .vimrc file doesn't exist by default, so it is recommended that you create it first.

Don't use the .viminfo file that exist in the home directory. It is used for a different purpose.

Step 1: Go to your home directory

cd ~

Step 2: Create the file

vim .vimrc

Step 3: Add the configuration stated above

filetype plugin indent on
set tabstop=4
set shiftwidth=4
set expandtab

Step 3: Save file, by pressing Shift + ZZ.

Share:
974,339
Dennis Kioko
Author by

Dennis Kioko

Updated on July 19, 2022

Comments

  • Dennis Kioko
    Dennis Kioko almost 2 years

    How do I make vi-Vim never use tabs (converting spaces to tabs, bad!), makes the tab key == 4 spaces, and automatically indent code after curly brace blocks like Emacs does?

    Also, how do I save these settings so I never have to input them again?

    I've seen other questions related to this, but it always seems to be a little off from what I want.

  • Jonathan Leffler
    Jonathan Leffler over 15 years
    Thanks - smartindent (as a name) was new to me. I hadn't managed to work out which option did the trick on MacOS X.
  • Azat Razetdinov
    Azat Razetdinov over 15 years
    Even with those settings applied, if I press ‘o’ in a line indented with spaces, the new line is indented with tabs :-( How can I change this behaviour?
  • Ken
    Ken over 15 years
    If you have expandtab set then it should be using spaces. Do you also "set compatible"? That has various side effects including resetting expandtab to its default of "off"
  • graywh
    graywh over 14 years
    Sorry, but smartindent was replaced by cindent, which itself is only appropriate for C-style syntax. Turning on either in your vimrc can be a problem when working with other languages. Just use "filetype indent on" instead.
  • 0fnt
    0fnt almost 14 years
    IMHO, better than the answer that has been marked correct. filetype indent on supersedes cindent and smartindent.
  • graywh
    graywh almost 14 years
    Well, smartindent is also only for C-style syntax and is essentially deprecated.
  • Eno
    Eno about 12 years
    FYI, if you dont want your tab to be replaced by spaces, remove the expandtab line.
  • hunt
    hunt about 10 years
    Aren't tabs whitespace? ;-)
  • netjeff
    netjeff about 10 years
    @Rob-Wells: I changed "whitespace" to "spaces". Are you happy now? ;-)
  • user2987828
    user2987828 about 9 years
    Ken: You should update your answer, see stackoverflow.com/a/23426067/2987828 which is more up to date.
  • Fermat's Little Student
    Fermat's Little Student over 8 years
    I noticed when I do backspace, wim will only delete one space at a time, which is annoying. Any solutions?
  • User
    User over 8 years
    It seems this actually added a tab the size of 8 spaces now.
  • shas
    shas over 8 years
    Dont use Shift + ZZ it will create .swp file. use wq.
  • Daniele Segato
    Daniele Segato about 8 years
    if I enable expandtab, is there a way to actually input the tab character in the text anyway?
  • Ken
    Ken about 8 years
    @DanieleSegato <ctrl v><tab> should work in insert mode : stackoverflow.com/questions/4781070/…
  • Nic
    Nic over 7 years
    Could you explain what that first line means?
  • Gert van den Berg
    Gert van den Berg almost 7 years
    @shas: "ZZ" is equivalent to ":x", which is the same as ":wq", except that it only saves if the file has been changed... (Ctrl-Z is another story...)
  • lucidbrot
    lucidbrot almost 7 years
    Why don't you need anelse ? It seems to me like the last lines overwrite the makefile-specific in all cases
  • Shervin Emami
    Shervin Emami almost 7 years
    Hi @lucidbrot, the "autocmd FileType make" statement basically tells vim some settings to use whenever it opens a Makefile. Whereas the lines below it are setting the defaults. In other words, the "tabstop=8 ..." settings are applied later when the file is opened, and will overwrite the "tabstop=4 ..." settings that apply on initialization.
  • JonnyRaa
    JonnyRaa over 6 years
    @graywh can you explain the filetype line? The others have nice comments and I'm struggling to understand the help
  • graywh
    graywh over 6 years
    @JonnyLeeds :filetype on enables filetype detection (so FileType autocmds will work). :filetype plugin on enables the loading of filetype-specific scripts in ftplugin directories when the filetype is set. The same goes for :filetype indent on. All three can be combined into a single line.
  • Juha Untinen
    Juha Untinen over 6 years
    Note that this broke vim for me in Vagrant 2.0.0 when I edited the file with vim. It got stuck after vim opened a file - you couldn't do anything except Ctrl + C. However, mysteriously, it works again after I simply opened the file with nano and saved. No idea what causes that.
  • mcmacerson
    mcmacerson over 6 years
    expandtab determines if tabs are expanded to spaces. ts = tabstop = Number of spaces that a <Tab> in the file counts for. sw = shiftwidth = Number of spaces to use for each step of (auto)indent. ai = autoindent = Copy indent from current line when starting a new line.
  • code_dredd
    code_dredd almost 6 years
    Add set nu if you want to display line numbers :)
  • Nick Tsai
    Nick Tsai almost 6 years
    You could comment outfiletype plugin indent on for preventing multi-lines paste problem such as Cmder.
  • Kaz
    Kaz about 4 years
    @shas That simply untrue. If you don't want a swap file for an edit sesion, you have to run vim -n <file>. A swap file is not something that is generated at save time; that would pretty much defeat its purpose, since swap files become useful in recovering abruptly terminated edit sessions.
  • D. Ben Knoble
    D. Ben Knoble about 4 years
    All your mappings should use the non-recursive variants. Mapping go <C-t> can use that syntax rather than literals. Lastly, mapping <Tab> in normal mode will also map <C-i> (they are the same character), so I don’t recommend that (you lose a nifty piece of vim functionality
  • Kaz
    Kaz about 4 years
    @D.BenKnoble I don't recommend any of this; I use Ctrl-T, Ctrl-D, and < > myself. That's using Vim as intended. People used to using Tab in other editors might not like that, that's all.
  • Ramganesh
    Ramganesh over 3 years
    Detailed description can be found here.(vim.fandom.com/wiki/Converting_tabs_to_spaces)
  • PAT-O-MATION
    PAT-O-MATION over 3 years
    This is great worked like a charm. I felt like I was wasting time removing tabs when I forgot to hit the space bar x number of times.
  • bballdave025
    bballdave025 over 2 years
    +1 for making it extensible. I chose this one, because the comments about what each part does allow me to set things up exactly my way (without breaking anything), because I know what everything is doing. Hooray!