Vim Tips Wiki
No edit summary
(reason for smart tab and copy/preserve indent settings)
Tag: sourceedit
(42 intermediate revisions by 11 users not shown)
Line 1: Line 1:
  +
{{TipNew
Tabs vs. spaces for whitespace: which to use? Tabs are good for indentation because their width can be customized (<tt>tabstop</tt>). On the other hand, spaces must be used to line something up across lines. Why not have the best of both worlds and use ''both''?
 
  +
|id=1626
  +
|previous=1625
  +
|next=1627
  +
|created=2009
  +
|complexity=basic
  +
|author=
  +
|version=7.0
  +
|subpage=/200906
  +
|category1=
  +
|category2=
 
}}
 
Tabs vs. spaces for whitespace: which to use? Tabs are good for indentation because their width can be adjusted according to preference ({{help|'tabstop'}}). On the other hand, spaces must be used to ensure text stays lined up across lines if <code>tabstop</code> is changed.
   
  +
Using the "[[#Smart_tabs|smart tabs]]" scheme described below combines the strengths of both.
--->int...foo;
 
--->float.bar;
 
   
  +
This tip discusses indenting using tabs and spaces, including methods to allow <code>tabstop</code> adjustment, while maintaining textual alignment. See [[VimTip83|indenting source code]] for background information on indenting.
Here, tabs (<tt>---></tt>) are used for indentation, while spaces (<tt>.</tt>) are used for alignment.
 
   
== Smart Tabs ==
+
==Spaces or tabs?==
  +
Programs use whitespace (spaces or tabs) for two purposes:
  +
*To indent blocks of code (for example, to show the code that is in a loop).
  +
*To align text (for example, so comments start in the same column).
   
  +
