mirror of
https://github.com/vim/vim
synced 2025-07-16 01:01:58 +00:00
runtime(doc): clarify tabstop settings and guidance
closes: #17381 Signed-off-by: Damien Lejay <damien@lejay.be> Co-authored-by: Aliaksei Budavei <32549825+zzzyxwvut@users.noreply.github.com> Co-authored-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
570e71a277
commit
a4a3f712e2
@ -8493,46 +8493,14 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
*'tabstop'* *'ts'*
|
||||
'tabstop' 'ts' number (default 8)
|
||||
local to buffer
|
||||
Number of spaces that a <Tab> in the file counts for. Also see
|
||||
the |:retab| command, and the 'softtabstop' option.
|
||||
Defines the column multiple used to display the Horizontal Tab
|
||||
character (ASCII 9); a Horizontal Tab always advances to the next
|
||||
tab stop.
|
||||
The value must be at least 1 and at most 9999.
|
||||
If Vim was compiled with |+vartabs| and |'vartabstop'| is set, this option
|
||||
is ignored.
|
||||
Leave it at 8 unless you have a strong reason (see usr |30.5|).
|
||||
|
||||
Note: Setting 'tabstop' to any other value than 8 can make your file
|
||||
appear wrong in many places, e.g., when printing it.
|
||||
The value must be more than 0 and less than 10000.
|
||||
|
||||
There are five 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 <Tab> and <BS> will
|
||||
behave like a tab appears every 4 (or 3) characters.
|
||||
This is the recommended way, the file will look the same with other
|
||||
tools and when listing it in a terminal.
|
||||
2. Set 'softtabstop' 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 (leave
|
||||
it at 8 just in case). The file will be a bit larger.
|
||||
You do need to check if no Tabs exist in the file. You can get rid
|
||||
of them by first setting 'expandtab' and using `%retab!`, making
|
||||
sure the value of 'tabstop' is set correctly.
|
||||
3. 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.
|
||||
You do need to check if no Tabs exist in the file, just like in the
|
||||
item just above.
|
||||
4. 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, other tools assume a tabstop
|
||||
is worth 8 spaces.
|
||||
5. 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.
|
||||
|
||||
If Vim is compiled with the |+vartabs| feature then the value of
|
||||
'tabstop' will be ignored if |'vartabstop'| is set to anything other
|
||||
than an empty string.
|
||||
|
||||
*'tagbsearch'* *'tbs'* *'notagbsearch'* *'notbs'*
|
||||
'tagbsearch' 'tbs' boolean (default on)
|
||||
|
@ -1,4 +1,4 @@
|
||||
*usr_30.txt* For Vim version 9.1. Last change: 2024 Apr 29
|
||||
*usr_30.txt* For Vim version 9.1. Last change: 2025 May 30
|
||||
|
||||
VIM USER MANUAL - by Bram Moolenaar
|
||||
|
||||
@ -409,108 +409,202 @@ the cursor is on "printf":
|
||||
==============================================================================
|
||||
*30.5* Tabs and spaces
|
||||
|
||||
'tabstop' is set to eight by default. Although you can change it, you quickly
|
||||
run into trouble later. Other programs won't know what tabstop value you
|
||||
used. They probably use the default value of eight, and your text suddenly
|
||||
looks very different. Also, most printers use a fixed tabstop value of eight.
|
||||
Thus it's best to keep 'tabstop' alone. (If you edit a file which was written
|
||||
with a different tabstop setting, see |25.3| for how to fix that.)
|
||||
For indenting lines in a program, using a multiple of eight spaces makes
|
||||
A QUICK HISTORY OF THE RATIONALE BEHIND TABS
|
||||
|
||||
`vi` (the ancestor of Vim) was created by Bill Joy. At the time, he was using
|
||||
a PDP-11 with limited memory and I/O operation capabilities. Back then, it
|
||||
was common to optimize the size of source code with the following trick.
|
||||
The ASCII table was first designed to remotely control teleprinters. When
|
||||
control character 9 (the Horizontal Tab, caret notation: ^I) was sent to a
|
||||
teleprinter, it would move the carriage to the next tab stop. Assuming tab
|
||||
stops were separated by 8 columns (a typical standard), this means that a
|
||||
single control character could produce the same visual effect as up to 8 space
|
||||
characters. For example, the following two lines will display identically >
|
||||
|
||||
1234^I9
|
||||
1234 9
|
||||
|
||||
Using the <Tab> key was also faster than typing <Space> several times; the
|
||||
same was true for <BS>.
|
||||
|
||||
|
||||
THE ISSUE WITH TABS AND INDENTATION
|
||||
|
||||
In Vim, the number of columns between two (virtual) horizontal tab stops
|
||||
is controlled by 'tabstop' and is set to eight by default. Although you can
|
||||
change it, you quickly run into trouble later. Other programs won't know what
|
||||
tabstop value you used. They probably use the default value of eight, and
|
||||
your text suddenly looks very different. Also, most printers use a fixed
|
||||
tabstop value of eight. Thus it's best to keep 'tabstop' alone; if you edit a
|
||||
file which was written with a different tabstop setting, see |25.3| for how
|
||||
to fix that.
|
||||
For indenting lines in a program, using a multiple of eight columns makes
|
||||
you quickly run into the right border of the window. Using a single space
|
||||
doesn't provide enough visual difference. Many people prefer to use four
|
||||
spaces, a good compromise.
|
||||
Since a <Tab> is eight spaces and you want to use an indent of four spaces,
|
||||
you can't use a <Tab> character to make your indent. There are two ways to
|
||||
handle this:
|
||||
Since a tab character at the beginning of a line is visually represented
|
||||
as eight spaces and you want to use an indent of four spaces, you can't use a
|
||||
tab character to make your indent.
|
||||
To remedy this, `vi` had the 'shiftwidth' option. When set to 4, on a new
|
||||
line, pressing <C-t> in Insert mode would indent the line by 4 spaces,
|
||||
a result impossible to get with the <Tab> key and 'tabstop' set to 8.
|
||||
To optimize space, `vi` would also silently remove packs of spaces and replace
|
||||
them with tab characters. The following shows what happens pressing <C-t>
|
||||
a few times.
|
||||
A "." stands for a space character and "------->" for a tab character.
|
||||
|
||||
1. Use a mix of <Tab> and space characters. Since a <Tab> takes the place of
|
||||
eight spaces, you have fewer characters in your file. Inserting a <Tab>
|
||||
is quicker than eight spaces. Backspacing works faster as well.
|
||||
type result ~
|
||||
<C-t> ....
|
||||
<C-t><C-t> ------->
|
||||
<C-t><C-t><C-t> ------->....
|
||||
|
||||
2. Use spaces only. This avoids the trouble with programs that use a
|
||||
different tabstop value.
|
||||
Similarly pressing <C-d> in Insert mode would decrease the indent. Hence
|
||||
with `set tabstop=8 shiftwidth=2` one has
|
||||
|
||||
Fortunately, Vim supports both methods quite well.
|
||||
type result ~
|
||||
<C-t><Tab><C-t> ..----->..
|
||||
<C-t><Tab><C-t><C-d> ------->
|
||||
|
||||
A third option that one could set in `vi` was 'autoindent'. It copies the
|
||||
indent level of the previous lines,
|
||||
|
||||
SPACES AND TABS
|
||||
type result ~
|
||||
<Space><Tab>hello .------>hello
|
||||
<Space><Tab>hello<Enter> .------>hello
|
||||
------->
|
||||
|
||||
If you are using a combination of tabs and spaces, you just edit normally.
|
||||
The Vim defaults do a fine job of handling things.
|
||||
You can make life a little easier by setting the 'softtabstop' option.
|
||||
This option tells Vim to make the <Tab> key look and feel as if tabs were set
|
||||
at the value of 'softtabstop', but actually use a combination of tabs and
|
||||
spaces.
|
||||
After you execute the following command, every time you press the <Tab> key
|
||||
the cursor moves to the next 4-column boundary: >
|
||||
|
||||
:set softtabstop=4
|
||||
|
||||
When you start in the first column and press <Tab>, you get 4 spaces inserted
|
||||
in your text. The second time, Vim takes out the 4 spaces and puts in a <Tab>
|
||||
(thus taking you to column 8). Thus Vim uses as many <Tab>s as possible, and
|
||||
then fills up with spaces.
|
||||
When backspacing it works the other way around. A <BS> will always delete
|
||||
the amount specified with 'softtabstop'. Then <Tab>s are used as many as
|
||||
possible and spaces to fill the gap.
|
||||
The following shows what happens pressing <Tab> a few times, and then using
|
||||
<BS>. A "." stands for a space and "------->" for a <Tab>.
|
||||
|
||||
type result ~
|
||||
<Tab> ....
|
||||
<Tab><Tab> ------->
|
||||
<Tab><Tab><Tab> ------->....
|
||||
<Tab><Tab><Tab><BS> ------->
|
||||
<Tab><Tab><Tab><BS><BS> ....
|
||||
|
||||
An alternative is to use the 'smarttab' option. When it's set, Vim uses
|
||||
'shiftwidth' for a <Tab> typed in the indent of a line, and a real <Tab> when
|
||||
typed after the first non-blank character. However, <BS> doesn't work like
|
||||
with 'softtabstop'.
|
||||
but the new line is produced by optimizing the number of characters used.
|
||||
|
||||
|
||||
JUST SPACES
|
||||
|
||||
If you want absolutely no tabs in your file, you can set the 'expandtab'
|
||||
option: >
|
||||
But separating tab stops with 8 columns was not universal: IBM had a standard
|
||||
at 10 columns, and today some Go developers write code with `tabstop=4`. Every
|
||||
time text is displayed with a different 'tabstop' value, it risks misaligning
|
||||
the text, especially once the file is shared and opened on another machine.
|
||||
In the meantime, computers got much better and the few octets saved by using
|
||||
tabs were no longer making any real difference. It became possible to use
|
||||
only spaces and thus guarantee the same resulting text everywhere. But using
|
||||
only spaces was impossible in `vi` without sacrificing features. Remember that
|
||||
'autoindent' would systematically try to input a tab character when it could.
|
||||
Vim 4.0 made working with only spaces as convenient as working only with
|
||||
tabs (or a mix of tabs and spaces), by introducing the 'expandtab' option.
|
||||
When set, Vim will replace any horizontal tab character it would normally
|
||||
insert with an equivalent number of spaces, to end up with the same visual
|
||||
effect. <BS> would continue to remove only one character at a time.
|
||||
|
||||
:set expandtab
|
||||
|
||||
When this option is set, the <Tab> key inserts a series of spaces. Thus you
|
||||
get the same amount of white space as if a <Tab> character was inserted, but
|
||||
there isn't a real <Tab> character in your file.
|
||||
The backspace key will delete each space by itself. Thus after typing one
|
||||
<Tab> you have to press the <BS> key up to eight times to undo it. If you are
|
||||
in the indent, pressing CTRL-D will be a lot quicker.
|
||||
type result ~
|
||||
<Tab> ........
|
||||
<Tab><BS> .......
|
||||
|
||||
|
||||
CHANGING TABS IN SPACES (AND BACK)
|
||||
|
||||
Setting 'expandtab' does not affect any existing tabs. In other words, any
|
||||
tabs in the document remain tabs. If you want to convert tabs to spaces, use
|
||||
the ":retab" command. Use these commands: >
|
||||
Setting 'expandtab' does not immediately affect existing tab characters. In
|
||||
order to purge a file from all its horizontal tab characters, Vim 5.3
|
||||
introduced the |:retab| command. Use these commands: >
|
||||
|
||||
:set expandtab
|
||||
:%retab
|
||||
|
||||
Now Vim will have changed all indents to use spaces instead of tabs. However,
|
||||
all tabs that come after a non-blank character are kept. If you want these to
|
||||
be converted as well, add a !: >
|
||||
|
||||
:%retab!
|
||||
:retab
|
||||
|
||||
This is a little bit dangerous, because it can also change tabs inside a
|
||||
string. To check if these exist, you could use this: >
|
||||
|
||||
/"[^"\t]*\t[^"]*"
|
||||
|
||||
It's recommended not to use hard tabs inside a string. Replace them with
|
||||
"\t" to avoid trouble.
|
||||
It's recommended not to use actual tab characters inside a string. Replace
|
||||
them with "\t" to avoid trouble.
|
||||
|
||||
The other way around works just as well: >
|
||||
The other way around works just as well: >
|
||||
|
||||
:set noexpandtab
|
||||
:%retab!
|
||||
:retab!
|
||||
|
||||
|
||||
SOFT TAB STOPS
|
||||
|
||||
When using only spaces, or a mix of spaces and horizontal tabs, one gets the
|
||||
unpleasant feeling that the two keys <Tab> and <BS> do not act in mirror, as
|
||||
they do when using only tab characters.
|
||||
Vim 5.4 introduced the 'softtabstop' option. On top of the (hard) tab stops
|
||||
used to display the horizontal tab characters in the text, Vim adds extra
|
||||
soft tab stops dedicated only to the cursor. When 'softtabstop' is set to a
|
||||
positive value, and the <Tab> key will push the cursor to the next soft tab
|
||||
stop. Vim will insert the correct combination of tab characters and spaces to
|
||||
make the effect visually. Likewise pressing <BS> will have the cursor try to
|
||||
reach the nearest soft tab stop. The following example uses
|
||||
`:set softtabstop=4`
|
||||
|
||||
type result ~
|
||||
<Tab> ....
|
||||
<Tab><Tab>a ------->a
|
||||
<Tab><Tab>a<Tab> ------->a...
|
||||
<Tab><Tab>a<Tab><BS> ------->a
|
||||
|
||||
To maintain global coherence, one can `:set softtabstop=-1` so that
|
||||
the value of 'shiftwidth' is use for the number of columns between two soft
|
||||
tab stops.
|
||||
|
||||
If you prefer to have different values for 'shiftwidth' and 'softtabstop',
|
||||
you can still do so and use <C-t> to indent with 'shiftwidth'. Or you can
|
||||
use the 'smarttab' option introduced in Vim 5.6, allowing for a unified
|
||||
<Tab> key that knows what to do in the different situations.
|
||||
|
||||
|
||||
VARIABLE TAB STOPS
|
||||
|
||||
As we said before, the ASCII table was designed to remotely control
|
||||
teleprinters. A given teleprinter could be configured to have their physical
|
||||
tab stops have variable spacing. After all, the ^I control character was
|
||||
only stipulating: go to the next tab stop wherever it is.
|
||||
Vim 7.3 introduced 'vartabstop' to emulate the same functionality. For
|
||||
example if Vim was compiled with `+vartabs` and `:set vartabstop=2,4` one gets
|
||||
|
||||
actual character result ~
|
||||
^I ->
|
||||
^I^I ->--->
|
||||
^I^I^I ->--->--->
|
||||
|
||||
Similarly, 'varsofttabstop' was also introduced, to have variably spaced
|
||||
soft tab stops. With `:set varsofttabstop=2,4` one gets
|
||||
|
||||
type result ~
|
||||
<Tab> ..
|
||||
<Tab><Tab> ......
|
||||
<Tab><Tab><Tab> ------->....
|
||||
|
||||
|
||||
EXAMPLES OF CONFIGURATION
|
||||
|
||||
By default, Vim is configured to use only tabs: >
|
||||
|
||||
:set tabstop=8
|
||||
:set shiftwidth=8
|
||||
:set noexpandtab
|
||||
:set softtabstop=0
|
||||
:set nosmarttab
|
||||
<
|
||||
If you want to write C code as if it were Python (only spaces, with indents
|
||||
of 4 spaces), here is what you can use: >
|
||||
|
||||
:set shiftwidth=4
|
||||
:set softtabstop=-1
|
||||
:set expandtab
|
||||
<
|
||||
If you want the same behavior but with better control over alignment
|
||||
(e.g. lining up parameters or comments in multiples of 2 spaces), use: >
|
||||
|
||||
:set shiftwidth=4
|
||||
:set softtabstop=2
|
||||
:set expandtab
|
||||
:set smarttab
|
||||
<
|
||||
If instead, you would like to write C code like Bram Moolenaar would have
|
||||
(using a mix of tabs and spaces), you can use >
|
||||
|
||||
:set shiftwidth=4
|
||||
:set softtabstop=-1
|
||||
<
|
||||
|
||||
==============================================================================
|
||||
*30.6* Formatting comments
|
||||
|
Reference in New Issue
Block a user