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
function! Incr() let a = line('.') - line("'<") let c = virtcol("'<") if a > 0 execute 'normal! '.c.'|'.a."\<C-a>" endif normal `< endfunction vnoremap <C-a> :call Incr()<CR>
You can use this script for increasing number in a column. For example, you want to initialize an array with the value i
for the element i
. You can type:
my_array[0] = 0;
then copy and paste that line (type Y6p
to copy then paste the line six times). The result will be the first column shown below:
my_array[0] = 0; my_array[0] = 0; my_array[0] = 0; my_array[0] = 1; my_array[0] = 0; my_array[0] = 2; my_array[0] = 0; --> my_array[0] = 3; my_array[0] = 0; my_array[0] = 4; my_array[0] = 0; my_array[0] = 5; my_array[0] = 0; my_array[0] = 6;
Put the cursor on the second 0
in the first line, then 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 second column of zeros, then press Ctrl-A. The result (using the above script) will be the column shown on the right of -->
above.
Repeating these steps for the first column of zeros changes the text:
my_array[0] = 0; my_array[0] = 0; my_array[0] = 1; my_array[1] = 1; my_array[0] = 2; my_array[2] = 2; my_array[0] = 3; --> my_array[3] = 3; my_array[0] = 4; my_array[4] = 4; my_array[0] = 5; my_array[5] = 5; my_array[0] = 6; my_array[6] = 6
See making a list for a simple macro as an alternative to the 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