Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to normalize whitespace for block of text in vim?

Tags:

vim

Suppose I have a file (newlines marked as ^n):

aaaa^n
                        bbbb^n
cccc^n

Is there a simple command to backfill whitespace to the rightmost portion of the block (probably using a visual selection); I often see questions about removing leading whitespace, but in this case I want leading whitespace normed to the longest non-whitespace character in the block, like below:

aaaa                        ^n
                        bbbb^n
cccc                        ^n
like image 376
Kevin Lee Avatar asked Jul 25 '13 19:07

Kevin Lee


People also ask

How to remove white spaces in Vim?

One way to make sure to remove all trailing whitespace in a file is to set an autocmd in your . vimrc file. Every time the user issues a :w command, Vim will automatically remove all trailing whitespace before saving.


2 Answers

Probaly the easiest way would be to do

set virtualedit=all

Go to the top left of the block you want to select. Use a Blockwise visual selection (<C-V>) and select the the lines you want. Then hit $ to extend the visual block to the end of the line.

Then yank the selection with y

Then type gvp to past what you yanked lines back onto it self. (gv reselects the last visual block). When you are done this will extend all lines to be the length of the longest line + 1.

The reason this works. When you are using a virtual edit the visual selection is extends each line to the length the longest when putting it into the register.

This will add an extra space to the end which is easily fixable with with :%s/ $//

like image 151
FDinoff Avatar answered Sep 29 '22 23:09

FDinoff


You can do it in a single :substitute, although it does get a little involved:

:'<,'>s/$/\=repeat(' ', max(map(getline(line("'<"),line("'>")),'strdisplaywidth(v:val)'))-strdisplaywidth(getline('.')))/

This command applies to the Visual selection. If you need more control over the range, consider wrapping the substitute in a function that accepts a range.

How does it work?

  • \= in the replacement string lets you evaluate an expression: see :h sub-replace-expression.

  • The replacement is a number of padding space characters: repeat(' ', ...).

  • The exact number of space characters is determined as the difference between

    • the maximum line length in the selection, max(map(getline(start,end), 'strdisplaywidth(v:val)')), and
    • the width of the current line, strdisplaywidth(getline('.')).

Note that strdisplaywidth() is not available in older Vims, but it is necessary to handle both tabs and spaces in the line correctly. (Use strlen() as a cheap substitute.)

like image 30
glts Avatar answered Sep 29 '22 22:09

glts