Vim Tips Wiki
(Move categories to tip template)
No edit summary
(13 intermediate revisions by 8 users not shown)
Line 1: Line 1:
{{review}}
 
 
{{TipImported
 
{{TipImported
 
|id=12
 
|id=12
|previous=11
+
|previous=10
|next=13
+
|next=14
|created=February 24, 2001
+
|created=2001
 
|complexity=basic
 
|complexity=basic
 
|author=Yegappan
 
|author=Yegappan
Line 12: Line 11:
 
|category2=
 
|category2=
 
}}
 
}}
  +
==Settings==
To insert space characters whenever the tab key is pressed, set the 'expandtab' option:
+
To insert space characters whenever the tab key is pressed, set the <code>'expandtab'</code> option:
:set expandtab
 
  +
<pre>
 
:set expandtab
  +
</pre>
   
With this option set, if you want to enter a real tab character use Ctrl-V&lt;Tab&gt; key sequence.
+
With this option set, if you want to enter a real tab character use Ctrl-V<Tab> key sequence.
   
 
To control the number of space characters that will be inserted when the tab key is pressed, set the 'tabstop' option. For example, to insert 4 spaces for a tab, use:
 
To control the number of space characters that will be inserted when the tab key is pressed, set the 'tabstop' option. For example, to insert 4 spaces for a tab, use:
  +
<pre>
:set tabstop=4
+
:set tabstop=4
  +
</pre>
   
After the 'expandtab' option is set, all the new tab characters entered will be changed to spaces. This will not affect the existing tab characters. To change all the existing tab characters to match the current tab settings, use
+
After the <code>'expandtab'</code> option is set, all the new tab characters entered will be changed to spaces. This will not affect the existing tab characters. To change all the existing tab characters to match the current tab settings, use:
  +
<pre>
:retab
+
:retab
  +
</pre>
   
 
To change the number of space characters inserted for indentation, use the 'shiftwidth' option:
 
To change the number of space characters inserted for indentation, use the 'shiftwidth' option:
  +
<pre>
:set shiftwidth=4
+
:set shiftwidth=4
  +
</pre>
   
 
For example, to get the following coding style,
 
For example, to get the following coding style,
*No tabs in the source file
+
*No tabs in the source file.
*All tab characters are 4 space characters
+
*All tab characters are 4 space characters.
   
 
use the following set of options:
 
use the following set of options:
  +
<pre>
:set tabstop=4
 
:set shiftwidth=4
+
:set tabstop=4
:set expandtab
+
:set shiftwidth=4
 
:set expandtab
  +
</pre>
  +
  +
or as a oneliner:
  +
  +
<pre>
 
:set tabstop=4 shiftwidth=4 expandtab
  +
</pre>
  +
  +
 
Add the above settings to your [[vimrc]].
  +
  +
==Adjusting indent==
  +
Since tabs effectively group spaces together, you may be tempted to work with tabs rather than spaces and change individual lines selectively. To easily change a tab-based indent to use spaces instead when 'noexpandtab' is set, you can temporarily set 'expandtab' and use <code>:retab</code> with a range. For example, to convert only the current line to use spaces, use <code>:.retab</code>.
  +
  +
However, Vim makes working with spaces for [[Indenting source code|indentation]] just as easy as working with tabs. Just use the {{help|prefix=no|<}} and {{help|prefix=no|>}} operators to quickly indent/de-indent lines or visual selections.
   
  +
==See also==
Add the above settings to your .vimrc file.
 
  +
*[[VimTip1592|Super retab]] to change only indents (whitespace at left margin)
  +
*[[VimTip396|Highlight unwanted spaces]] to display unwanted whitespace
   
 
==References==
 
==References==
Line 44: Line 70:
   
 
==Comments==
 
==Comments==
  +
To turn off expandtab for editing makefiles, put the following in your vimrc:
I use this to highlight tabs and trailing spaces:
 
 
<pre>
 
<pre>
 
autocmd FileType make setlocal noexpandtab
set list listchars=tab:»·,trail:·
 
 
</pre>
 
</pre>
   
 
----
 
----
To turn off expandtab for editing makefiles, I put the following in my .vimrc:
+
To use this mode only for Python add the following to your vimrc:
  +
<pre>
au FileType make setlocal noexpandtab
 
 
autocmd FileType * set tabstop=2|set shiftwidth=2|set noexpandtab
  +
autocmd FileType python set tabstop=4|set shiftwidth=4|set expandtab
  +
</pre>
   
 
----
 
----
 
This is what I use for Python:
To use this mode only for python add the following to ~/.vimrc
 
  +
<pre>
autocmd FileType * set tabstop=2|set shiftwidth=2|set noexpandtab
 
autocmd FileType python set tabstop=4|set shiftwidth=4|set expandtab
+
autocmd BufEnter *.py set ai sw=4 ts=4 sta et fo=croql
  +
</pre>
   
 
----
 
----
 
I also add the following line:
 
I also add the following line:
  +
<pre>
set softtabstop=4 " makes the spaces feel like real tabs
+
set softtabstop=4 " makes the spaces feel like real tabs
  +
