This tip presents different methods showing how to insert a list of increasing numbers.
Making a list
It is easy to insert a list of ascending numbers, for example, this command inserts five lines after the current line:
:put =range(11,15)
The five lines are:
11 12 13 14 15
If wanted, the lines can be inserted after a particular line number, for example :123put =range(11,15)
inserts them after line number 123, while :0put =range(11,15)
inserts the lines at the start of the buffer, and :$put =range(11,15)
inserts them after the last line.
An equivalent command is :call append(123,range(11,15))
) to insert the five lines after line number 123, for example.
The list of numbers can be formatted. For example, the following inserts 150 lines, where each line contains a number displayed in four columns with leading zeros.
:put =map(range(1,150), 'printf(''%04d'', v:val)')
The results range from 0001
to 0150
. The map()
function replaces each value with the result of the expression, which must be given as a string (the double ''
presents a single apostrophe when inside an apostrophe-quoted string). In the expression, v:val
represents each value from the list in the first argument.
Here is another example, using a loop rather than map()
:
:for i in range(1,10) | put ='192.168.0.'.i | endfor
Executing this command inserts the following after the current line:
192.168.0.1 192.168.0.2 192.168.0.3 192.168.0.4 192.168.0.5 192.168.0.6 192.168.0.7 192.168.0.8 192.168.0.9 192.168.0.10
Substitute with ascending numbers
Suppose you want to replace each occurrence of "abc
" with "xyz_N
" where N is an ascending number (xyz_1
, xyz_2
, xyz_3
, and so on).
One approach uses the following command:
:let i=1 | g/abc/s//\='xyz_'.i/ | let i=i+1
However, this only changes the first abc
on each line. Adding the g
flag for a global substitute does not help as i
is only incremented once per matching line.
The following trick uses the a
register which can be changed with the setreg()
function:
:let @a=1 | %s/abc/\='xyz_'.(@a+setreg('a',@a+1))/g
As setreg returns 0 rather than a useful value, the replacement expression (\=
) calls setreg
by adding it to register a
.
Using a function
Put the following script in your vimrc or in a file in your plugin
directory.
" Add argument (can be negative, default 1) to global variable i. " Return value of i before the change. function Inc(...) let result = g:i let g:i += a:0 > 0 ? a:1 : 1 return result endfunction
Suppose you want to replace each occurrence of "abc
" with "xyz_N
" where N is an ascending number (xyz_1
, xyz_2
, xyz_3
, and so on). To do this, enter the command:
:let i = 1 | %s/abc/\='xyz_' . Inc()/g
For another example, the following command replaces each occurrence of "abc
" with a number that increases by 5, starting at 100 (the numbers will be 100, 105, 110, and so on):
:let i=100 | :%s/abc/\=Inc(5)/g
Incrementing selected numbers
In Vim 8, the first number in a selection can be incremented by pressing Ctrl-A. If the selection covers several lines, the first number in the selection on each line is incremented. Alternatively, numbers in a selection covering several lines can be converted to a sequence by typing g Ctrl-A. For example, start with the following line:
my_array[0] = 0;
Then copy it using Y6p
(copy the line and paste it six times). The result is:
my_array[0] = 0; my_array[0] = 0; my_array[0] = 0; my_array[0] = 0; my_array[0] = 0; my_array[0] = 0; my_array[0] = 0;
With the cursor on the first 0
in the first line, start a blockwise select by pressing Ctrl-V (or Ctrl-Q if you use Ctrl-V for pasting). Move the cursor down to select the first column of zeros, then press g Ctrl-A. Using Vim 8, that will give:
my_array[1] = 0; my_array[2] = 0; my_array[3] = 0; my_array[4] = 0; my_array[5] = 0; my_array[6] = 0; my_array[7] = 0;
In Vim 7 and earlier, need bellow script or a macro to create a sequence.
Put bellow script to your vimrc source.
let g:INC=0 function! INC_F(firstpoint,...) let a:num = get(a:, 1, 1) let a:sum = g:INC + a:firstpoint let g:INC = g:INC + a:num return a:sum endfunction " create a map for INC_F cab inc s/\%V\(\d\+\)/\=INC_F(submatch(1))/ \| let INC=0
Selecting a visual block around the numbers by pressing Ctrl-V, then call the abbreviation inc
by pressing :inc<Enter>
. The result will be same with above.
See also
- Increasing or decreasing numbers
- Generating a column of increasing numbers
- script#145
- script#156
- script#189
- script#821 use Ctrl-A and Ctrl-X to operate on a visual selection