## 「Vim」Making a list of numbers

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.