</pre>
   
 
This makes the backspace key treat the four spaces like a tab (so one backspace goes back a full 4 spaces).
 
This makes the backspace key treat the four spaces like a tab (so one backspace goes back a full 4 spaces).
  +
 
----
 
It is possible to get vim to insert at the "true" start of the line with soft tabs, if you have:
  +
<pre>
 
set softtabstop=4
  +
</pre>
   
 
----
 
----
 
I change these so frequently that I have keystrokes bound to switch between them:
 
I change these so frequently that I have keystrokes bound to switch between them:
  +
<pre>
 
" That awful mixed mode with the half-tabs-are-spaces:
 
map \M <Esc>:set noexpandtab tabstop=8 softtabstop=4 shiftwidth=4<CR>
   
  +
" Mini tabs, small "m":
" That awful mixed mode with the half-tabs-are-spaces:
 
map \M &lt;Esc&gt;:set noexpandtab tabstop=8 softtabstop=4 shiftwidth=4&lt;CR&gt;
+
map \m <Esc>:set expandtab tabstop=2 shiftwidth=2<CR>
   
" Mini tabs, small "m":
+
" Think "little tabs" and "big tabs":
map \m &lt;Esc&gt;:set expandtab tabstop=2 shiftwidth=2&lt;CR&gt;
+
map \t <Esc>:set expandtab tabstop=4 shiftwidth=4<CR>
  +
map \T <Esc>:set expandtab tabstop=8 shiftwidth=8<CR>
 
  +
</pre>
" Think "little tabs" and "big tabs":
 
map \t &lt;Esc&gt;:set expandtab tabstop=4 shiftwidth=4&lt;CR&gt;
 
map \T &lt;Esc&gt;:set expandtab tabstop=8 shiftwidth=8&lt;CR&gt;
 
 
----
 
It is possible to get vim to insert at the "true" start of the line with soft tabs, if you have:
 
set softtabstop=4
 
   
 
----
 
----
 
I use this to insert spaces at the beginning of a line and real tab characters elsewhere:
 
I use this to insert spaces at the beginning of a line and real tab characters elsewhere:
  +
<pre>
 
inoremap <Silent> <Tab> <C-R>=(col('.') > (matchend(getline('.'), '^\s*') + 1))?'<C-V><C-V><Tab>':'<Tab>'<CR>
  +
</pre>
   
 
If you're trying to figure out how it works and are confused by the <C-V><C-V><Tab> thing: <C-R>= asks for an expression, and the expression is entered as if it was typed, then the return value of the expression is inserted as if it too was typed - so, we want to insert <C-V><Tab>, but if we just entered that into the expression, it would be converted to <Tab> before the expression is executed - so, we have to enter <C-V><C-V><Tab> into the expression, which will be converted to <C-V><Tab> before the expression is executed, which will then become <Tab> in the actual file.
inoremap &lt;silent&gt; &lt;Tab&gt; &lt;C-R&gt;=(col('.') &gt; (matchend(getline('.'), '^\s*') + 1))?'&lt;C-V&gt;&lt;C-V&gt;&lt;Tab&gt;':'&lt;Tab&gt;'&lt;CR&gt;
 
 
If you're trying to figure out how it works and are confused by the &lt;C-V&gt;&lt;C-V&gt;&lt;Tab&gt; thing: &lt;C-R&gt;= asks for an expression, and the expression is entered as if it was typed, then the return value of the expression is inserted as if it too was typed - so, we want to insert &lt;C-V&gt;&lt;Tab&gt;, but if we just entered that into the expression, it would be converted to &lt;Tab&gt; before the expression is executed - so, we have to enter &lt;C-V&gt;&lt;C-V&gt;&lt;Tab&gt; into the expression, which will be converted to &lt;C-V&gt;&lt;Tab&gt; before the expression is executed, which will then become &lt;Tab&gt; in the actual file.
 
   
 
I also remapped Shift-Tab so I could easily insert real tabs at the beginning of the line when necessary:
 
I also remapped Shift-Tab so I could easily insert real tabs at the beginning of the line when necessary:
  +
<pre>
inoremap &lt;S-Tab&gt; &lt;C-V&gt;&lt;Tab&gt;
+
inoremap &lt;S-Tab> <C-V><Tab>
  +
</pre>
   
 
----
 
----
or (surely there is a better way???):
+
Or (surely there is a better way?):
  +
<pre>
" make tab do tabs at beginning and spaces elsewhere
+
" make tab do tabs at beginning and spaces elsewhere
function VaryTabs()
+
function VaryTabs()
if &expandtab
 
  +
if &expandtab
 
return "\<Tab>"
  +
else
  +
let nonwhite = matchend(getline('.'),'\S')
  +
if nonwhite < 0 || col('.') <= nonwhite
 
return "\<Tab>"
 
return "\<Tab>"
 
else
 
else
let nonwhite = matchend(getline('.'),'\S')
+
let pos = virtcol('.')
if nonwhite < 0 || col('.') <= nonwhite
+
let num = pos + &tabstop
 
