runtime(doc): clarify tabstop settings and guidance Commit: https://github.com/vim/vim/commit/a4a3f712e250299bb788a1de9c7557ba0de92f06 Author: Damien Lejay <dam...@lejay.be> Date: Fri May 30 17:36:37 2025 +0200
runtime(doc): clarify tabstop settings and guidance closes: https://github.com/vim/vim/issues/17381 Signed-off-by: Damien Lejay <dam...@lejay.be> Co-authored-by: Aliaksei Budavei <32549825+zzzyxw...@users.noreply.github.com> Co-authored-by: Christian Brabandt <c...@256bit.org> diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 86392dd57..0f8d06362 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -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. - - 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. + 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|). - 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) diff --git a/runtime/doc/usr_30.txt b/runtime/doc/usr_30.txt index c3bbcba69..9efc2efa0 100644 --- a/runtime/doc/usr_30.txt +++ b/runtime/doc/usr_30.txt @@ -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 -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: +A QUICK HISTORY OF THE RATIONALE BEHIND TABS -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. +`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 > -2. Use spaces only. This avoids the trouble with programs that use a - different tabstop value. + 1234^I9 + 1234 9 -Fortunately, Vim supports both methods quite well. +Using the <Tab> key was also faster than typing <Space> several times; the +same was true for <BS>. -SPACES AND TABS +THE ISSUE WITH TABS AND INDENTATION -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: > +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 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. - :set softtabstop=4 + type result ~ + <C-t> .... + <C-t><C-t> -------> + <C-t><C-t><C-t> ------->.... -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>. + Similarly pressing <C-d> in Insert mode would decrease the indent. Hence +with `set tabstop=8 shiftwidth=2` one has - type result ~ - <Tab> .... - <Tab><Tab> -------> - <Tab><Tab><Tab> ------->.... - <Tab><Tab><Tab><BS> -------> - <Tab><Tab><Tab><BS><BS> .... + type result ~ + <C-t><Tab><C-t> ..----->.. + <C-t><Tab><C-t><C-d> -------> -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'. + A third option that one could set in `vi` was 'autoindent'. It copies the +indent level of the previous lines, + type result ~ + <Space><Tab>hello .------>hello + <Space><Tab>hello<Enter> .------>hello + -------> -JUST SPACES +but the new line is produced by optimizing the number of characters used. -If you want absolutely no tabs in your file, you can set the 'expandtab' -option: > - :set expandtab +JUST SPACES -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. +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. + + 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: > /"[^" ]* [^"]*" -It's recommended not to use hard tabs inside a string. Replace them with -" " to avoid trouble. +It's recommended not to use actual tab characters inside a string. Replace +them with " " 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 -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1uL1up-007Nzy-2G%40256bit.org.