Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easily aligning characters after whitespace in vim

I would like to create a mapped vim command that helps me align assignments for variables across multiple lines. Imagine I have the following text in a file:

foo                     = 1;
barbar            = 2;
asdfasd    = 3;
jjkjfh                = 4;
baz              = 5;

If I select multiple lines and use the regex below, noting that column 10 is in the whitespace for all lines, stray whitespace after column 10 will be deleted up to the equals sign.

:'<,'>s/^\(.\{10}\)\s*\(=.*\)$/\1\2/g

Here's the result:

foo       = 1;
barbar    = 2;
asdfasd   = 3;
jjkjfh    = 4;
baz       = 5;

Is there a way to get the current cursor position (specifically the column position) while performing a visual block selection and use that column in the regular expression?

Alternatively, if it is possible to find the max column for any of the equals signs on the selected lines and insert whitespace so all equals signs are aligned by column, that is preferred to solving the previous problem. Imagine quickly converting:

foo = 1;
barbar = 2;
asdfasd = 3;
jjkjfh = 4;
baz = 5;

to:

foo     = 1;
barbar  = 2;
asdfasd = 3;
jjkjfh  = 4;
baz     = 5;

with a block selection and a key-combo.

like image 226
chardson Avatar asked Jan 26 '13 16:01

chardson


2 Answers

Without plugins

In this case

foo = 1
fizzbuzz = 2
bar = 3

You can add many spaces with a macro:

0f=10iSPACEESCj

where 10 is an arbitrary number just to add enough space.

Apply the macro M times (for M lines) and get

foo           = 1
fizzbuzz           = 2
bar           = 3

Then remove excessive spaces with a macro that removes all characters till some column N:

0f=d12|j

where 12 is the column number you want to align along and | is a vertical bar (SHIFT + \). Together 12| is a "go to column 12" command.

Repeat for each line and get

foo        = 1
fizzbuzz   = 2
bar        = 3

You can combine the two macros into one:

0f=10iSPACEESCd11|j

like image 170
Anton Tarasenko Avatar answered Oct 19 '22 15:10

Anton Tarasenko


Not completely satisfied with Tabular and Align, I've recently built another similar, but simpler plugin called vim-easy-align.

Check out the demo screencast: https://vimeo.com/63506219

For the first case, simply visual-select the lines and enter the command :EasyAlign= to do the trick.

If you have defined a mapping such as,

vnoremap <silent> <Enter> :EasyAlign<cr>

you can do the same with just two keystrokes: Enter and =

The case you mentioned in the comment,

final int foo = 3;
public boolean bar = false;

can be easily aligned using ":EasyAlign*\ " command, or with the aforementioned mapping, Enter, *, and space key, yielding

final  int     foo = 3;
public boolean bar = false;
like image 29
Junegunn Choi Avatar answered Oct 19 '22 17:10

Junegunn Choi