Francis Lewis
Francis Lewis

Reputation: 8980

Vim retab spaces at the beginning of lines only

I'm currentling using

:set noet|retab!

But the problem I'm running into is it's replacing all instances of 4 spaces to tabs throughout the entire file. I need vim to only replace instances of 4 spaces at the beginning of lines only.

If I remove the ! at the end of retab, spaces are not replaced anywhere.

I've tried using a custom function that somebody created:

" Retab spaced file, but only indentation
command! RetabIndents call RetabIndents()

" Retab spaced file, but only indentation
func! RetabIndents()
    let saved_view = winsaveview()
    execute '%s@^\( \{'.&ts.'}\)\+@\=repeat("\t", len(submatch(0))/'.&ts.')@'
    call winrestview(saved_view)
endfunc

but I get a nice little error message when I run:

:RetabIndents

Error detected while processing function RetabIndents:

line 2:

E486: Pattern not found: ^( {4})+

Upvotes: 7

Views: 3051

Answers (2)

ethoms
ethoms

Reputation: 1

I use a different method to change spaces to tabs at beginning of my shell scripts. I just use sed from the command line.

Using BSD sed:

sed -i "" -e ':loop' -e "s/^\([ ]*\)  /\1   /" -e 't loop' somefile.sh

*note: (i) the character in the square brackets is a tab character (ii) the character aftger the /\1 is also a tab character. Both tabs cgharacters are entered in the terminal using Ctrl+v+Tab key combination.

Using GNU sed:

sed -i -e ':loop' -e 's/^\([\t]*\)  /\1\t/' -e 't loop' somefile.sh

Upvotes: 0

Francis Lewis
Francis Lewis

Reputation: 8980

After talking with some other people about this, I needed to add the silent! command before execute. So this is what I have working now:

autocmd BufWritePre * :RetabIndents
command! RetabIndents call RetabIndents()

func! RetabIndents()
    let saved_view = winsaveview()
    execute '%s@^\(\ \{'.&ts.'\}\)\+@\=repeat("\t", len(submatch(0))/'.&ts.')@e'
    call winrestview(saved_view)
endfunc

So now this function will automatically replace spaces with tabs at the beginning of each line only.

Upvotes: 9

Related Questions