let num = num - (num % &tabstop) - pos +1
return "\<Tab>"
 
else
+
return repeat(" ",num)
let pos = virtcol('.')
 
let num = pos + &tabstop
 
let num = num - (num % &tabstop) - pos +1
 
return repeat(" ",num)
 
endif
 
 
endif
 
endif
 
endif
endfunction
+
endfunction
inoremap <Tab> <C-R>=VaryTabs()<CR>
+
inoremap <Tab> <C-R>=VaryTabs()<CR>
 
  +
</pre>
 
----
 
This is what I use for python
 
au BufEnter *.py set ai sw=4 ts=4 sta et fo=croql
 
   
  +
Nice plugin: {{script|id=2308}}
 
----
 
----

Revision as of 13:31, 16 November 2013

Tip 12 Printable Monobook Previous Next

created 2001 · complexity basic · author Yegappan · version 5.7


Settings

To insert space characters whenever the tab key is pressed, set the 'expandtab' option:

:set expandtab

With this option set, if you want to enter a real tab character use Ctrl-V<Tab> key sequence.

To control the number of space characters that will be inserted when the tab key is pressed, set the 'tabstop' option. For example, to insert 4 spaces for a tab, use:

:set tabstop=4

After the 'expandtab' option is set, all the new tab characters entered will be changed to spaces. This will not affect the existing tab characters. To change all the existing tab characters to match the current tab settings, use:

:retab

To change the number of space characters inserted for indentation, use the 'shiftwidth' option:

:set shiftwidth=4

For example, to get the following coding style,

  • No tabs in the source file.
  • All tab characters are 4 space characters.

use the following set of options:

:set tabstop=4
:set shiftwidth=4
:set expandtab

or as a oneliner:

:set tabstop=4 shiftwidth=4 expandtab


Add the above settings to your vimrc.

Adjusting indent

Since tabs effectively group spaces together, you may be tempted to work with tabs rather than spaces and change individual lines selectively. To easily change a tab-based indent to use spaces instead when 'noexpandtab' is set, you can temporarily set 'expandtab' and use :retab with a range. For example, to convert only the current line to use spaces, use :.retab.

However, Vim makes working with spaces for indentation just as easy as working with tabs. Just use the < and > operators to quickly indent/de-indent lines or visual selections.

See also

References

Comments

To turn off expandtab for editing makefiles, put the following in your vimrc:

autocmd FileType make setlocal noexpandtab

To use this mode only for Python add the following to your vimrc:

autocmd FileType * set tabstop=2|set shiftwidth=2|set noexpandtab
autocmd FileType python set tabstop=4|set shiftwidth=4|set expandtab

This is what I use for Python:

autocmd BufEnter *.py set ai sw=4 ts=4 sta et fo=croql

I also add the following line:

set softtabstop=4 " makes the spaces feel like real tabs

This makes the backspace key treat the four spaces like a tab (so one backspace goes back a full 4 spaces).


It is possible to get vim to insert at the "true" start of the line with soft tabs, if you have:

set softtabstop=4

I change these so frequently that I have keystrokes bound to switch between them:

" That awful mixed mode with the half-tabs-are-spaces:
map \M <Esc>:set noexpandtab tabstop=8 softtabstop=4 shiftwidth=4<CR>

" Mini tabs, small "m":
map \m <Esc>:set expandtab tabstop=2 shiftwidth=2<CR>

" Think "little tabs" and "big tabs":
map \t <Esc>:set expandtab tabstop=4 shiftwidth=4<CR>
map \T <Esc>:set expandtab tabstop=8 shiftwidth=8<CR>

I use this to insert spaces at the beginning of a line and real tab characters elsewhere:

inoremap <Silent> <Tab> <C-R>=(col('.') > (matchend(getline('.'), '^\s*') + 1))?'<C-V><C-V><Tab>':'<Tab>'<CR>

If you're trying to figure out how it works and are confused by the <C-V><C-V><Tab> thing: <C-R>= asks for an expression, and the expression is entered as if it was typed, then the return value of the expression is inserted as if it too was typed - so, we want to insert <C-V><Tab>, but if we just entered that into the expression, it would be converted to <Tab> before the expression is executed - so, we have to enter <C-V><C-V><Tab> into the expression, which will be converted to <C-V><Tab> before the expression is executed, which will then become <Tab> in the actual file.

I also remapped Shift-Tab so I could easily insert real tabs at the beginning of the line when necessary:

inoremap <S-Tab> <C-V><Tab>

Or (surely there is a better way?):

" make tab do tabs at beginning and spaces elsewhere
function VaryTabs()
  if &expandtab
    return "\<Tab>"
  else
    let nonwhite = matchend(getline('.'),'\S')
    if nonwhite < 0 || col('.') <= nonwhite
      return "\<Tab>"
    else
      let pos = virtcol('.')
      let num = pos + &tabstop
      let num = num - (num % &tabstop) - pos +1
      return repeat(" ",num)
    endif
  endif
endfunction
inoremap <Tab> <C-R>=VaryTabs()<CR>

Nice plugin: script#2308