Vim Tips Wiki
Register
(Adding categories)
(→‎Comments: added another real-world example where this tip is useful)
Tag: Visual edit
(21 intermediate revisions by 15 users not shown)
Line 3: Line 3:
 
|previous=28
 
|previous=28
 
|next=30
 
|next=30
|created=March 7, 2001
+
|created=2001
 
|complexity=intermediate
 
|complexity=intermediate
 
|author=slimzhao
 
|author=slimzhao
 
|version=5.7
 
|version=5.7
 
|rating=43/27
 
|rating=43/27
|category1=
+
|category1=Usage
 
|category2=
 
|category2=
 
}}
 
}}
 
This command given in {{help|12.4}} will reverse all lines in the current buffer:
 
This command given in {{help|12.4}} will reverse all lines in the current buffer:
<pre>:g/^/m0</pre>
+
<pre>
  +
:g/^/m0
  +
</pre>
   
 
# : start command-line mode.
 
# : start command-line mode.
Line 22: Line 24:
 
# 0 is the destination line (beginning of buffer)
 
# 0 is the destination line (beginning of buffer)
   
  +
This takes advantage of the implementation detail noted just below {{help|:v}}, that <code>:g</code> works by first marking all lines that match, then visiting each mark ''in order'' to run the command. Hence, you first move the first line to the top, then the second above the first, then the third above the second, etc.
If you do not want to reverse the entire file, you can supply the range of lines to reverse to the command and adjust the destination accordingly. For example, to reverse only lines 100-150:
 
   
 
If you do not want to reverse the entire file, you can supply the range of lines to reverse to the command and adjust the destination accordingly. For example, to reverse only lines 100-150:
 
<pre>
 
<pre>
 
:100,150g/^/m99
 
:100,150g/^/m99
 
</pre>
 
</pre>
   
If you are running Vim on a Unix-like operating system, the <tt>tac</tt> utility will reverse all lines for you. Like any external utility, you can call <tt>tac</tt> from Vim as an alternate method:
+
If you are running Vim on a Unix-like operating system, the <code>tac</code><sup title="cat spelled backwards. cat utility concatenates files" style=color:green;cursor:help>&dagger;</sup> utility will reverse all lines for you. Like any external utility, you can call <code>tac</code> from Vim as an alternate method:
 
 
<pre>
 
<pre>
 
:%!tac
 
:%!tac
Line 35: Line 37:
   
 
A range will also work with this method:
 
A range will also work with this method:
 
 
<pre>
 
<pre>
 
:100,150!tac
 
:100,150!tac
Line 44: Line 45:
 
For example,
 
For example,
 
<pre>
 
<pre>
command! -range=% Reverse <line1>,<line2>g/^/m0
+
command! -bar -range=% Reverse <line1>,<line2>g/^/m0|nohl
 
" REVERSE line ordering, and move those lines to the top of the file.
 
" REVERSE line ordering, and move those lines to the top of the file.
  +
</pre>
  +
  +
It is probably more useful to reverse the lines in-place, i.e. without moving them to the top:
  +
<pre>
  +
command! -bar -range=% Reverse <line1>,<line2>g/^/m<line1>-1|nohl
 
</pre>
 
</pre>
   
Line 52: Line 58:
   
 
==Comments==
 
==Comments==
  +
OK I give up. Why would you want to do this?
[[Category:Usage]]
 
  +
:1. I'm inclined to agree with the implication lurking in your question, but sometimes style triumphs over utility and the cuteness is sufficient to justify this tip. However, I actually used the command from this the tip a month ago when I had a log of lines in order newest-first, and I needed it in the reverse order. [[User:JohnBeckett|JohnBeckett]] 01:24, January 8, 2010 (UTC)
  +
  +
:2. I think without a range it has very few real uses, but with a range (which could even be a visual selection with <code>'<,'></code>) it becomes much more useful. With minor tweaking, using an actual pattern for the <code>:g</code> command and a range on the <code>:m</code> command (which could contain searches, etc.) this simple command becomes extremely versatile for moving large blocks of text and placing in reverse order. --[[User:Fritzophrenic|Fritzophrenic]] 14:32, January 8, 2010 (UTC)
  +
  +
:3. I just want to say thank you very much for this hint. I use vim to organize and search my account log (Kontobewegungen) and I receive the account info as list newest first so this hint was very helpful for me. --[[User:Peter Schneider|pu.schneider@gmx.net]] 10:00, October 4, 2010 (UTC)
  +
  +
:4. This is actually very useful if recovery fails. On a Unix system you can still recover your edits by typing "strings .swp" at a command line, but the lines are reversed. This command sets things right. 23:20, February 8, 2011 (UTC).
  +
  +
:5. Another real world: I installed a ruby gem with many dependencies on the wrong system. I wanted to remove the 20+ resulting gems, but because of gem dependencies I needed to remove them in opposite order. Google got me here, and this tip worked perfectly. 01:50, July 3, 2011 (UTC)
  +
  +
:6 Real world. I had a list with one section in between sorted in reverse order. This fixed it in a flash.
  +
  +
:7. One more real world. I am writing a very long MySQL query. I had to gather all my create statements and make drop statements in reverse order. First I copied all my create table statements with <code>qaq:g/CREATE TABLE/y A</code>. Then I put them all where they go (line 43) and highlighted them in visual mode and <code>:'<,'>g/^/m43</code> reversed their order before doing turning them into drop statements.
  +
