I want to be able to increment letters but only in visual block mode. I don't want <C-a>/<C-x> to increment letters outside of visual block.

This is for making incrementing lists from this:

a) this
a) is a
a) test

... to this:

a) this
b) is a
c) test

There is no simple way to do it (considering all edge cases).

You can try remapping solution:

nnoremap <C-v> :setl nf+=alpha<CR><C-v>
nnoremap v :setl nf+=alpha<CR>v
nnoremap V :setl nf+=alpha<CR>V
xnoremap <C-a> <C-a>:setl nf-=alpha<CR>
xnoremap <C-x> <C-x>:setl nf-=alpha<CR>
xnoremap <ESC> <ESC>:setl nf-=alpha<CR>

It just remaps visual mode keys to add alpha to nrformats and as there is no event to for exiting visual mode, remaps <ESC>, <C-a> and <C-x> to do default mapping and then remove alpha from nrformats.


This started as a small refinement on Maxim Kim's answer to only remap the <C-a> and <C-x> commands to add alpha to 'nrformats before executing the original action. But then it grew into refactoring the operation into a separate function, which is nice since it addresses one of your original requests (use alphabetic increments only in Visual Block mode) and also supports working with counts.

This, of course, makes it quite complex, but gives us the flexibility to check visualmode() to only act special when we're coming from Visual Block mode, and also to save and restore the original 'nrformats' setting (which will preserve "alpha" if it was explicitly added at some point.)

The function uses the gv mapping to restore the initial Visual selection before executing the original command. It also checks v:count and passes it to original command if it was used in our mappings.

function! AlphaIncrement(cmd) abort
    if visualmode() ==# "\<C-v>"
        let savenf = &l:nrformats
        setlocal nrformats+=alpha
    let cmd = v:count > 0 ? v:count.a:cmd : a:cmd
    execute 'normal! gv'.cmd
    if visualmode() ==# "\<C-v>"
        let &l:nrformats = savenf

xnoremap <silent> <C-a> :<C-u>call AlphaIncrement('<C-a>')<CR>
xnoremap <silent> g<C-a> :<C-u>call AlphaIncrement('g<C-a>')<CR>
xnoremap <silent> <C-x> :<C-u>call AlphaIncrement('<C-x>')<CR>
xnoremap <silent> g<C-x> :<C-u>call AlphaIncrement('g<C-x>')<CR>

You could also decide to keep the original commands unchanged and add a set of alternative mappings (for example, <Leader><C-a>, <Leader>g<C-a>, and so on) for the version that acts on alphabetic characters. That would give you easy access to the new feature, while still preserving the useful part of only incrementing the first number found on the block. (Or perhaps remap the <Leader> version of the mappings to the unmodified commands, so they're still accessible.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.