Is it possible to convert tabs to spaces, while maintaining text alignment?
Simply replacing only works usefully when there are no leading characters.
You can use the :retab
command. From
:help :retab
Replace all sequences of white-space containing a
<Tab>
with new strings of white-space using the new tabstop value given. If you do not specify a new tabstop size or it is zero, Vim uses the current value of'tabstop'
. [...] With'expandtab'
on, Vim replaces all tabs with the appropriate number of spaces.
Note that the command accepts a range, so you can make a visual selection and
then just :retab
the selected lines.
Vim provides :retab!
command which will replace all sequences of <Tab>
with new strings of white-space using the new tabstop (e.g. :set tabstop=2
) value given, but all tabs inside of strings can be modified (e.g. in a C program, you should use \t
to avoid this)!
So alternatively you can change all tabs into spaces using the following command:
:%s/\t/ /g
or as suggested by @Shahbaz:
:%s/^\t\+/ /g
So only the tabs used in indentation are converted.
Note: there is a subtle difference between both commands. The first one will replace each Tab character by two spaces, the second one replace any number of leading Tab characters in a line by a single space.
Explanation:
%
represents the entire buffer/file (:help :%
)s
stands for substitute (:help sub-replace-special
)\t
, or ^I
stands for tab
- use as many spaces as you need per one tabg
- stands for global, and it'll convert multiple occurences of tabs in the same lineThen to correct indentation of the entire file, you may try: gg=G. Check: Re-indenting badly indented code for more details.
To use spaces by default instead of tabs, you need to add the following settings into your .vimrc
file:
set tabstop=2 " (ts) width (in spaces) that a <tab> is displayed as
set expandtab " (et) expand tabs to spaces (use :retab to redo entire file)
set shiftwidth=2 " (sw) width (in spaces) used in each step of autoindent (aswell as << and >>)
Alternative solution is to use tidy
Related:
%s/^\t\+/ g
so that only the tabs used in indentation are converted. Also, gg=G
could be catastrophic with languages like python.
You can use :retab
, as stated, however, this will change all tabs to spaces, not only tabs at the start of the line
So this (where ⇥
is a tab character):
if :; do
⇥echo "⇥hello"
end
gets changed to (where ␣
is a space character):
if :; do
␣␣echo "␣␣hello"
end
This can produce unexpected side-effects in some scenarios, and it's even more of an issue when changing spaces to tabs!
So, I wrote a little function to change only tabs/spaces at the start of the line:
" :retab changes *everything*, not just start of lines
fun! Retab(expandtab)
let l:spaces = repeat(' ', &tabstop)
" Replace tabs with spaces
if a:expandtab
silent! execute '%substitute#^\%(' . l:spaces . '\)\+#\=repeat("\t", len(submatch(0)) / &tabstop)#e'
" Replace spaces with tabs
else
silent! execute '%substitute#^\%(\t\)\+#\=repeat("' . l:spaces . '", len(submatch(0)))#e'
endif
endfun
With this version, you have to manually specify expandtab
in the function call
(ie. :call Retab(1)
to change tabs to spaces), but you could also modify it
to take the current value of &expandtab
(as it already does with &tabstop
)
just like :retab
does. (I happen to prefer to specify it manually).
Try using:
expand -t 4 input_filename output_filename
expand
is a command-line tool to convert tabs to spaces, which you can run from a shell or with :!expand
.
It's in POSIX so it should be available on most systems. unexpand
will do the reverse, by the way.
:%!expand -t 4
inside of vim. Better yet, you could also use the current shift width option: :exe '%!expand -t ' . &shiftwidth
Commented
Feb 1, 2016 at 21:29
For completeness, =
could also be used to fix indentations, after you have specified that tabs are replaced with spaces. In normal mode, you can do so by typing :set expandtab
. Then =
could be used in two ways:
=
would fix indentations of selected code blocks. gg=G
would fix the entire file, where gg
moves the cursor to the beginning of the file, then =
is applied, and G
moves the cursor to the end of the file. Reference: link
:h vim-faq
and search/tab characters
. The hard to memorize tag is:h faq-14.16
.