Vim Tips Wiki
Line 97: Line 97:
 
</table></onlyinclude>
 
</table></onlyinclude>
   
  +
  +
''Use the wiki markup'' <code><nowiki>{{:Ranges}}</nowiki></code> ''to include this cheat sheet into other articles. See [[Help:Transclusion]] for more information this process.''
   
 
== Comments ==
 
== Comments ==

Revision as of 17:22, 19 December 2008

Vim 7.2 Red Hat Enterprise Linux AS release 4 (Nahant Update 6)

Overview

Ranges permit a command to be applied over a subset of a file's lines. By default, the range of a Vim command is the current line. It can be helpful to think in terms of commands being executed over a one-line range of lines, and of range changes as modifiers to the range.

In general, range modifications should be specified in the form x,y where x is the number of a line in a file and y is a subsequent line in the same file; though there are some special options as well:

  • The percent sign (%) is used as a special sigil to denote all lines in the file.
  • The special syntax .,.x can be used to denote x lines from the current line.


Mnemonic
The o/o of a percent sign resembles the x,y and .,. structure of ranges, but with a "wildcard" for each number.


Ranges should always be forward ranges -- that is, it should always be true that x < y. Inverting the range by making y < x (such as,

:14,10s/abc/def/g

) will cause Vim to object, prompting the user as to whether the x and y should be reversed:

Backwards range given, OK to swap (y/n)?

Choosing "y" here will cause Vim to invert the range (making it a forward range) and execute the command. Choosing "n" will abort the operation.

Range Errors

When a user requests that a command be applied over a range of lines beyond those found in the file, Vim will object with an error:

E16: Invalid range

Examples

Current line

By default, the range of a Vim command is the current line. The following command will replace the letters "abc" with "def" on the current line:

:s/abc/def/
Note
Use the "g" flag at the end of the replacement to replace globally (within the range). That is, the above command will convert abc,abc to def,abc. To replace every occurrence of "abc" with "def", use the command
:s/abc/def/g
. See Search and replace for more information.

Between specific line numbers

Using the above string replacement example, we can modify the range to replace all occurrences of "abc" with "def" between any two lines in the file (inclusive) using the x,y syntax for range modification. Specific ranges should always be forward ranges (see the Overview section above for details). For example, to execute the replacement over lines 10, 11, 12, and 13, we may type

:10,13s/abc/def/g

X lines from the current line

Use the special .,.x syntax to modify the range to apply to the current line and x subsequent lines. Thus, to replace all occurrences of "abc" with "def" in the current line and the next 4 lines, we may type

:.,.4s/abc/def/g

If the current line is line 100, then all occurrences of "abc" will be replaced with "def" in lines 100, 101, 102, 103, and 104.

Because of this, it is permissible to restrict a command to the current line explicitly with the following syntax:

:.,.0s/abc/def/g

which will be interpreted that the command should be executed over the current line and zero subsequent lines. It's usually better simply to use the implicit "current-line" range interpretation provided by

:s/abc/def/g

It is also permissible to restrict a command to the current line semi-explicitly by omitting the x entirely:

:.,.s/abc/def/g

Finally, for advanced users, it should be noted that Vim's interpretation of the .,.x range modifier is symbolic and not iterative; that is, rather than iterating the command over x lines, the current line number is first calculated, then the last line number, and (effectively) a standard range modifier is applied. So if the cursor is currently on line 30 and the command

:.,.12s/abc/def/g

is executed, the lines involved will be internally calculated and applied as

:30,42s/abc/def/g

It is possible to exploit this mechanism to apply an backwards range from the current line by using a negative value for x. Thus, if the current cursor is on line 30 and the command

:.,.-12s/abc/def/g

is executed, it will be interpreted as the command

:30,18s/abc/def/g

As this is a backwards range, Vim will object, asking the user

Backwards range given, OK to swap (y/n)?

Choosing "y" will cause Vim to reverse the range to

:18,30s/abc/def/g

giving the desired effect.

The added inconvenience of the extra "y" keystroke may be mitigated for some users by the ability to execute a backwards-range command from the current cursor location.

It should be noted that this is probably not an expected or desired behavior and may be changed in subsequent versions of Vim. Habituate yourself at your own risk =)

All lines

As mentioned in the overview above, there is a special sigil to modify the range to apply to all lines in the current file: the percent sign (%). It can be used this way:

:%s/abc/def/g

Cheat sheet

The following "range cheat sheet" can be used as a quick-reference, and can be included dynamically in other articles in the Vim wiki.

Range cheat sheet (from Ranges)
Command Description
:s/abc/def/g Replace "abc" with "def" in the current line
:.,.12s/abc/def/g Replace "abc" with "def" in the current line and the 12 following lines
:10,35s/abc/def/g Replace "abc" with "def" between lines 10 and 35
:%s/abc/def/g Replace "abc" with "def" in all lines


Use the wiki markup {{:Ranges}} to include this cheat sheet into other articles. See Help:Transclusion for more information this process.

Comments