Vim Tips Wiki
(Copy in all text from 201104 Enhanced Ctrl-A and minor rearrangement.)
(Replace enhanced increment/decrement script with a simpler version and add some details.)
Line 33: Line 33:
 
</pre>
 
</pre>
   
==Original text from [[Enhanced Ctrl-A]]==
+
==Enhanced increment/decrement==
  +
The following script enhances Ctrl-A and Ctrl-X so that they operate on the next number, even if that number is not on the current line (they search for the next number). Also, assuming the default backslash leader key, typing <tt>\</tt> then Ctrl-A or Ctrl-X will search backwards and operate on the previous number.
{{TipProposed
 
|id=0
 
|previous=0
 
|next=0
 
|created=April 6, 2011
 
|complexity=basic
 
|author=Kurkale6ka
 
|version=7.0
 
|subpage=/201104
 
|category1=
 
|category2=
 
}}
 
By default, pressing Ctrl-A increments the number at or after the cursor, and Ctrl-X decrements that number. In both cases, the number has to be on the same line as the cursor. This tip remaps these keys so that Ctrl-A (or Ctrl-X) will increment (or decrement) the next number even if it is not on the same line as the cursor. In addition, pressing the leader key then Ctrl-A (or Ctrl-X) will increment (or decrement) the next number at or before the cursor, if necessary searching backwards to find the number on previous lines. That is, assuming the default backslash leader, type <tt>\</tt> then Ctrl-A (or Ctrl-X) to increment (or decrement) the number at or before the cursor.
 
   
  +
Put the following script in your [[vimrc]] or in a file in your <tt>plugin</tt> directory.
===Code===
 
 
<pre>
 
<pre>
function! AddSubtract(operation, direction)
+
function! AddSubtract(char, back)
if &nrformats =~ 'alpha'
+
let pattern = &nrformats =~ 'alpha' ? '[[:alpha:][:digit:]]' : '[[:digit:]]'
 
call search(pattern, 'cw' . a:back)
let pattern = '[[:alpha:][:digit:]]'
 
 
execute 'normal! ' . v:count1 . a:char
else
 
 
silent! call repeat#set(":\<C-u>call AddSubtract('" .a:char. "', '" .a:back. "')\<CR>")
let pattern = '[[:digit:]]'
 
endif
 
if 'b' == a:direction
 
call search(pattern, 'bcw')
 
else
 
call search(pattern, 'cw')
 
endif
 
if 'a' == a:operation
 
execute 'normal! ' . v:count1 . "\<C-a>"
 
silent! call
 
\ repeat#set(":\<C-u>call AddSubtract('a', '" .a:direction. "')\<CR>")
 
else
 
execute 'normal! ' . v:count1 . "\<C-x>"
 
silent! call
 
\ repeat#set(":\<C-u>call AddSubtract('s', '" .a:direction. "')\<CR>")
 
endif
 
 
endfunction
 
endfunction
nnoremap <silent> <C-a> :<C-u>call AddSubtract('a', 'f')<CR>
+
nnoremap <silent> <C-a> :<C-u>call AddSubtract("\<C-a>", '')<CR>
nnoremap <silent> <Leader><C-a> :<C-u>call AddSubtract('a', 'b')<CR>
+
nnoremap <silent> <Leader><C-a> :<C-u>call AddSubtract("\<C-a>", 'b')<CR>
nnoremap <silent> <C-x> :<C-u>call AddSubtract('s', 'f')<CR>
+
nnoremap <silent> <C-x> :<C-u>call AddSubtract("\<C-x>", '')<CR>
nnoremap <silent> <Leader><C-x> :<C-u>call AddSubtract('s', 'b')<CR>
+
nnoremap <silent> <Leader><C-x> :<C-u>call AddSubtract("\<C-x>", 'b')<CR>
 
</pre>
 
</pre>
   
  +
