Vim Tips Wiki
Register
m (mark as duplicate)
m (Reverted edits by 103.16.62.22 (talk | block) to last version by Fritzophrenic)
Tag: rollback
(37 intermediate revisions by 13 users not shown)
Line 1: Line 1:
  +
{{TipImported
{{review}}
 
{{duplicate|924}}
 
{{Tip
 
 
|id=646
 
|id=646
  +
|previous=645
|title=moving lines up/down in a file
 
  +
|next=647
|created=January 28, 2004 22:33
+
|created=2004
 
|complexity=basic
 
|complexity=basic
|author=Frank Butler
+
|author=
|version=5.7
+
|version=6.0
 
|rating=80/42
 
|rating=80/42
  +
|category1=Moving
|text=
 
  +
|category2=
The following mappings in .vimrc provide a quick way to move a line of text up or down within a file:
 
 
}}
<pre>
 
  +
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 [[#Reordering up to nine lines|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.
map &lt;C-Up&gt; dd-P
 
map &lt;C-Down&gt; ddp
 
</pre>
 
   
  +
==Cut and paste==
Hold down the Control key, and the &lt;Up&gt; and &lt;Down&gt; arrow keys move the line. Check it out!
 
  +
Cut the line that you want to move by typing <code>dd</code>, or visually select some lines (press <code>V</code> then move the cursor) and type <code>d</code> to cut the selected block.
   
  +
Then move the cursor, and paste the text at the new position (press <code>p</code> to paste after the line with the cursor, or <code>P</code> to paste before).
This is particularly useful when editing a file consisting of single-line items in a particular order (such as priority) - it makes it easy to change the relative position of items in the list.
 
}}
 
   
  +
You can cut several lines, or blocks of text, by appending to a register using an uppercase letter, for example:
== Comments ==
 
  +
*Move to the first line you wish to move; type <code>"add</code> to delete it to register <code>a</code>.
This works everywhere except at the top or bottom of the buffer. There was a discussion about this on the Vim list a while back and a swap line plugin came out of it -- I don't know who produced it in the first place and I won't want to post it here without giving due credit, but basically it mapped the key combinations to two different functions that would first store the current column the cursor was in, then swap the line (behaving differently at the beginning/end of the buffer -- try doing the combination in the original tip here to see what I mean about the need to behave differently at the edges of the buffer) and then restore the cursor position, leaving you where you started, but with the lines swapped.
 
  +
*Move to another line; type <code>"Add</code> to delete it and ''append'' to the same register.
  +
*Move to another line; type <code>"Add</code> to delete it and ''append'' to the same register.
  +
**or type "." for the same effect
  +
*Select a range of lines vith V; type <code>"Ad</code> to delete the entire range and append it to the same register.
  +
*Continue in this fashion.
  +
*Move to the wanted destination.
  +
*Press <code>"ap</code> to paste after the line with the cursor, or <code>"aP</code> to paste before.
   
  +
==Move command==
salmanhalim--AT--hotmail.com
 
  +
You can move a line, or a block of lines, with the <code>:m</code> command. Examples:
, January 29, 2004 7:00
 
  +
{| class="cleartable"
----
 
  +
| <code>:m 12</code> || move current line to after line 12
I've been using the following for a while. I like them because:
 
  +
|-
* they work in any mode.
 
  +
| <code>:m 0</code> || move current line to before first line
* in visual mode they operate on the entire block.
 
  +
|-
* the indentation is adjusted automagically.
 
  +
| <code>:m $</code> || move current line to after last line
* they can handle the tops and bottoms of files.
 
  +
|-
<pre>
 
  +
| <code>:m 'a</code> || move current line to after line with mark <code>a</code> (see [[using marks]])
" move the current line up or down
 
  +
|-
nmap &lt;C-Down&gt; :m+&lt;CR&gt;==
 
  +
| <code>:m 'a-1</code> || move current line to before line with mark <code>a</code>
nmap &lt;C-Up&gt; :m-2&lt;CR&gt;==
 
  +
|-
imap &lt;C-Down&gt; &lt;C-O&gt;:m+&lt;CR&gt;&lt;C-O&gt;==
 
  +
| <code>:m '}-1</code> || move current line to the end of the current paragraph
imap &lt;C-Up&gt; &lt;C-O&gt;:m-2&lt;CR&gt;&lt;C-O&gt;==
 
  +
|}
   
  +
For clarity, a space is shown after the <code>:m</code> commands above, but that space is not required.
" move the current line left or right
 
nmap &lt;C-Left&gt; &lt;&lt;
 
nmap &lt;C-Right&gt; &gt;&gt;
 
imap &lt;C-Left&gt; &lt;C-O&gt;&lt;&lt;
 
imap &lt;C-Right&gt; &lt;C-O&gt;&gt;&gt;
 
   
  +
To move a block of lines, use the same command but visually select the lines before entering the move command. You can also use arbitrary [[ranges]] with the move command. Examples:
" move the selected block up or down
 
  +
{| class="cleartable"
vmap &lt;C-Down&gt; :m'&gt;+&lt;CR&gt;gv=gv
 
  +
| <code>:5,7m 21</code> || move lines 5, 6 and 7 to after line 21
vmap &lt;C-Up&gt; :m'&lt;-2&lt;CR&gt;gv=gv
 
  +
|-
  +
| <code>:5,7m 0</code> || move lines 5, 6 and 7 to before first line
  +
|-
  +
| <code>:5,7m $</code> || move lines 5, 6 and 7 to after last line
  +
|-
  +
| <code>:.,.+4m 21</code> || move 5 lines starting at current line to after line 21
  +
|-
  +
| <code>:,+4m14</code> || same (<code>.</code> for current line is assumed)
  +
|}
   
  +
==Reordering up to nine lines==
" move the selected block left or right
 
  +
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):
vmap &lt;C-Right&gt; &gt;gv
 
 
<pre>
vmap &lt;C-Left&gt; &lt;gv
 
  +
line 3
  +
line 9
  +
line 8
  +
line 1
  +
line 5
  +
line 7
  +
line 2
  +
line 6
  +
line 4
 
</pre>
 
</pre>
   
  +
Move the cursor to "line&nbsp;1" and type <code>dd</code> to delete the line. Go to "line&nbsp;2" and press <code>.</code> to repeat (delete another line). Repeat this on "line&nbsp;3", and so on, until everything has been deleted in order.
jcm314--AT--hotmail.com
 
  +
, January 30, 2004 13:22
 
  +
Now type <code>"1P</code> to paste the contents of register 1 before the cursor.
----
 
  +
A variation on the above, &lt;f11&gt; stores one line &lt;f12&gt; restores it, also allows copying one line to another file
 
  +
Repeat with the dot command, eight times:
 
<pre>
 
<pre>
  +
........
map &lt;f11&gt; :.w! c:/aaa/xr&lt;CR&gt;
 
map! &lt;f11&gt; &lt;ESC&gt;:.w! c:/aaa/xr&lt;CR&gt;
 
map &lt;f12&gt; :r c:/aaa/xr&lt;CR&gt;
 
map! &lt;f12&gt; &lt;ESC&gt;:r c:/aaa/xr&lt;CR&gt;
 
 
</pre>
 
</pre>
zzapper--AT--ntlworld.com
 
, February 2, 2004 11:12
 
----
 
Cool! I took jcm314's nmap's for up/down (you get an error at top/bottom of file) and left/right, except dropped the == from the end (don't want line to get reformatted when I move it).
 
   
  +
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.
frankbutler--AT--ieee.org
 
, February 9, 2004 16:42
 
----
 
jcm314's mapping is great, thanks.
 
I also remove the reformatting "==" and "=gv" since it cause some confusion when moving a line/block through complex code.
 
   
  +
You have to press <code>.</code> eight times (using a count like <code>8.</code> will insert the same line eight times). See {{help|redo-register}}
vimmiv--AT--msn.com
 
  +
, March 22, 2004 21:40
 
  +
==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.
another strategy for moving visual mode blocks is:
 
 
<pre>
 
<pre>
  +
nnoremap <A-j> :m .+1<CR>==
:vmap &lt;f6&gt; xkP1v
 
  +
nnoremap <A-k> :m .-2<CR>==
:vmap &lt;f7&gt; xp1v
 
  +
inoremap <A-j> <Esc>:m .+1<CR>==gi
  +
inoremap <A-k> <Esc>:m .-2<CR>==gi
  +
vnoremap <A-j> :m '>+1<CR>gv=gv
  +
vnoremap <A-k> :m '<-2<CR>gv=gv
 
</pre>
 
</pre>
translation: "x = cut, k = move up one line, P = paste, 1v = reselect last visual area"
 
   
  +
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.
I haven't tested this extensively, so I don't know how well it works under heavy use.
 
  +
  +
After visually selecting a block of lines (for example, by pressing <code>V</code> 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 <code>:m .+1</code> (which can be abbreviated to <code>:m+</code>) moves the current line to after line number <code>.+1</code> (current line number + 1). That is, the current line is moved down one line.
  +
  +
The command <code>:m .-2</code> (which can be abbreviated to <code>:m-2</code>) moves the current line to after line number <code>.-2</code> (current line number − 2). That is, the current line is moved up one line.
  +
  +
After visually selecting some lines, entering <code>:m '>+1</code> moves the selected lines to after line number <code>'>+1</code> (one line after the last selected line; <code>'></code> is a mark assigned by Vim to identify the selection end). That is, the block of selected lines is moved down one line.
  +
  +
The <code>==</code> re-indents the line to suit its new position. For the visual-mode mappings, <code>gv</code> reselects the last visual block and <code>=</code> re-indents that block.
   
  +
==See also==
--Robert
 
  +
*[[VimTip191|Transposing]] enhanced mappings (better at maintaining cursor position?)
  +
*[[VimTip344|Cut or copy lines without counting the lines]] ''(needs to be fixed)''
  +
*[http://stackoverflow.com/questions/741814/move-entire-line-up-and-down-in-vim stackoverflow - Move entire line up and down in Vim]
   
 
==Comments==
ramses0--AT--yahoo.com
 
, May 20, 2004 9:22
 
----
 
<!-- parsed by vimtips.py in 0.531635 seconds-->
 
[[Category:Usage]]
 

Revision as of 15:09, 3 August 2015

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 you wish to move; type "add to delete it to register a.
  • Move to another line; type "Add to delete it and append to the same register.
  • Move to another line; type "Add to delete it and append to the same register.
    • or type "." for the same effect
  • Select a range of lines vith V; type "Ad to delete the entire range and append it to the same 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

For clarity, a space is shown after the :m commands above, but that space is not required.

To move a block of lines, use the same command but visually select the lines before entering the move command. You can also use arbitrary ranges with the move command. Examples:

:5,7m 21 move lines 5, 6 and 7 to after line 21
:5,7m 0 move lines 5, 6 and 7 to before first line
:5,7m $ move lines 5, 6 and 7 to after last line
:.,.+4m 21 move 5 lines starting at current line to after line 21
:,+4m14 same (. for current line is assumed)

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 .+1<CR>==
nnoremap <A-k> :m .-2<CR>==
inoremap <A-j> <Esc>:m .+1<CR>==gi
inoremap <A-k> <Esc>:m .-2<CR>==gi
vnoremap <A-j> :m '>+1<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 .+1 (which can be abbreviated to :m+) moves the current line to after line number .+1 (current line number + 1). That is, the current line is moved down one line.

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

After visually selecting some lines, entering :m '>+1 moves 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