Vim Tips Wiki
(reword with basic methods; merge in from 200908 Reordering lines)
(→‎Comments: not sure about merge of deletion register magic)
Line 100: Line 100:
   
 
==Comments==
 
==Comments==
  +
Woah! You surprised me with the merge of the content in [[#Reordering up to nine lines]]! This content relies on a very different method than the rest, and is a surprising enough behavior that I think it may deserve its own tip, or at least a more prominent section. The trick to use '.' to cycle throught all 9 deletion registers is something I would never have learned without seeing that new tip. I might see it when looking at a random page, but I certainly wouldn't be looking for it. On seeing a page like "moving lines up or down", I would be unlikely to read the entire thing, thinking I'd seen all the content. I would have missed a gem like this. --[[User:Fritzophrenic|Fritzophrenic]] 18:25, March 26, 2010 (UTC)

Revision as of 18:25, 26 March 2010

Tip 646 Printable Monobook Previous Next

created 2004 · complexity basic · version 6.0


Programmers often want to move a line of text up or down, or to some other position. We start by explaining the basics (cut and paste, as well as move), and show how to append to a register. An amazing trick with the redo register is then presented (useful for reordering up to nine lines), and there is a set of mappings so you can press a key to move the current line, or a block of selected lines, up or down.

Cut and paste

Cut the line that you want to move by typing dd, or visually select some lines (press V then move the cursor) and type d to cut the selected block.

Then move the cursor, and paste the text at the new position (press p to paste after the line with the cursor, or P to paste before).

You can cut several lines, or blocks of text, by appending to a register using an uppercase letter, for example:

  • Move to the first line; type "add to delete it to register a.
  • Move to the next line; type "Add to delete it and append to the register.
  • Move to the next line; type "Add to delete it and append to the register.
  • Continue in this fashion.
  • Move to the wanted destination.
  • Press "ap to paste after the line with the cursor, or "aP to paste before.

Move command

You can move a line, or a block of lines, with the :m command. Examples:

:m 12 move current line to after line 12
:m 0 move current line to before first line
:m $ move current line to after last line
:m 'a move current line to after line with mark a (see using marks)
:m 'a-1 move current line to before line with mark a
:m '}-1 move current line to the end of the current paragraph

To move a block of lines, visually select the lines before entering the move command. For clarity, a space is shown after the :m command but that space is not required.

Reordering up to nine lines

The following example lines can be moved to a different order by deleting each line in turn (starting with the line that will be first when the move is complete):

line 3
line 9
line 8
line 1
line 5
line 7
line 2
line 6
line 4

Move the cursor to "line 1" and type dd to delete the line. Go to "line 2" and press . to repeat (delete another line). Repeat this on "line 3", and so on, until everything has been deleted in order.

Now type "1P to paste the contents of register 1 before the cursor.

Repeat with the dot command, eight times:

........

The first dot command pastes register 2, and the next pastes register 3, and so on. The result is that all the lines are pasted, in the correct order.

You have to press . eight times (using a count like 8. will insert the same line eight times). See :help redo-register

Mappings to move lines

The following mappings in your vimrc provide a quick way to move lines of text up or down. The mappings work in normal, insert and visual modes, allowing you to move the current line, or a selected block of lines.

nnoremap <A-j> :m+<CR>==
nnoremap <A-k> :m-2<CR>==
inoremap <A-j> <Esc>:m+<CR>==gi
inoremap <A-k> <Esc>:m-2<CR>==gi
vnoremap <A-j> :m'>+<CR>gv=gv
vnoremap <A-k> :m-2<CR>gv=gv

In normal mode or in insert mode, press Alt-j to move the current line down, or press Alt-k to move the current line up.

After visually selecting a block of lines (for example, by pressing V then moving the cursor down), press Alt-j to move the whole block down, or press Alt-k to move the block up.

Explanation

The command :m+ is an abbreviation for :m .+1 which moves the current line to after line number .+1 (the current line number + 1). That is, the current line is moved down one line.

The command :m-2 is an abbreviation for :m .-2 which moves the current line to after line number .-2 (the current line number − 2). That is, the current line is moved up one line.

After visually selecting some lines, entering :m'>+ (that is :m '>+1), will move the selected lines to after line number '>+1 (one line after the last selected line; '> is a mark assigned by Vim to identify the selection end). That is, the block of selected lines is moved down one line.

The == re-indents the line to suit its new position. For the visual-mode mappings, gv reselects the last visual block and = re-indents that block.

See also

Comments

Woah! You surprised me with the merge of the content in #Reordering up to nine lines! This content relies on a very different method than the rest, and is a surprising enough behavior that I think it may deserve its own tip, or at least a more prominent section. The trick to use '.' to cycle throught all 9 deletion registers is something I would never have learned without seeing that new tip. I might see it when looking at a random page, but I certainly wouldn't be looking for it. On seeing a page like "moving lines up or down", I would be unlikely to read the entire thing, thinking I'd seen all the content. I would have missed a gem like this. --Fritzophrenic 18:25, March 26, 2010 (UTC)