How to set up vim allowing to use tabs and 4spaces - vim

I want normally always use four spaces to indent code.
Unfortunately for example Makefiles enforce the use of tabs as separator.
My idea now was to set the tab key to four spaces and some extra key (e.g. tab + shift) for the real tabs.
How do I set something like this up?
Currently my ~/.vimrc looks like:
syntax on
:set tabstop=4
:set cindent
:set autoindent

You may prefer something like this as well:
set expandtab
autocmd FileType make setlocal noexpandtab
This will always convert tabs to spaces, except when you are editing Makefiles.

Ctrl+V Tab will insert a literal tab, even if expandtab is set. If you prefer, you can map this to Shift+Tab with :inoremap <s-tab> <c-v><tab>.

You need to use shiftwidth, e.g.,
:set shiftwidth=4
:set expandtab
You may also need to use this command to convert existing tabs to spaces:
:retab

:filetype plugin on should be enough to have the tab key always insert real tabs in makefiles, using file type detection.
See :help vimrc-filetype.

While I generally prefer to convert everything to spaces, I have a specific command in my .vimrc to prevent doing so in makefiles. First I activate expandtab and set shiftwidth, but then I turn off expandtab for makefiles. Order is important here.
set shiftwidth=4
set expandtab
if has('autocmd')
autocmd FileType make set noexpandtab
endif
I also recommend the following, as they are somewhat related and possibly helpful:
set softtabstop=4
set shiftwidth=4
set smarttab
set autoindent

Related

Why does indentation done in vim look different in different editors?

