I want to remap Ctrl-A (normal mode) to do something similar
with other data, e.g.

:nmap <c-a> ciw<c-r>=IncRoman(@-)<cr><esc>

Now if a count is provided this will mess up the text, e.g. 10<c-a> does 10ciw...

What is a good way to catch the count and make it available to
the function call?

Well, after hacking at it on and off for the last day or two, trying various ideas, this is one of my uglier hacks and abuses of vim's conventions.

function! IncRoman(initial, howmuch)
        " do your own IncRoman stuff here...this
        " just a generic increment
        try
                let l:result = a:initial + a:howmuch
        catch
                let l:result = a:howmuch
        endtry
        return l:result
endfunction

:noremap <c-a> :<home><right><right><right><right><c-u>let howmuch=<end>+1<cr>ciw<c-r>=IncRoman(@-,howmuch)<cr><esc>

This one-liner mapping (in case mailers on either end of things ended up breaking that mapping line) seems to work correctly on various values that I threw at it. If you try to increment a non-number, it will replace it with the increment quantity, which seemed reasonable to me. If you don't like the behavior, you can change the "catch" clause to return what you prefer (either the initial contents, or an empty string would be other good candidates).

It should even be swappable if you have a companion DecRoman function with the same sort of call-signature.

It's a horrible abuse of the fact that vim, when you start typing a count and press the colon, defaults to the range ".,.+x" where "x" is one less than the count given. But it works :)

Funny behaviors may occur is you specify a register as well, such as

        "_5^A

(where ^A is the control+A at hand), though it seems to be pretty smart about matters.

You can't just use <home> followed by 4x <del> statements, but rather you have to go <home> followed by 4x <right> statements and then use <c-u> because otherwise, you end up cancelling the command line. Crazy stuff.

Happy hacking,

-tim



Reply via email to