0

Using VIM on Ubuntu 20.04.2. I would like to clean up the white spaces automatically upon opening or saving a file with VIM.

Create a file full of white spaces to clean up:

printf "if (denom != 0)  \t \n{     \n\tresult = num / denom\n\treturn result  \t  \n} \t\t   \n" > ./needcleanup.txt

Open the file by VIM

vim ./needcleanup.txt

I would like to perform the following actions automatically when opening or saving a file (regardless of file type):

  • replace all \t with two spaces
  • delete all trailing spaces

Looking at basic.vim, in github.com/amix/vimrc it looks like the idea is feasible. Hope you can give some guidelines. I am OK with programming, regex, bash. But sadly don't know VIM.

2
  • 1
    Just a caveat: You might want to restrict replacing tabs with spaces on every open/save a bit. There are cases where tabs have a syntactic meaning, like Makefile. Also if you work on other peoples code, they might get upset breaking their layout that works for them. Always check contribution guides. I also highly recommend to watch the first episodes of Vimcasts about handling whitespace in VIM vimcasts.org/episodes/archive – okket Feb 15 at 4:10
  • @okket Oups make sense. But fortunately in my case this is not a problem. Maybe the better solution would be to make the whitespace cleanup to be callable on demand. Like Ctrl-Alt-L or something like that. But for now I am happy with what I got. – Polymerase Feb 15 at 5:17
1

This is quite easy thanks to auto commands. They allow you to specify vimscript to be run when certain events occur in Vim. There are event types for many different things that happen in Vim including loading and exiting/saving a buffer (file).

You'll need something like this in your vimrc.

augroup SpaceFix
  autocmd!
  autocmd BufReadPost,BufWritePre * :silent %s/\s\+$//ge | :silent %s/\t/  /ge
augroup END

The surrounding augroup bits aren't strictly necessary but, along with autocmd! which deletes existing auto commands from the containing group, prevent doubly defining auto commands if you reload your vimrc.

The main line has two events which, from what I am reading in your question, match the occurrences you specified. The following * indicates that this should be applied for all file types. And following that are two basic substitution commands for deleting trailing space and converting tabs. The pipe character | is used to separate different commands from each other. The optional but desirable :silent prefixes prevent both the appearance of X substitutions on Y lines and the inconvenient necessity of a tap on Return.

One thing that might not be familiar is the e flag after each substitution. This suppresses errors such as if you don't actually have anything to be substituted in a file.

Update: @Mass mentioned something noteworthy in a comment. The substitution commands will add their patterns to your search history and since this happens for each file load and save you might be bothered by it. If so, :keeppatterns will prevent it. Insert keepp before each substitution, e.g. :keepp %s/\s ..etc...

10
  • better to add keeppatterns – Mass Feb 14 at 18:41
  • @Mass Personally I wouldn't add it as wouldn't be much bother to me. But I'll certainly note it so people have the option. Thanks. – B Layer Feb 14 at 18:54
  • I think \t will do for tab, but maybe vim doesnt have it and I’m remembering wrong – D. Ben Knoble Feb 14 at 21:18
  • Wonderful thanks. Does VIM has its regex dialect? More exactly, is there any need to escape the + in \s+$ ? and can I hope I can use \t for the TAB char. Like this in cmd line: printf "\t\t1tab=2tildes\n" | sed "s/\t/~~/g" – Polymerase Feb 15 at 0:28
  • I addressed a couple of your issues/questions. Run the updated version and let me know if you have any left. And yes, vim regex requires escaping of + unless you use "very magic mode" (I leave the research for that one to you). – B Layer Feb 15 at 1:40

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.