:
  +
:8. I find myself generating lists of numbers from time to time for Verilog coding. Today, I wanted a list of numbers and the reverse list. I did it in half the time with this trick.
  +
:
  +
:9. I create network objects and config to apply in the order it must be created. If it needs to be removed later the order of removal is the reverse. For large lists of objects and ACLs that were temporary this works great!
  +
  +
:10. I was making a list of links for a playlist. I wanted to manually copy them off the web page, but I only wanted some from the latest ones published. So I had the links listed in reverse chronological order, last ones on top, copied them in the order I saw them in a file using vim. Of course, I wanted them in chronological order. So I just reversed the file. Doing it manually for a file with 27 lines would be a pain in the ass or I would need to be lucky with the software I want parsing the list so that it allows parsing it in reverse, or I'd have to write a shell script. But with this tip, I'm done in a second. 18:25, September 30, 2019 (UTC)

Revision as of 17:26, 30 September 2019

Tip 29 Printable Monobook Previous Next

created 2001 · complexity intermediate · author slimzhao · version 5.7


This command given in :help 12.4 will reverse all lines in the current buffer:

:g/^/m0
  1. : start command-line mode.
  2. g means you'll take an action on any lines where a regular expression matches
  3. / begins the regular expression (could have used any valid delimiter)
  4. ^ matches the start of a line (which matches all lines in the buffer)
  5. the second / ends the regular expression; the rest is an Ex command to execute on all matched lines (i.e. all lines in buffer)
  6. m means move (:help :move)
  7. 0 is the destination line (beginning of buffer)

This takes advantage of the implementation detail noted just below :help :v, that :g works by first marking all lines that match, then visiting each mark in order to run the command. Hence, you first move the first line to the top, then the second above the first, then the third above the second, etc.

If you do not want to reverse the entire file, you can supply the range of lines to reverse to the command and adjust the destination accordingly. For example, to reverse only lines 100-150:

:100,150g/^/m99

If you are running Vim on a Unix-like operating system, the tac utility will reverse all lines for you. Like any external utility, you can call tac from Vim as an alternate method:

:%!tac

A range will also work with this method:

:100,150!tac

Either of these methods can easily be assigned a mapping or Ex command.

For example,

command! -bar -range=% Reverse <line1>,<line2>g/^/m0|nohl
" REVERSE line ordering, and move those lines to the top of the file.

It is probably more useful to reverse the lines in-place, i.e. without moving them to the top:

command! -bar -range=% Reverse <line1>,<line2>g/^/m<line1>-1|nohl

See also

Comments

OK I give up. Why would you want to do this?

1. I'm inclined to agree with the implication lurking in your question, but sometimes style triumphs over utility and the cuteness is sufficient to justify this tip. However, I actually used the command from this the tip a month ago when I had a log of lines in order newest-first, and I needed it in the reverse order. JohnBeckett 01:24, January 8, 2010 (UTC)
2. I think without a range it has very few real uses, but with a range (which could even be a visual selection with '<,'>) it becomes much more useful. With minor tweaking, using an actual pattern for the :g command and a range on the :m command (which could contain searches, etc.) this simple command becomes extremely versatile for moving large blocks of text and placing in reverse order. --Fritzophrenic 14:32, January 8, 2010 (UTC)
3. I just want to say thank you very much for this hint. I use vim to organize and search my account log (Kontobewegungen) and I receive the account info as list newest first so this hint was very helpful for me. --pu.schneider@gmx.net 10:00, October 4, 2010 (UTC)
4. This is actually very useful if recovery fails. On a Unix system you can still recover your edits by typing "strings .swp" at a command line, but the lines are reversed. This command sets things right. 23:20, February 8, 2011 (UTC).
5. Another real world: I installed a ruby gem with many dependencies on the wrong system. I wanted to remove the 20+ resulting gems, but because of gem dependencies I needed to remove them in opposite order. Google got me here, and this tip worked perfectly. 01:50, July 3, 2011 (UTC)
6 Real world. I had a list with one section in between sorted in reverse order. This fixed it in a flash.
7. One more real world. I am writing a very long MySQL query. I had to gather all my create statements and make drop statements in reverse order. First I copied all my create table statements with qaq:g/CREATE TABLE/y A. Then I put them all where they go (line 43) and highlighted them in visual mode and :'<,'>g/^/m43 reversed their order before doing turning them into drop statements.
8. I find myself generating lists of numbers from time to time for Verilog coding. Today, I wanted a list of numbers and the reverse list. I did it in half the time with this trick.
9. I create network objects and config to apply in the order it must be created. If it needs to be removed later the order of removal is the reverse. For large lists of objects and ACLs that were temporary this works great!
10. I was making a list of links for a playlist. I wanted to manually copy them off the web page, but I only wanted some from the latest ones published. So I had the links listed in reverse chronological order, last ones on top, copied them in the order I saw them in a file using vim. Of course, I wanted them in chronological order. So I just reversed the file. Doing it manually for a file with 27 lines would be a pain in the ass or I would need to be lucky with the software I want parsing the list so that it allows parsing it in reverse, or I'd have to write a shell script. But with this tip, I'm done in a second. 18:25, September 30, 2019 (UTC)