16

If I have a text file like this:

alpha: 1
beta: 2
gamma: 3
delta: 4
epsilon: 5

Is there a way to align the numbers like so?:

alpha:   1
beta:    2
gamma:   3
delta:   4
epsilon: 5
3
  • See the accepted answer to vi.stackexchange.com/questions/20658/…
    – Maxim Kim
    Jul 25, 2019 at 7:22
  • 2
    @D.BenKnoble this question was asked in 2015, the one you have provide link to was asked in 2019.
    – Maxim Kim
    Jul 26, 2019 at 13:33
  • 1
    @MaximKim well aware. The question i linked has an accepted answer, however; at any rate, one of them should be closed as a dupe of the other. This seemed a more convenient way to point folks towards answers.
    – D. Ben Knoble
    Jul 26, 2019 at 13:36

7 Answers 7

10

See accepted answer to Align a block of code on the basis of a single character

To recap

  1. ggVG to select all
  2. :'<,'>normal f:5a you don't have to enter '<,'> and also note space at the end. For each line in a selection it will execute normal command to find : and add 5 spaces after it
  3. goto second space after epsilon: <here> and press <C-v> to activate block visual mode
  4. 5k to select one char column up to the first row
  5. < to dedent everything 1 time
  6. . repeat it until everything is aligned

PS

enter image description here

2
  • Instead of :normal f:5a you could also use :s/:/: /
    – Matt
    Jul 25, 2019 at 10:16
  • Indeed :s/:/: / might be used instead. (5 spaces are trimmed by formatting unfortunately)
    – Maxim Kim
    Jul 25, 2019 at 10:42
8

You can do this with the vim-lion plugin.

Install it, then place your cursor on the first line. In normal mode, type glip/. You'll be prompted to type in a pattern, so just type \d to match any digit, and press Enter. It will line up the numbers for you.

1
  • 3
    Actually, this can be done with the gL operator defined by lion.vim. This operator performs alignment by adding spaces to the right of the alignment character (instead of the left, as with the gl operator). The full command would then be gLip:.
    – tommcdo
    Feb 7, 2015 at 21:53
7

Here's a method not using any plugin. The strategy is to use tabs as a temporary column delimiter, then reformat the tabs as spaces.

  1. Start by setting :set noexpandtab (noet for short)
  2. Type the text, using the Tab key to insert a horizontal tab character after each colon. It will probably look slightly wrong, like this:

    alpha:  1
    beta:   2
    gamma:  3
    delta:  4
    epsilon:        5
    
  3. :set tabstop=9 (:set ts=9 for short) makes it look as desired:

    alpha:   1
    beta:    2
    gamma:   3
    delta:   4
    epsilon: 5
    

    However, the whitespace is actually a horizontal tab character, not spaces.

  4. To indicate that you want spaces instead of tabs, :set et. Then, :%retab to perform the tabs-to-spaces conversion.
4
  • 2
    This is less than ideal, because this just changes how tabs are visualized in vim, if someone else were to open the file in a different editor it wouldn't look as good. Feb 8, 2015 at 5:49
  • 3
    @DhruvaSagar How so? The result is exactly identical after the tabs-to-spaces conversion in step 4. Feb 8, 2015 at 6:41
  • Different editors visualize / deal with tabs differently. Feb 8, 2015 at 12:34
  • hmm ok, I guess I overlooked step #4. Sorry for that, my mistake. Feb 8, 2015 at 14:58
2

Here's another method that doesn't use any plugins.

First replace the spaces with much bigger spaces. No need to be precise: just mash the Space key a bunch of times:

:%s/ /        /

Now trim them all to be the same length:

:%norm! 10|dw

The only tricky part is knowing what count to use. For this example it's fairly easy, The longest line contains a 7 letter word: epsilon plus 2 more characters (a colon and a space), so you need to use a count of 9 + 1.

For more complicated alignments you might benefit by having your current cursor position displayed in your statusline (or by using something like getcurpos()).

Alternatively, you can just position the cursor manually on each line and use normal-mode dw by hand.

You can also use this technique in a macro:

qqf:a    <Esc>10|dw+q4@q
     └──┤
        └─ Mash space bar here
1

You can try this plugin: vim-easy-align.

1

if you're on a unix environment you could just run

%!column -t

But if you're on windows, and you have git installed, that means you could use one of the fancy unix tools installed :) Tools like grep, tee, which, and column can be found here:

%localappdata%\Programs\Git\usr\bin

Running the column command from inside Vim then looks like this:

:%!C:\Users\USERNAME\AppData\Local\Programs\Git\usr\bin\column.exe -t
0

My attemp to solve the issue

vip ............... select paragraph
:'<,'>!column -t    align
:%norm $X ......... remove one space

Not the answer you're looking for? Browse other questions tagged or ask your own question.