FANDOM


(Insert TipProposed template + minor manual clean)
(major rewrite)
Line 5: Line 5:
 
|created=December 19, 2008
 
|created=December 19, 2008
 
|complexity=basic
 
|complexity=basic
|author=Sirrobert
+
|author=
 
|version=7.0
 
|version=7.0
 
|subpage=/200812
 
|subpage=/200812
Line 11: Line 11:
 
|category2=
 
|category2=
 
}}
 
}}
==Overview==
+
A ''range'' permits a command to be applied to a group of lines in the current buffer. For most commands, the default range is the current line. For example:
''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.
+
*<tt>:s/old/new/g</tt> &nbsp;&nbsp;changes all ''old'' to ''new'' in the current line
+
*<tt>:11,15s/old/new/g</tt> &nbsp;&nbsp;changes lines 11 to 15 inclusive
In general, range modifications should be specified in the form <code>'''x,y'''</code> 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:
+
*<tt>:%s/old/new/g</tt> &nbsp;&nbsp;changes all lines
* 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, <pre style="display: inline; padding: 1px 3px;">:14,10s/abc/def/g</pre>) 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==
 
==Examples==
  +
A range can be specified using line numbers or special characters, as in these examples:
  +
{| class="wikitable"
  +
!Range !! Description !! Example
  +
|-
  +
| <tt>21</tt> || line 21 || <tt>:21s/old/new/g</tt>
  +
|-
  +
| <tt>1</tt> || first line || <tt>:1s/old/new/g</tt>
  +
|-
  +
| <tt>$</tt> || last line || <tt>:$s/old/new/g</tt>
  +
|-
  +
| <tt>.</tt> || current line || <tt>:.w single.txt</tt>
  +
|-
  +
| <tt>%</tt> || all lines (same as <tt>1,$</tt>) || <tt>:%s/old/new/g</tt>
  +
|-
  +
| <tt>21,25</tt> || lines 21 to 25 inclusive || <tt>:21,25s/old/new/g</tt>
  +
|-
  +
| <tt>21,$</tt> || lines 21 to end || <tt>:21,$s/old/new/g</tt>
  +
|-
  +
| <tt>.,$</tt> || current line to end || <tt>:.,$s/old/new/g</tt>
  +
|-
  +
| <tt>.+1,$</tt> || line ''after'' current line to end || <tt>:.+1,$s/old/new/g</tt>
  +
|-
  +
| <tt>.,.+5</tt> || six lines (current to current+5 inclusive) || <tt>:.,.+5s/old/new/g</tt>
  +
|-
  +
| <tt>.,.5</tt> || same (<tt>.5</tt> is interpreted as <tt>.+5</tt>) || <tt>:.,.5s/old/new/g</tt>
  +
|}
   
===Current line===
+
The <tt>:s///</tt> command substitutes in the specified lines. The <tt>:w</tt> command writes a file. On its own, <tt>:w</tt> writes all lines from the current buffer to the file name for the buffer. Given a range and a file name, <tt>:w</tt> writes only the specified lines to the specified file. The example above creates file <tt>single.txt</tt> containing the 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 <code>abc,abc</code> to <code>def,abc</code>. To replace ''every'' occurrence of "abc" with "def", use the command <pre style="display: inline; padding: 1px 3px;">:s/abc/def/g</pre>. See [[Search and replace]] for more information.
+
==Default range==
  +
