mirror of
				https://github.com/vim/vim.git
				synced 2025-10-30 09:47:20 -04: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
						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