I often want to move and indent code at the same time. Is it possible to do the following.

Original text:

1: var x = foo();
2: bar(x);

Desired text:

1: setTimeout(function(){
2:     var x = foo();
3:     bar(x);
4: });

Working keystrokes:

  1. Place the cursor on line 1.
  2. Type O (insert text on the line above) and type the two lines setTimeout(function(){ and });. Press escape to exit insert mode.
  3. Type 3,4> | 3,4m1.

Is it possible to condense step 3 into something like the following:



Short answer: no.

You can use the :global command to pick some lines to operate on, and then give a sequence of commands to operate on those selected lines:

:3,4 g/^/ > | m1

We're only interested in the range, but :g also wants a pattern. So in this case we'll just use /^/ which will always match in a line.

This however moves each line in sequence which reverses the order of the moved lines. A simple way to rectify this is to mark the last inserted line (line 2 at this point) before you start the :global and move the indented lines before it:

:k x | 3,4 g/^/ > | m 'x-

Or you could shift each line up by 2, provided you know you've inserted exactly 2 new lines:

:3,4 g/^/ > | m-2

That's hardly a condensing of the original command but shows the general principle.

Another option is to indent your lines, and then use the '[ and '] marks, which delimit previously changed text:

:3,4> | '[,']m1

This still isn't a condensing, but for more complicated ranges it may be worth the effort, and might be your best bet. But maybe for simple edits do the simple thing.

Finally: I guess we're talking about general principles here. But in this particular case, after your step #2, the Normal mode commands dd>jjp would also achieve the same result.

  • 1
    I appreciate the answer, but unfortunately, this reverses the lines, presumably because it executes "indent then move to line 1" for every line, rather than once for the entire range. – magnus May 9 '17 at 2:36
  • Of course it does. See edit. – Antony May 9 '17 at 2:44

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.