7

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})+

Francis Lewis
  • 8,872
  • 9
  • 55
  • 65
  • Are you certain you haven't already replaced all of the beginning spaces with tabs? Are you using the original file, or the modified file (or buffer) in which you already ran `:set noet|retab!`? – gotgenes Mar 02 '11 at 20:27
  • Ok, so that is the issue, that I don't have any spaces to replace. Shouldn't there be a modifier to ignore if no matches are found? – Francis Lewis Mar 02 '11 at 20:34
  • 1
    see also http://stackoverflow.com/questions/5144284/force-vi-vim-to-use-leading-tabs-only-on-retab – wimh Jun 07 '11 at 11:35

2 Answers2

9

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.

Francis Lewis
  • 8,872
  • 9
  • 55
  • 65
0

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
ethoms
  • 1
  • 1