I just used vim to edit a javascript file. My indentation in vim is set like so:
(source: take.ms)
When I edit a portion of the file, in vim it looks as though the indentation is correct:
(source: take.ms)
However, in SourceTree and in Sublime Text, the indentation is incorrect:
SourceTree:
(source: take.ms)
Sublime Text:
Can anyone explain to me why this is happening and how I might fix it? I'm also curious which, really, is the "true" representation of the file's state.
There are three related settings: tabstop, softtabstop, and shiftwidth. They are not the same.
tabstop sets the size of a tab character.
softtabstop sets the number of spaces inserted when the <Tab> key is pressed.
shiftwidth sets the number of spaces inserted when autoindentation is used (e.g. after typing if (foo) {<Cr>).
If expandtab isn't set, then spaces will be automatically replaced by a Tab character (0x09) as soon as the number of spaces is a multitude of tabstop. If expandtab is set, then spaces are never "expanded" to a tab character.
In your case, you only set the shiftwidth, which doesn't control the actual size of the tab characters. You either want to set tabstop to the same value as Sublime text, or you want to use space indentation by setting expandtab. If you use set list you can see if your file is using tab characters or spaces (use set nolist to disable this).
Bonus tip
In my personal opinion, you generally want to set all three settings to the same value. I use this command to quickly set all three with :TS 4:
command! -nargs=1 TS setlocal ts=<args> sts=<args> sw=<args>
The solution (thanks to #ceejayoz) was to set the expandtab option in my .vimrc settings, so this:
autocmd FileType javascript setlocal shiftwidth=2 tabstop=2 expandtab
autocmd FileType jsx setlocal shiftwidth=2 tabstop=2 expandtab
did the job.

Autoindenting not working in vim?

I am currently using vim and wish to autoindent every time I need to (such as after a brace in javascript or after a colon in Python). For some reason, I tried autoindent and smartindent, but every new line gave me 2 tabs instead of one. Why is it doing this? I thought it would only insert one tab.
My current ~/.vimrc file has:
set ts=4
set autoindent
set smartindent
filetype plugin indent on
you need to set up as well:
:set shiftwidth=4 softtabstop=4
tabstop is only for the number of columns a real "\t" tab takes:
:he shiftwidth
Number of spaces to use for each step of (auto)indent. Used for
|'cindent'|, |>>|, |<<|, etc.
When zero the 'ts' value will be used.
:he softtabstop
Number of spaces that a <Tab> counts for while performing editing
operations, like inserting a <Tab> or using <BS>. It "feels" like
<Tab>s are being inserted, while in fact a mix of spaces and <Tab>s is
used.
whereas tabstop:
:he tabstop
Number of spaces that a <Tab> in the file counts for. Also see
|:retab| command, and 'softtabstop' option.
As a bonus, here's a few mappings I've set up for that, when I need to work on projects that do not use my favorite default of expand tabs with 4 spaces indent:
nmap <Leader>t2 :set expandtab tabstop=2 shiftwidth=2 softtabstop=2<CR>
nmap <Leader>t4 :set expandtab tabstop=4 shiftwidth=4 softtabstop=4<CR>
nmap <Leader>t8 :set expandtab tabstop=8 shiftwidth=8 softtabstop=4<CR>
nmap <Leader>T2 :set noexpandtab tabstop=2 softtabstop=2 shiftwidth=2<CR>
nmap <Leader>T4 :set noexpandtab tabstop=4 softtabstop=4 shiftwidth=4<CR>
nmap <Leader>T8 :set noexpandtab tabstop=8 softtabstop=8 shiftwidth=8<CR>
I use like this in my .vimrc
filetype plugin indent on
set smartindent
set autoindent
set shiftwidth=4
set expandtab
set tabstop=4
set softtabstop=4
The expandtab will replace the tabs with spaces, I think this will be perfect for coding.

How to use only tab (not space) in vim

I prefer to use tab than white space(may be a little different from most of others)
But I found, when I hit Enter at the end of line, it will add some white spaces, but not tab. So, I have to delete them and press tab.
I want to know how to set vim as:
use only tab to indent the lines
a tab looks like 4-spaces, but actually is a tab
when hit enter at the end of a line, the new line is started with only tabs
I've googled for this for a while, but not found a good answer. Thank you in advance
UPDATE
The answer #Alok has provided works well in most of cases. But I just found, sometimes, it depends on the file type. For example, if you are editing a haml file, and there is a haml.vim in your vimfiles/indent/, then all the tabs will be converted to space. So if you want it to be tab only, you should modify(or delete) the corresponding indent file.
The settings you are looking for are:
set autoindent
set noexpandtab
set tabstop=4
set shiftwidth=4
As single line:
set autoindent noexpandtab tabstop=4 shiftwidth=4
autoindent can be replaced with smartindent or cindent, depending upon your tastes. Also look at filetype plugin indent on.
http://vim.wikia.com/wiki/Indenting_source_code
Late to the discussion, just for anyone who struggled to force the use of tabs. With the current version of vim (>8) it was required to set:
:set noet ci pi sts=0 sw=4 ts=4
which expands to:
:set noexpandtab
:set copyindent
:set preserveindent
:set softtabstop=0
:set shiftwidth=4
:set tabstop=4
We can also use this setup with only specific file types, taking advantage of setlocal:
autocmd FileType c,cpp,java,python setlocal noet ci pi sts=0 sw=4 ts=4
For further reference, see: https://vim.fandom.com/wiki/Indent_with_tabs,_align_with_spaces
In my case set indentexpr= did the trick.
I have found the config files which set the annoying behavior with fd python.vim /. In /usr/share/vim/vim90/indent/python.vim there is the line setlocal indentexpr=python#GetIndent(v:lnum). The function python#GetIndent is defined in /usr/share/vim/vim90/autoload/python.vim. This function returned a weird value which was not a multiple of shiftwidth and tabstop. Therefore vim inserted a tab followed by some spaces.
Now, that I have set indentexpr to an empty value, I think vim falls back to autoindent. smartindent and cindent are turned off. (https://vimhelp.org/indent.txt.html)
Of course set noexpandtab is required, too. I am not sure if any other settings are relevant here.
EDIT: autoindent is not perfect, it does nothing more than indent the new line as much as the previous line.
set smartindent
set cinwords=if,elif,else,try,except,finally,with,for,while,class,def
does not work as expected and cindent does not seem suitable for python, so using indentexpr is the way to go after all.
Luckily the indentation function can be configured, see help ft-python-indent or look at the code – that was more informative regarding the disable_parentheses_indenting feature. It seems this is the solution for me:
if !exists('g:python_indent')
let g:python_indent = {}
endif
let g:python_indent.disable_parentheses_indenting = 1
(https://vi.stackexchange.com/a/38824/43863)

How do I change tab size in Vim?

Every time I add a selector in CSS and I press Enter to define the properties it ends up like this:
#selector {
property: value;
}
(8-space tabs)
How can I configure Vim to make it like this:
#selector {
property: value;
}
(4-space tabs)
:set tabstop=4
:set shiftwidth=4
:set expandtab
This will insert four spaces instead of a tab character. Spaces are a bit more “stable”, meaning that text indented with spaces will show up the same in the browser and any other application.
To make the change for one session, use this command:
:set tabstop=4
To make the change permanent, add it to ~/.vimrc or ~/.vim/vimrc:
set tabstop=4
This will affect all files, not just css. To only affect css files:
autocmd Filetype css setlocal tabstop=4
as stated in Michał's answer.
Expanding on zoul's answer:
If you want to setup Vim to use specific settings when editing a particular filetype, you'll want to use autocommands:
autocmd Filetype css setlocal tabstop=4
This will make it so that tabs are displayed as 4 spaces. Setting expandtab will cause Vim to actually insert spaces (the number of them being controlled by tabstop) when you press tab; you might want to use softtabstop to make backspace work properly (that is, reduce indentation when that's what would happen should tabs be used, rather than always delete one char at a time).
To make a fully educated decision as to how to set things up, you'll need to read Vim docs on tabstop, shiftwidth, softtabstop and expandtab. The most interesting bit is found under expandtab (:help 'expandtab):
There are four main ways to use tabs in Vim:
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.
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.
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.
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' is changed.
As a one-liner into vim:
:set tabstop=4 shiftwidth=4
For permanent setup, add these lines to ~/.vimrc:
set tabstop=4
set shiftwidth=4
set expandtab <-- (optional) 4-spaces instead of Tab indentation
Several of the answers on this page are 'single use' fixes to the described problem. Meaning, the next time you open a document with vim, the previous tab settings will return.
If anyone is interested in permanently changing the tab settings:
find/open your .vimrc - instructions here
add the following lines: (more info here)
set tabstop=4
set shiftwidth=4
set expandtab
then save file and test
UPDATE
If you are working in a particular project I highly recommend using editorconfig.
It lets you define an .editorconfig file at the root of your repository defining the indentation you want to use for each file type across your repository.
For example:
root = true
[*.css]
charset = utf-8
indent_style = space
indent_size = 4
[*.js]
charset = utf-8
indent_style = space
indent_size = 2
There is a vim plugin that automatically configures vim according to the config file for file you open.
On top of that the .editorconfig file is automatically supported on many other IDEs and editors so it is the best option for collaborating between users with different environments.
ORIGINAL ANSWER
If you need to change sizes often and you don't want to bind this to a specific file type you can have predefined commands on your .vimrc file to quickly switch preferences:
nmap <leader>t :set expandtab tabstop=4 shiftwidth=4 softtabstop=4<CR>
nmap <leader>m :set expandtab tabstop=2 shiftwidth=2 softtabstop=2<CR>
This maps two different sets of sizes to keys \t and \m. You can rebind this to whatever keys you want.
in my .vim/vimrc (vim 8.0 under ubuntu bionic), I have
if has("autocmd")
filetype plugin indent on
endif
so added line like :
autocmd Filetype css setlocal tabstop=2
doesn't work.
I created .vim/indent folder and added in :
css.vim with
set tabstop=2
set shiftwidth=2
set softtabstop=2
and it works !
I tried to on another computer with ubuntu focal and vim 8.1, it doesn't work !-(
in vim command mode, write:
:set ts=X
where X is your new desired space length

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

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.
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
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
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).
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.
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.
The recommended way is to use filetype based indentation and only use smartindent and cindent if that doesn't suffice.
Add the following to your .vimrc
set expandtab
set shiftwidth=2
set softtabstop=2
filetype plugin indent on
Hope it helps as being a different answer.
From the VIM wiki:
:set tabstop=4
:set shiftwidth=4
:set expandtab
edit your ~/.vimrc
$ vim ~/.vimrc
add following lines :
set tabstop=4
set shiftwidth=4
set softtabstop=4
set expandtab
The auto-indent is based on the current syntax mode. I know that if you are editing Foo.java, then entering a { and hitting Enter indents the following line.
As for tabs, there are two settings. Within Vim, type a colon and then "set tabstop=4" which will set the tabs to display as four spaces. Hit colon again and type "set expandtab" which will insert spaces for tabs.
You can put these settings in a .vimrc (or _vimrc on Windows) in your home directory, so you only have to type them once.
Firstly, do not use the Tab key in Vim for manual indentation. Vim has a pair of commands in insert mode for manually increasing or decreasing the indentation amount. Those commands are Ctrl-T and Ctrl-D. These commands observe the values of tabstop, shiftwidth and expandtab, and maintain the correct mixture of spaces and tabs (maximum number of tabs followed by any necessary number of spaces).
Secondly, these manual indenting keys don't have to be used very much anyway if you use automatic indentation.
If Ctrl-T instead of Tab bothers you, you can remap it:
:imap <Tab> ^T
You can also remap Shift-Tab to do the Ctrl-D deindent:
:imap <S-Tab> ^D
Here ^T and ^D are literal control characters that can be inserted as Ctrl-VCtrl-T.
With this mapping in place, you can still type literal Tab into the buffer using Ctrl-VTab. Note that if you do this, even if :set expandtab is on, you get an unexpanded tab character.
A similar effect to the <Tab> map is achieved using :set smarttab, which also causes backspace at the front of a line to behave smart.
In smarttab mode, when Tab is used not at the start of a line, it has no special meaning. That's different from my above mapping of Tab to Ctrl-T, because a Ctrl-T used anywhere in a line (in insert mode) will increase that line's indentation.
Other useful mappings may be:
:map <Tab> >
:map <S-Tab> <
Now we can do things like select some lines, and hit Tab to indent them over. Or hit Tab twice on a line (in command mode) to increase its indentation.
If you use the proper indentation management commands, then everything is controlled by the three parameters: shiftwidth, tabstop and expandtab.
The shiftwidth parameter controls your indentation size; if you want four space indents, use :set shiftwidth=4, or the abbreviation :set sw=4.
If only this is done, then indentation will be created using a mixture of spaces and tabs, because noexpandtab is the default. Use :set expandtab. This causes tab characters which you type into the buffer to expand into spaces, and for Vim-managed indentation to use only spaces.
When expandtab is on, and if you manage your indentation through all the proper Vim mechanisms, the value of tabstop becomes irrelevant. It controls how tabs appear if they happen to occur in the file. If you have set tabstop=8 expandtab and then sneak a hard tab into the file using Ctrl-VTab, it will produce an alignment to the next 8-column-based tab position, as usual.
Afterall, you could edit the .vimrc,then add the conf
set tabstop=4
Or exec the command
Simplest one will be n vim file
set tabstop=4

Resources