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
endif
let cmd = v:count > 0 ? v:count.a:cmd : a:cmd
execute 'normal! gv'.cmd
if visualmode() ==# "\<C-v>"
let &l:nrformats = savenf
endif
endfunction
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.)