ChatGPT解决这个技术问题 Extra ChatGPT

Replace tabs with spaces in vim

I would like to convert tab to spaces in gVim. I added the following line to my _vimrc:

set tabstop=2

It works to stop at two spaces but it still looks like one tab key is inserted (I tried to use the h key to count spaces afterwards).

I'm not sure what should I do to make gVim convert tabs to spaces?

Personally, I'd find tabstop=2 too small an indent; I use ts=4, and understand why people (such as the Linux kernel team) use ts=8 (and they don't use expandtab - I do).
Is there a way to convert spaces to tabs inside vim?
@cwd replacing the spaces with tab character ( ^I which come from Ctrl-v then Tab ) would works, for example if your current tabs is 4 spaces: :%s/ /^I/g

D
Daniel Hershcovich

Once you've got expandtab on as per the other answers, the extremely convenient way to convert existing files according to your new settings is:

:retab

It will work on the current buffer.


but how can we make retab ask confirmation of each occurrence of TAB?
And being Vim, it works on visually selected regions too :)
Thanks for teach me a new thing. I've use the tedious :%s/\t/ /g for years before seeing your comment.
You can even do :args retab | w to do to all files opened on the command line, e.g., vim *.txt.
Does anyone know which version of vim has :retab? My 7.3.322 doesn't.
S
Shyam Habarakada

IIRC, something like:

set tabstop=2 shiftwidth=2 expandtab

should do the trick. If you already have tabs, then follow it up with a nice global RE to replace them with double spaces.

If you already have tabs you want to replace,

:retab

Oops, that's ":%!expand -t2"
or you can just use :retab
what if i want to save it with spaces ? right now when I :wq and open the file again i am back to tabs
@Gorkem put these commands into your .vimrc, so that vim uses those settings every session
What this all means, is nicely explained on the Vim wiki.
H
Hank Gay

Try

set expandtab

for soft tabs.

To fix pre-existing tabs:

:%s/\t/  /g

I used two spaces since you already set your tabstop to 2 spaces.


That fix up will insert two spaces where only one is required.
instead of doing the substitution, you can do what Nick suggested above - ie retab. That will retab all your existing tabs as the number of spaces set in your tabstop.
Awesome tip! Vim showed me a perfectly idented file while cat (linux cmd) showed irregular identation. I just changed the 2 spaces to 4 as I use in Vim set ts = 4.
s
serup

This worked for me:

you can see tabs with first doing this:

:set list

then to make it possible to replace tabs then do this:

:set expandtab

then

:retab

now all tabs have been replaced with spaces you can then go back to normal viewing like this :

:set nolist

:set list is just beautiful.
J
Jake Sellers

gg=G will reindent the entire file and removes most if not all the tabs I get in files from co-workers.


does it replace tabs with spaces?
Awesome! Worked for me as well.
Can you explain what gg=G do? this did exactly what i was looking for. I have html on sublime and when i pasted it in vim, it was madly indented. This now looks clean.
@jes516 gg moves your cursor to the beginning of the buffer. = is format, and takes a movement command. G moves your cursor the end of the buffer, so it tells vim to format from the beginning to the end of your current buffer.
s
sth

Add following lines to your .vimrc

set expandtab
set tabstop=4
set shiftwidth=4
map <F2> :retab <CR> :wq! <CR>

Open a file in vim and press F2 The tabs will be converted to 4 spaces and file will be saved automatically.


It's probably worth noting that the q will close the current buffer of the file as well. This may or may not be desired.
p
pk.

If you want to keep your \t equal to 8 spaces then consider setting:

   set softtabstop=2 tabstop=8 shiftwidth=2

This will give you two spaces per <TAB> press, but actual \t in your code will still be viewed as 8 characters.


Thanks for mentioning softtabstop, one of the killer features, I think.
W
Willem van Ketwich

This got it working for me:

:set tabstop=2 shiftwidth=2 expandtab | retab

Thanks for the tip on :retab. I added that to the accepted answer so no one misses on that important piece :-)
C
Community

This article has an excellent vimrc script for handling tabs+spaces, and converting in between them.

These commands are provided: Space2Tab Convert spaces to tabs, only in indents. Tab2Space Convert tabs to spaces, only in indents. RetabIndent Execute Space2Tab (if 'expandtab' is set), or Tab2Space (otherwise). Each command accepts an argument that specifies the number of spaces in a tab column. By default, the 'tabstop' setting is used.

Source: http://vim.wikia.com/wiki/Super_retab#Script

" Return indent (all whitespace at start of a line), converted from
" tabs to spaces if what = 1, or from spaces to tabs otherwise.
" When converting to tabs, result has no redundant spaces.
function! Indenting(indent, what, cols)
  let spccol = repeat(' ', a:cols)
  let result = substitute(a:indent, spccol, '\t', 'g')
  let result = substitute(result, ' \+\ze\t', '', 'g')
  if a:what == 1
    let result = substitute(result, '\t', spccol, 'g')
  endif
  return result
endfunction

" Convert whitespace used for indenting (before first non-whitespace).
" what = 0 (convert spaces to tabs), or 1 (convert tabs to spaces).
" cols = string with number of columns per tab, or empty to use 'tabstop'.
" The cursor position is restored, but the cursor will be in a different
" column when the number of characters in the indent of the line is changed.
function! IndentConvert(line1, line2, what, cols)
  let savepos = getpos('.')
  let cols = empty(a:cols) ? &tabstop : a:cols
  execute a:line1 . ',' . a:line2 . 's/^\s\+/\=Indenting(submatch(0), a:what, cols)/e'
  call histdel('search', -1)
  call setpos('.', savepos)
endfunction

command! -nargs=? -range=% Space2Tab call IndentConvert(<line1>,<line2>,0,<q-args>)
command! -nargs=? -range=% Tab2Space call IndentConvert(<line1>,<line2>,1,<q-args>)
command! -nargs=? -range=% RetabIndent call IndentConvert(<line1>,<line2>,&et,<q-args>)

This helped me a bit more than the answers here did when I first went searching for a solution.


S
Shekar

first search for tabs in your file : /^I :set expandtab :retab

will work.


the first part could you please explain that
q
qwr

expand is a unix utility to convert tabs to spaces. If you do not want to set anything in vim, you can use a shell command from vim:

:!% expand -t8

if you just want to expand a portion of the code: first select that portion in visual mode, then press :. Now the vim command line shows :'<,'>. Then input !expand -t4 for tab to 4 space. (The resulted command line is like :'<,'>!expand -t4)
A
Andronicus

if u are using makefile or other text file, which need real tab other than some spaces, add set noexpandtab in your ~/vimrc first, or just input set noexpandtab command, when edit some file with vi(vim)