5

The question's title might sound a little vague, so I'll explain the situation here more clearly. I have these lines of code in a file which I want to align with respect to the character =.

const service = require('./service');
const baseService = require('./baseService');
const config = require('../config');
const Promise = require('bluebird');
const errors = require('../errors');

I want the above lines to somehow look like this

const service     = require('./service');
const baseService = require('./baseService');
const config      = require('../config');
const Promise     = require('bluebird');
const errors      = require('../errors');

I hope you understand what I'm trying to ask. I want all the = characters to lie in the same column and shift the after-coming code accordingly. What can I do to achieve this task?

A plugin capable of doing this would be nice, but it'd be great if I could do this without the aid of any plugin. That way I'd also learn something.

7

If you're in a pinch and want to get the expressions aligned, without having to install and learn any plug-ins, here is a quick way to do it.

  1. Select the lines on a visual selection. For example, if this is your whole buffer, you could use ggVG, but if these lines are in the middle of a file, just select appropriately. Perhaps V4j?
  2. Insert enough whitespace before the =, which you can do with :normal f=9i . (Note the "space" at the end.) This will add 9 spaces before each = in the lines of the visual selection. If 9 is not enough, add more (like 99 or 999, as much as you want.) Note that when you type : with the visual selection, Vim will automatically insert the range, so the actual command is :'<,'>normal f=9i , but you don't need to type those characters.
  3. Move to the column where you want the =s to be flushed to. In this case, line 2 has the longest variable name, so move to two spaces after the end of that name, which is where the =s should be at the end. If this is the whole buffer, you could use 2G2e2l to get there.
  4. Staying on that same column, move to the first line of the block. In this case, you're moving from line 2 to line 1, so k is enough.
  5. Start visual-block selection, pressing Ctrl-V.
  6. Move to the last line of the block. If this is the whole buffer, you could use G, if this is the middle of a file, you could use 4j to go four lines down, etc.
  7. (Optional) Use $ to select until the end of the line, on every line of the visual block selection. UPDATE: This step is actually not necessary here, since < will work correctly even if you don't select lines to the end. Using $ is important when using e.g. A to append to the end of all lines though.
  8. Now you can use the < command to shift the lines left, but until they hit the left of the visual block. Each < will shift them by one 'shiftwidth' only, so you're likely to need more than one. So, to be sure, use 9< (or 99<, or 999<, if you added tons of spaces in step 2.)

Voilà!

This is a pretty cool technique and it can be helpful when you need more flexibility than plug-ins can afford you. It's a good one to learn and keep on your Vim toolbox.

  • 2
    Thanks. Nice trick. – dedowsdi Jul 19 at 5:57
  • 2
    Is $ necessary? – dedowsdi Jul 19 at 6:00
  • 1
    So, to be sure, use 9< BTW. If you've shifted too little then the visual selection could be restored with gv. Also, some people use vnoremap < <gv, so it's possible to press < one after another. – Matt Jul 19 at 7:30
  • 2
    @Matt, you don't have to vnoremap as < command is dot repeatable. So press < once and continue with . s – Maxim Kim Jul 19 at 9:30
  • 1
    @dedowsdi Ah indeed $ is not needed! I was under the impression it was, as I recall blocks being shifted and spaces shuffling, but I just tested and it's not the case. I just updated my answer to point out that's not necessary here. Thanks for checking that out! – filbranden Jul 19 at 12:39
2

Install vim-easy-align, assume you bind <Plug>(EasyAlign) to ga, execute gaip=, done.

This plugin comes with a lot of predefined rule to handle common align scenarios.

Another way to do this is to use :h ! : !ipcolumn -t

  • you mean column not ipcolumn right? (however that does not work on windows) – Christian Brabandt Jul 18 at 14:45
  • @ChristianBrabandt It's :h ! in normal mode, not :h :!. And yes, it doesn't work on windows. – dedowsdi Jul 18 at 23:42
  • @dedowsdi I didn't get the second solution. What is ipcolumn and is this vim's native command? – Kartik Chauhan Jul 19 at 7:03
  • 1
    @KartikChauhan :h ! is a valid normal mode operator, it Filter {motion} text lines through the external program {filter}. In this case, {motion} is ip, {filter} is column -t. – dedowsdi Jul 19 at 7:12

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.