The above uses the [https://github.com/tpope/vim-repeat repeat plugin] so you can press <tt>.</tt> to repeat an operation performed by the script. For example, pressing <tt>5</tt> then Ctrl-A would search for the next number and increment it 5 times, and pressing <tt>.</tt> would repeat that (add 5 again). The prefix <tt>:silent!</tt> is used so that no error occurs if <tt>repeat.vim</tt> is not found.
===References===
 
  +
*{{help|CTRL-A}}
 
  +
The script has an inconsistency when searching in the forwards direction. With the default hex in <tt>'nrformats'</tt>, the code finds and operates on the next number, which may be a hex number. After the operation, the cursor is left on the last character of the number, and if that character is a letter (for example, <tt>0x12AB</tt>), repeating the operation will find and operate on the ''next'' number because the script starts by searching for a digit 0..9.
*{{help|CTRL-X}}
 
   
 
==Making a list==
 
==Making a list==
Line 105: Line 78:
 
</pre>
 
</pre>
   
Later, you might insert a new item after #102. Now you need to renumber the following items (the new item will be 103, so the old 103 has to be incremented, as does 104, and so on. The can be done using {{tt|:.,$g/^\d/exe "normal! \<C-A>"}} (see [[Power of g|here]]).
+
Later, you might insert a new item after #102. Now you need to renumber the following items (the new item will be 103, so the old 103 has to be incremented, as does 104, and so on. The can be done using {{tt|:.,$g/^\d/exe "normal! \<C-a>"}} (see [[Power of g|here]]).
   
 
==Related plugin==
 
==Related plugin==

Revision as of 10:44, 4 April 2012

Tip 30 Printable Monobook Previous Next

created 2001 · complexity basic · version 7.0


In normal mode, typing Ctrl-A will increment the next number, and typing Ctrl-X will decrement the next number. The number can be at the cursor, or to the right of the cursor (on the same line). These are the defaults for Vim, although some scripts remap these keys to perform other functions.

These keys work with a count. For example, pressing 5 then Ctrl-A will increment the following number five times (add 5).

Number formats

The 'nrformats' option defaults to "octal,hex" which means that increment and decrement work on octal and hex numbers, as well as decimal. If 'nrformats' includes "alpha", alphabetic characters are also operated on (the next letter is incremented or decremented). Use :set nrformats? to view the current options, or :set nrformats+=alpha to add the alpha option.

An octal number starts with 0, and a hex number starts with 0x or 0X. Decimal numbers can be preceded with a sign (any + is ignored, while - makes the number negative).

Alternative mapping

On Windows, your vimrc file may source mswin.vim or another script that maps Ctrl-A to Select All. To view and then remove such a normal-mode mapping, enter:

:verbose map <C-a>
:nunmap <C-a>

Alternatively, you can keep the Ctrl-A mapping, and use a different key for incrementing. For example, the following maps Alt-A to perform an increment (it also maps Alt-X to perform a decrement so the Alt key can be used for both):

:nnoremap <A-a> <C-a>
:nnoremap <A-x> <C-x>

Enhanced increment/decrement

The following script enhances Ctrl-A and Ctrl-X so that they operate on the next number, even if that number is not on the current line (they search for the next number). Also, assuming the default backslash leader key, typing \ then Ctrl-A or Ctrl-X will search backwards and operate on the previous number.

Put the following script in your vimrc or in a file in your plugin directory.

function! AddSubtract(char, back)
  let pattern = &nrformats =~ 'alpha' ? '[[:alpha:][:digit:]]' : '[[:digit:]]'
  call search(pattern, 'cw' . a:back)
  execute 'normal! ' . v:count1 . a:char
  silent! call repeat#set(":\<C-u>call AddSubtract('" .a:char. "', '" .a:back. "')\<CR>")
endfunction
nnoremap <silent>         <C-a> :<C-u>call AddSubtract("\<C-a>", '')<CR>
nnoremap <silent> <Leader><C-a> :<C-u>call AddSubtract("\<C-a>", 'b')<CR>
nnoremap <silent>         <C-x> :<C-u>call AddSubtract("\<C-x>", '')<CR>
nnoremap <silent> <Leader><C-x> :<C-u>call AddSubtract("\<C-x>", 'b')<CR>

The above uses the repeat plugin so you can press . to repeat an operation performed by the script. For example, pressing 5 then Ctrl-A would search for the next number and increment it 5 times, and pressing . would repeat that (add 5 again). The prefix :silent! is used so that no error occurs if repeat.vim is not found.

The script has an inconsistency when searching in the forwards direction. With the default hex in 'nrformats', the code finds and operates on the next number, which may be a hex number. After the operation, the cursor is left on the last character of the number, and if that character is a letter (for example, 0x12AB), repeating the operation will find and operate on the next number because the script starts by searching for a digit 0..9.

Making a list

There are several ways to make a list of increasing numbers. One simple method is to use Ctrl-A in a macro. As an example, suppose you type the line:

101 This is an item.

In normal mode, enter the following to record a macro into the a register (type the characters shown, without pressing Enter). This macro yanks the current line, then pastes it below, then increments the number.

qa
Y
p
Ctrl-A
q

Now type 15@a to perform the macro 15 times. You will see:

101 This is an item.
102 This is an item.
103 This is an item.
104 This is an item.
and so on

Later, you might insert a new item after #102. Now you need to renumber the following items (the new item will be 103, so the old 103 has to be incremented, as does 104, and so on. The can be done using :.,$g/^\d/exe "normal! \<C-a>" (see here).

Related plugin

The keys Ctrl-A and Ctrl-X can be used on a visual selection by using script#821. This plugin also allows resequencing numbers in a selected list (example included on the script page).

References

Comments

If you use Vim under screen, press Ctrl-A and then hit a. Screen then sends on a translation of Ctrl-A to the underlying program, Vim.