Moving Lines

Reorganizing lines in a buffer is a very common task. While a yank and paste sequence could be used for each line, there is a better way.

The following keymaps allow a line or group of lines to be easily moved up or down using a single keystroke:

-- single-line
vim.keymap.set("n", "<A-j>", ":move .+1<CR>==")
vim.keymap.set("n", "<A-k>", ":move .-2<CR>==")

-- multi-line
vim.keymap.set("v", "<A-j>", ":move '>+1<CR>gv=gv")
vim.keymap.set("v", "<A-k>", ":move '<-2<CR>gv=gv")

To see how they work, consider the following buffer:

Initial Conditions
a·=·[
····"one",
····"three",
····"two",
····"four",
····"five",
]
NORMAL
Top
1:1
 

Note that the words are out of order, and we would like to fix that. We start by moving the cursor to the line that we want to move (i.e. the "target" line):

Move to Target Line
2j
a·=·[
····"one",
····"three",
····"two",
····"four",
····"five",
]
NORMAL
38%
3:1
 

With this keymap, hitting A-J allows us to easily move the currently down one position, swapping its position with the line below it:

Move Current Line
<A-j>
a·=·[
····"one",
····"two",
····"three",
····"four",
····"five",
]
NORMAL
50%
4:1
 

To get a better idea about what happened, consider the command that executed when we hit A-J:

:move .+1<CR>==

The :move command has a call signature:

:m[ove] {address}

and moves the current line (or selected lines) to the line below the specified address.

In this case, the specified address is .+1, which we learned in the ranges chapter means "the line below the current line". The carriage return causes the preceding command to execute, which is follows by ==, which formats (indents) the line after it is moved.

Let's see how this works with a visual selection. First, let's move the cursor so that the selection spans three lines:

Select Multiple Lines
v2j
a·=·[
····"one",
····"two",
····"three",
····"four",
····"five",
]
VISUAL
75%
6:1
 

Note that although the selection only touches the third line, the entire line is included in the block of lines to move. Now, move these lines up:

Move Multiple Lines
<A-k>
a·=·[
····"one",
····"three",
····"four",
····"five",
····"two",
]
VISUAL
62%
5:1
3 lines indented

The selected lines have each move up one line, and the line containing "two" (which has previously been above the selection) is now located below the selection.