For most commands, the default range is <tt>.</tt> (the current line, for example, <tt>:s///</tt> substitutes in the current line). However, for <tt>:g//</tt> and <tt>:w</tt> the default is <tt>%</tt> (all lines).
   
===Between specific line numbers===
+
{| class="wikitable"
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 [[Ranges#Overview|the Overview section]] above for details). For example, to execute the replacement over lines 10, 11, 12, and 13, we may type
+
!Example !! Equivalent !! Description
:10,13s/abc/def/g
+
|-
  +
| <tt>:s/old/new/g</tt> || <tt>:.s/old/new/g</tt> || substitute in current line
  +
|-
  +
| <tt>:g/old/</tt> || <tt>:%g/old/</tt> || list all lines matching <tt>old</tt>
  +
|-
  +
| <tt>:w my.txt</tt> || <tt>:%w my.txt</tt> || write all lines to file <tt>my.txt</tt>
  +
|}
   
===X lines from the current line===
+
==Deleting, copying and moving==
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
+
Ex commands are those typed after a colon (<tt>:</tt>). As well as the commands we've seen so far, it's handy to know how to use <tt>:d</tt> (delete lines), <tt>:t</tt> or <tt>:co</tt> (copy lines), and <tt>:m</tt> (move lines).
:.,.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.
+
{| class="wikitable"
  +
!Command !! Description
  +
|-
  +
| <tt>:21,25d</tt> || delete lines 21 to 25 inclusive
  +
|-
  +
| <tt>:$d</tt> || delete the last line
  +
|-
  +
| <tt>:1,.-1d</tt> || delete all lines before the current line
  +
|-
  +
| <tt>:.+1,$d</tt> || delete all lines after the current line
  +
|-
  +
| <tt>:21,25t 30</tt> || copy lines 21 to 25 inclusive to just after line 30
  +
|-
  +
| <tt>:$t 0</tt> || copy the last line to before the first line
  +
|-
  +
| <tt>:21,25m 30</tt> || move lines 21 to 25 inclusive to just after line 30
  +
|-
  +
| <tt>:$m 0</tt> || move the last line to before the first line
  +
|}
   
Because of this, it is permissible to restrict a command to the current line explicitly with the following syntax:
+
The line numbers in a command are those ''before'' the command executes. In the earlier example which moved lines 21..25 to after 30, the "30" refers to the line number before the move occurred.
:.,.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:
+
==Ranges with marks and searches==
:.,.s/abc/def/g
+
In a range, a line number can be given as:
  +
*A mark (for example, <tt>'x</tt> is the line containing mark <tt>x</tt>).
  +
*A search (for example, <tt>/pattern/</tt> is the next line matching ''pattern'').
   
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
+
When using a mark, it must exist in the current buffer.
:.,.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
+
{| class="wikitable"
:.,.-12s/abc/def/g
+
!Command !! Description
is executed, it will be interpreted as the command
+
|-
:30,18s/abc/def/g
+
| <tt>:'a,'bd</tt> || delete lines from mark <tt>a</tt> to mark <tt>b</tt>, inclusive
  +
|-
  +
| <tt>:.,'bd</tt> || delete lines from the current line to mark <tt>b</tt>, inclusive
  +
|-
  +
| <tt>:'a,'bm 0</tt> || move lines from mark <tt>a</tt> to <tt>b</tt> inclusive, to the beginning
  +
|}
   
As this is a ''backwards'' range, Vim will object, asking the user
+
Here are some examples using searches:
Backwards range given, OK to swap (y/n)?
+
;<tt>.,/green/co $</tt>
  +
:copy the lines from the current line to the next line containing 'green' (inclusive), to the end of the buffer
  +
;<tt>:/apples/,/apples/+1s/old/new/g</tt>
  +
:replace all "old" in the next line in which the "apples" occurs, and the line following it
   
Choosing "y" will cause Vim to reverse the range to
+
Even more tricks are available; see {{help|:range}}. Summary:
: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.
+
{| class="wikitable"
+
!Item !! Description
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 =)
+
|-
+
| <tt>/pattern/</tt> || next line where ''pattern'' matches
===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:
+
| <tt>?pattern?</tt> || previous line where ''pattern'' matches
:%s/abc/def/g
+
|-
+
| <tt>\/</tt> || next line where the previously used search pattern matches
===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.
+
| <tt>\?</tt> || previous line where the previously used search pattern matches
<onlyinclude><table style="border: 1px solid #aaaaaa;" cellpadding=0 cellspacing=0>
+
|-
<caption style="background-color: #aaaaaa; color: white">Range cheat sheet (from [[Ranges]])</caption>
+
| <tt>\&</tt> || next line where the previously used substitute pattern matches
<tr style="background-color: #fec423;">
+
|-
<th>Command</th>
+
| <tt>0;/that</tt> || first line containing "that" (also matches in the first line)
<th style="text-align: left; padding: 2px 5px;">Description</th>
+
|-
</tr>
+
| <tt>1;/that</tt> || first line after line 1 containing "that"
<tr>
+
|}
<td><code style="padding: 2px 5px; margin: 2px;">:s/abc/def/g</code></td>
 
<td style="padding: 2px 5px;">Replace "abc" with "def" in the current line</td>
 
</tr>
 
<tr>
 
<td><code style="padding: 2px 5px; margin: 2px;">:.,.12s/abc/def/g</code></td>
 
<td style="padding: 2px 5px;"> Replace "abc" with "def" in the current line and the 12 following lines </td>
 
</tr>
 
<tr>
 
<td><code style="padding: 2px 5px; margin: 2px;">:10,35s/abc/def/g</code></td>
 
<td style="padding: 2px 5px;">Replace "abc" with "def" between lines 10 and 35</td>
 
</tr>
 
<tr>
 
<td><code style="padding: 2px 5px; margin: 2px;">:%s/abc/def/g</code></td>
 
<td style="padding: 2px 5px;">Replace "abc" with "def" in all lines</td>
 
</tr>
 
</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==
Also should mention other things in {{help|:range}}
 
<pre>
 
$ = last line in file
 
't = position of mark t
 
'T = position of mark T if it is in the same buffer
 
/{pattern}/ = next line where pattern matches
 
?{pattern}? = previous line where pattern matches
 
\/ = next place previous search pattern matches
 
\? = previous place previous search pattern matches
 
\& = next place previous substitution pattern matches
 
</pre>
 
 
I find <tt>/{pattern}/</tt> to be especially useful.
 
 
Also mention that +{number} and -{number} can be added to the end of any of the range values to adjust the line number.
 
 
For example:
 
 
<tt>:/apples/,/apples/+1s/oranges/bananas/g</tt> will replace all occurrences of "oranges" in the next line in which the word "apples" occurs and the line following it.
 
 
----
 

Revision as of 08:46, April 11, 2009

Proposed tip Please edit this page to improve it, or add your comments below (do not use the discussion page).

Please use new tips to discuss whether this page should be a permanent tip, or whether it should be merged to an existing tip.
created December 19, 2008 · complexity basic · version 7.0

A range permits a command to be applied to a group of lines in the current buffer. For most commands, the default range is the current line. For example:

  • :s/old/new/g   changes all old to new in the current line
  • :11,15s/old/new/g   changes lines 11 to 15 inclusive
  • :%s/old/new/g   changes all lines

Examples

A range can be specified using line numbers or special characters, as in these examples:

Range Description Example
21 line 21 :21s/old/new/g
1 first line :1s/old/new/g
$ last line :$s/old/new/g
. current line :.w single.txt
% all lines (same as 1,$) :%s/old/new/g
21,25 lines 21 to 25 inclusive :21,25s/old/new/g
21,$ lines 21 to end :21,$s/old/new/g
.,$ current line to end :.,$s/old/new/g
.+1,$ line after current line to end :.+1,$s/old/new/g
.,.+5 six lines (current to current+5 inclusive) :.,.+5s/old/new/g
.,.5 same (.5 is interpreted as .+5) :.,.5s/old/new/g

The :s/// command substitutes in the specified lines. The :w command writes a file. On its own, :w writes all lines from the current buffer to the file name for the buffer. Given a range and a file name, :w writes only the specified lines to the specified file. The example above creates file single.txt containing the current line.

Default range

For most commands, the default range is . (the current line, for example, :s/// substitutes in the current line). However, for :g// and :w the default is % (all lines).

Example Equivalent Description
:s/old/new/g :.s/old/new/g substitute in current line
:g/old/ :%g/old/ list all lines matching old
:w my.txt :%w my.txt write all lines to file my.txt

Deleting, copying and moving

Ex commands are those typed after a colon (:). As well as the commands we've seen so far, it's handy to know how to use :d (delete lines), :t or :co (copy lines), and :m (move lines).

Command Description
:21,25d delete lines 21 to 25 inclusive
:$d delete the last line
:1,.-1d delete all lines before the current line
:.+1,$d delete all lines after the current line
:21,25t 30 copy lines 21 to 25 inclusive to just after line 30
:$t 0 copy the last line to before the first line
:21,25m 30 move lines 21 to 25 inclusive to just after line 30
:$m 0 move the last line to before the first line

The line numbers in a command are those before the command executes. In the earlier example which moved lines 21..25 to after 30, the "30" refers to the line number before the move occurred.

Ranges with marks and searches

In a range, a line number can be given as:

  • A mark (for example, 'x is the line containing mark x).
  • A search (for example, /pattern/ is the next line matching pattern).

When using a mark, it must exist in the current buffer.

Command Description
:'a,'bd delete lines from mark a to mark b, inclusive
:.,'bd delete lines from the current line to mark b, inclusive
:'a,'bm 0 move lines from mark a to b inclusive, to the beginning

Here are some examples using searches:

.,/green/co $
copy the lines from the current line to the next line containing 'green' (inclusive), to the end of the buffer
:/apples/,/apples/+1s/old/new/g
replace all "old" in the next line in which the "apples" occurs, and the line following it

Even more tricks are available; see :help :range. Summary:

Item Description
/pattern/ next line where pattern matches
?pattern? previous line where pattern matches
\/ next line where the previously used search pattern matches
\? previous line where the previously used search pattern matches
\& next line where the previously used substitute pattern matches
0;/that first line containing "that" (also matches in the first line)
1;/that first line after line 1 containing "that"

Comments

Community content is available under CC-BY-SA unless otherwise noted.