Some procedures commonly used to write programs are:
The [http://www.vim.org/scripts/script.php?script_id=231 Smart Tabs] plugin accomplishes the above by ensuring that tabs are only used at the beginning of lines, while spaces are used everywhere else.
 
  +
*Use spaces for indentation and alignment.
  +
*Use [[#Using_tabs_for_indentation|tabs]] for indentation and alignment.
  +
*Use a mixture of tabs and spaces for indentation and alignment.
  +
*Use tabs for indentation and spaces for alignment ("[[#Smart_tabs|smart tabs]]").
   
  +
In large projects, using as many tabs as possible can significantly reduce the size of the source code, and in some rare cases (for example, [[wikipedia:make (software)|make files]]), tabs ''must'' be used for indentation. Apart from these considerations, whether you use tabs or spaces is generally a personal choice, or is determined by the coding style of the project.
== Continuation lines ==
 
   
  +
Using spaces for indentation means that the code will look the same on all systems, even if the <code>tabstop</code> option is changed. However, different people like different indent sizes, so a common procedure is to use tabs for indentation so the indent size can easily be adjusted to suit whoever is working on the code. If the <code>tabstop</code> size is changed, it is necessary to use spaces for alignment because that will maintain the alignment with a different <code>tabstop</code>, provided the lines with aligned text use the same number of tabs for indenting.
When expressions span multiple lines, we may want to line up the ''beginning'' of those lines with the beginning of the expression in the first line.
 
   
 
Here is an example using tabs for indentation and spaces for alignment:
int f(int x,
 
  +
<pre>
int y) {
 
  +
int sample(int a)
return g(x,
 
  +
{
y);
 
  +
|-------int count; // variable names are aligned
}
 
  +
|-------float average; // (some people like it that way)
  +
|-------if (a > 0)
  +
|-------|-------return 1;
 
|-------return 0;
 
}
  +
</pre>
   
  +
In the above, "<code>|-------</code>" represents a tab using the default <code>:set tabstop=8</code>. Entering <code>:set tabstop=4</code> makes the code appear as:
To have Vim to align in this way, <tt>:set cindent</tt> and <tt>:set cinoptions=(0,u0,U0</tt>. Using the latest version of the [http://www.vim.org/scripts/script.php?script_id=231 Smart Tabs] plugin, the whitespace will be formatted as such:
 
  +
<pre>
  +
int sample(int a)
  +
{
  +
|---int count; // variable names are aligned
  +
|---float average; // (some people like it this way)
  +
|---if (a > 0)
  +
|---|---return 1;
  +
|---return 0;
  +
}
  +
</pre>
   
  +
This illustrates that using tabs for indentation and spaces for alignment keeps the alignment unchanged when the <code>tabstop</code> is altered (for lines with the same indent).
int f(int x,
 
......int y) {
 
--->return g(x,
 
--->.........y);
 
}
 
   
  +
==Using tabs for indentation==
== External resources ==
 
  +
If you want to use only tabs for indentation (not spaces), enter the following command (replace <code>4</code> with your preferred column width for each indent level):
  +
<pre>
  +
:set noet ci pi sts=0 sw=4 ts=4
  +
</pre>
   
  +
The previous line is an abbreviated equivalent of these commands:
* [http://www.emacswiki.org/emacs/IntelligentTabs EmacsWiki: Intelligent Tabs]. Editor-agnostic article about implementing smarter tabbing behavior.
 
  +
<pre>
* [http://www.iovene.com/tabs-vs-spaces-the-end-of-the-debate/ Tabs vs. Spaces: The end of the debate]. Vim/Emacs tips for tabbing.
 
  +
:set noexpandtab
* [http://www.movementarian.org/docs/whytabs/ Use Tabs in Source Code]. Spaces for alignment, but tabs for indentation.
 
  +
:set copyindent
  +
:set preserveindent
  +
:set softtabstop=0
  +
:set shiftwidth=4
  +
:set tabstop=4
  +
</pre>
  +
  +
However, note that in the case of [[#Continuation_lines|continuation lines]], some spaces may be added when the indentation is not a multiple of <code>tabstop</code>.
  +
  +
If you want the commands to affect only the current buffer, replace <code>set</code> with <code>setlocal</code> (abbreviated as <code>setl</code>). More information is [[VimTip83|here]].
  +
  +
===Smart tabs===
  +
The settings above use hard tabs as far as possible. To use tabs in a more "semantic" way &ndash; i.e., the number of tabs equals the indentation level &ndash; install the {{script|id=231|text=Smart Tabs}} plugin.
  +
  +
The plugin ensures that tabs are ''only'' used for indentation, while spaces are used everywhere else. When you press Tab in insert mode, a tab is inserted when indenting, and/or the correct number of spaces when aligning text (see [[#Continuation_lines|continuation lines]]). Different people can then use whatever <code>shiftwidth</code> and <code>tabstop</code> they want (provided these two values are equal) &ndash; the end result is the same, and is displayed correctly everywhere.
  +
  +
You do not need a "smart" editor to display or edit smartly tabbed files &ndash; that's the whole point. The Smart Tabs plugin is just an added convenience. If your non-Vim-using collaborators remain unconvinced, pass them these pointers, whichever is appropriate: [http://www.emacswiki.org/emacs/SmartTabs smart tabs for Emacs], and [http://www.jetbrains.com/idea/ IntelliJ IDEA] has a built-in "smart tabs" option.
  +
 
==Continuation lines==
 
When expressions span multiple lines, you may want to line up the ''beginning'' of those lines with the beginning of the expression in the first line:
  +
<pre>
 
int f(int x,
 
int y) {
 
return g(x,
 
y);
  +
}
  +
</pre>
  +
  +
To make Vim format the code in this way, using four-column indentation, enter the following (use <code>setl</code> instead of <code>set</code> to affect only the current buffer):
  +
<pre>
  +
:set noet sts=0 sw=4 ts=4
  +
:set cindent
  +
:set cinoptions=(0,u0,U0
  +
</pre>
  +
  +
Using the Smart Tabs plugin, tabs will then only be used for indenting (in the third and fourth lines), while spaces will be used for alignment:
  +
<pre>
 
int f(int x,
 
int y) {
  +
|---return g(x,
  +
|--- y);
  +
}
  +
</pre>
  +
  +
That makes the alignment of "<code>x</code>" and "<code>y</code>" independent of <code>tabstop</code>.
  +
  +
==See also==
  +
*[[VimTip1592|Super retab]] to convert leading spaces to tabs
  +
  +
==Comments==
  +
This [http://vim.wikia.com/index.php?title=Indent_with_tabs,_align_with_spaces&diff=26650&oldid=26649 edit] added copyindent and preserveindent to the [[#Using tabs for indentation]] section. I do not understand the benefit of these in that section which asserts that ''only'' tabs will be used for indentation. These options should be mentioned somewhere (here or in [[Indenting source code]]), but possibly not in that section. Any thoughts? [[User:JohnBeckett|JohnBeckett]] 22:23, March 8, 2010 (UTC)
  +
:Those options are useful for preserving manually created indentation, which is useful for using tabs for the indent (automatic) and then manually adding spaces to align stuff. --[[User:Fritzophrenic|Fritzophrenic]] ([[User talk:Fritzophrenic|talk]]) 16:18, March 4, 2015 (UTC)
  +
  +
----
  +
Hi, do I need the Smart Tabs plugin to get the behaviour like "Indent_with_tabs,_align_with_spaces"? Because first you say
  +
<code>:set noet ci pi sts=0 sw=4 ts=4</code>
  +
to use only tabs for indentation (not spaces), which implicitly means spaces for aligning, no?
  +
Later you say I need the Smart Tabs plugin because <blockquote>The plugin ensures that tabs are only used for indentation, while spaces are used everywhere else.</blockquote>. [[User:Massimo.b|Massimo.b]] 2015-03-04
  +
:Without Smart Tabs, Vim can insert tabs for indentation for you, but you will need to manually add spaces to do alignment past the indentation. The copyindent/preserveindent settings let Vim automatically copy that manual alignment for the next line, but the space-based alignment is still a manual step. And pressing Tab will always insert a tab with this setup, it will never insert any spaces, so it will take more keypresses to insert large amounts of alignment whitespace. With Smart Tabs, if I understand correctly what the plugin does, the plugin will automatically figure out whether you are adding indentation or alignment whitespace, and insert a space or tab accordingly. --[[User:Fritzophrenic|Fritzophrenic]] ([[User talk:Fritzophrenic|talk]]) 16:18, March 4, 2015 (UTC)

Revision as of 16:18, 4 March 2015

Tip 1626 Printable Monobook Previous Next

created 2009 · complexity basic · version 7.0


Tabs vs. spaces for whitespace: which to use? Tabs are good for indentation because their width can be adjusted according to preference (:help 'tabstop'). On the other hand, spaces must be used to ensure text stays lined up across lines if tabstop is changed.

Using the "smart tabs" scheme described below combines the strengths of both.

This tip discusses indenting using tabs and spaces, including methods to allow tabstop adjustment, while maintaining textual alignment. See indenting source code for background information on indenting.

Spaces or tabs?

Programs use whitespace (spaces or tabs) for two purposes:

  • To indent blocks of code (for example, to show the code that is in a loop).
  • To align text (for example, so comments start in the same column).

Some procedures commonly used to write programs are:

  • Use spaces for indentation and alignment.
  • Use tabs for indentation and alignment.
  • Use a mixture of tabs and spaces for indentation and alignment.
  • Use tabs for indentation and spaces for alignment ("smart tabs").

In large projects, using as many tabs as possible can significantly reduce the size of the source code, and in some rare cases (for example, make files), tabs must be used for indentation. Apart from these considerations, whether you use tabs or spaces is generally a personal choice, or is determined by the coding style of the project.

Using spaces for indentation means that the code will look the same on all systems, even if the tabstop option is changed. However, different people like different indent sizes, so a common procedure is to use tabs for indentation so the indent size can easily be adjusted to suit whoever is working on the code. If the tabstop size is changed, it is necessary to use spaces for alignment because that will maintain the alignment with a different tabstop, provided the lines with aligned text use the same number of tabs for indenting.

Here is an example using tabs for indentation and spaces for alignment:

int sample(int a)
{
|-------int   count;      // variable names are aligned
|-------float average;    // (some people like it that way)
|-------if (a > 0)
|-------|-------return 1;
|-------return 0;
}

In the above, "|-------" represents a tab using the default :set tabstop=8. Entering :set tabstop=4 makes the code appear as:

int sample(int a)
{
|---int   count;      // variable names are aligned
|---float average;    // (some people like it this way)
|---if (a > 0)
|---|---return 1;
|---return 0;
}

This illustrates that using tabs for indentation and spaces for alignment keeps the alignment unchanged when the tabstop is altered (for lines with the same indent).

Using tabs for indentation

If you want to use only tabs for indentation (not spaces), enter the following command (replace 4 with your preferred column width for each indent level):

:set noet ci pi sts=0 sw=4 ts=4

The previous line is an abbreviated equivalent of these commands:

:set noexpandtab
:set copyindent
:set preserveindent
:set softtabstop=0
:set shiftwidth=4
:set tabstop=4

However, note that in the case of continuation lines, some spaces may be added when the indentation is not a multiple of tabstop.

If you want the commands to affect only the current buffer, replace set with setlocal (abbreviated as setl). More information is here.

Smart tabs

The settings above use hard tabs as far as possible. To use tabs in a more "semantic" way – i.e., the number of tabs equals the indentation level – install the Smart Tabs plugin.

The plugin ensures that tabs are only used for indentation, while spaces are used everywhere else. When you press Tab in insert mode, a tab is inserted when indenting, and/or the correct number of spaces when aligning text (see continuation lines). Different people can then use whatever shiftwidth and tabstop they want (provided these two values are equal) – the end result is the same, and is displayed correctly everywhere.

You do not need a "smart" editor to display or edit smartly tabbed files – that's the whole point. The Smart Tabs plugin is just an added convenience. If your non-Vim-using collaborators remain unconvinced, pass them these pointers, whichever is appropriate: smart tabs for Emacs, and IntelliJ IDEA has a built-in "smart tabs" option.

Continuation lines

When expressions span multiple lines, you may want to line up the beginning of those lines with the beginning of the expression in the first line:

int f(int x,
      int y) {
    return g(x,
             y);
}

To make Vim format the code in this way, using four-column indentation, enter the following (use setl instead of set to affect only the current buffer):

:set noet sts=0 sw=4 ts=4
:set cindent
:set cinoptions=(0,u0,U0

Using the Smart Tabs plugin, tabs will then only be used for indenting (in the third and fourth lines), while spaces will be used for alignment:

int f(int x,
      int y) {
|---return g(x,
|---         y);
}

That makes the alignment of "x" and "y" independent of tabstop.

See also

Comments

This edit added copyindent and preserveindent to the #Using tabs for indentation section. I do not understand the benefit of these in that section which asserts that only tabs will be used for indentation. These options should be mentioned somewhere (here or in Indenting source code), but possibly not in that section. Any thoughts? JohnBeckett 22:23, March 8, 2010 (UTC)

Those options are useful for preserving manually created indentation, which is useful for using tabs for the indent (automatic) and then manually adding spaces to align stuff. --Fritzophrenic (talk) 16:18, March 4, 2015 (UTC)

Hi, do I need the Smart Tabs plugin to get the behaviour like "Indent_with_tabs,_align_with_spaces"? Because first you say :set noet ci pi sts=0 sw=4 ts=4 to use only tabs for indentation (not spaces), which implicitly means spaces for aligning, no?

Later you say I need the Smart Tabs plugin because

The plugin ensures that tabs are only used for indentation, while spaces are used everywhere else.

. Massimo.b 2015-03-04

Without Smart Tabs, Vim can insert tabs for indentation for you, but you will need to manually add spaces to do alignment past the indentation. The copyindent/preserveindent settings let Vim automatically copy that manual alignment for the next line, but the space-based alignment is still a manual step. And pressing Tab will always insert a tab with this setup, it will never insert any spaces, so it will take more keypresses to insert large amounts of alignment whitespace. With Smart Tabs, if I understand correctly what the plugin does, the plugin will automatically figure out whether you are adding indentation or alignment whitespace, and insert a space or tab accordingly. --Fritzophrenic (talk) 16:18, March 4, 2015 (UTC)