I have this texts

drwxr-xr-x  enan    enan    Jan 15  16:10   Desktop/
drwxr-xr-x  enan    enan    Jan 16  20:09   Documents/
drwxr-xr-x  enan    enan    Jan 20  19:52   Downloads/
drwxr-xr-x  enan    enan    Nov 3   20:44   Music/
drwxr-xr-x  enan    enan    Jan 17  20:21   Pictures/
drwxr-xr-x  enan    enan    Jan 20  20:10   Videos/

The spaces separating the columns are tabs. How could I replace these tabs with appropriate number of spaces so that the columns are arranged just like above, thus not altered at all.

I currently do this with :set et | '<,'> retab! | set noet after selecting the block visually, so that '< and '> marks are set.

But I came across these commands which are supposed to replace tabs at the beginning of a line to spaces, but I can't understand what it's doing. I think I could change this to do the above task with one substitution, although a complicated one.

The commands:

command! -range=% -nargs=0 Tab2Space
            \ execute '<line1>,<line2>s#^\t\+#\=repeat(" ", len(submatch(0))*' . &ts . ')'

Okay, so you want that command broken down? Here you go....

 command! -range=% -nargs=0 Tab2Space

Creates a custom command named "Tab2Space" that takes no arguments and operates on a range of lines which by default will be from first line to last line.

        \ execute '<line1>,<line2>s#^\t\+#\=repeat(" ", len(submatch(0))*' . &ts . ')'

The command just encompasses a regular substitution command that operates on the aforementioned range of lines (i.e. either the start and end lines specified by the caller or the entire file)

The pattern to match is ^\t\+ which is "one or more tabs at the start of the line".

The substitution starts with \= which means everything beyond that will be evaluated as a Vim expression and the result is what gets substituted.


This gives us the character length of whatever was matched on the current line by the pattern. In this case it means we get a count of the number of tabs at the start of the line.

The * that follows is multiplication operator and after that we look at the value of the 'ts' ('tabstop') setting with &ts. So we multiply number of tabs at the beginning of the line by the number of configured spaces per tab.

All of that is surrounded by repeat(" ", ....) which means the substitution string is N spaces where N = (number of tabs x tabstop length)

tl;dr For each line in the range of lines passed to it, the command replaces each tab at the beginning of the line with a number of spaces equal to the value stored in 'tabstop'

It sound like you want to use this with the '< and '> marks...which should work just fine.


Have you tried :h retab ?

Basically you have to have set expandtab in your vimrc (or set manually) and just issue


And all you tabs should be replaced with appropriate number of spaces.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.