Reputation: 12431
After reading Vim regex replace with n characters, I've known how to replace tabs by spaces:
:%s/^\v(\t)*/\=repeat(repeat(' ',4),strlen(submatch(0)))/g
The command above allows me to replace n tabs at the beginning of each line with n four-spaces.
Now I want to inverse it: replace n four-spaces with n tabs at the beginning of each line, I think the command should be :%s/^\v( )*/\=repeat("\t",strlen(submatch(0)))/g
, but it doesn't work: if there is one four-space, it will be replaced by four tabs (but I want to make it only one tab) after executing the command.
Besides, is it possible to get the length of tab of vim so that I can make the command as below?
:%s/^\v(\t)*/\=repeat(repeat(' ',getSizeOfTab()),strlen(submatch(0)))/g
Upvotes: 1
Views: 66
Reputation: 198556
You can get the value of an option in Vimscript by prepending &
. So, the size of tab is &tabstop
, or &ts
. There's also &softtabstop
(&sts
), pick which one you actually care about.
Whereas you needed to multiply the number of spaces with size of tab, you need to divide the number of tabs. Then there's the remainder to take care of. So, first set your tabstop
:
:set ts=4
Then you can convert from tabs to spaces and from spaces to tabs like this:
:%s/^\v(\t)*/\=repeat(repeat(' ',&ts),strlen(submatch(0)))/g
:%s#^\v( )*#\=repeat("\t",strlen(submatch(0))/&ts).repeat(' ',strlen(submatch(0))%&ts)#g
(changed the separator from /
to #
because I needed /
for division :P )
However... it seems you're reinventing the wheel here. :help :retab!
and :help 'expandtab'
. First set tabstop
as above, then:
:set et | ret!
:set noet | ret!
The first one will change tabs to spaces; the second one, spaces to tabs, according to tabstop
.
Upvotes: 1