TransWikia.com

Vim feedkeys in operator pending mode

Vi and Vim Asked by myc3lium on December 26, 2020

I’m trying to build a very simple plugin that allows for pressing a keymapping <Leader>, to call a function that prompts for a single keypress:

function! ControlKey()
    echo "Key → <C-Key> » "
    let l:key = getchar()
    let l:key = ((l:key >= 97 && l:key <= 122) ? l:key - 32 : l:key) - 64
    if l:key < 0 || l:key > 31
        echoerr "Invalid Key Conbination! "
    endif
    call feedkeys(nr2char(l:key), 't') | return ''
endfunction

cnoremap <Leader>, <C-r>=ControlKey()<Cr>
inoremap <Leader>, <C-r>=ControlKey()<Cr>
nnoremap <Leader>, :call ControlKey()<Cr>

The function takes this keypress (for example, a) and then uses feedkeys to send <C-a> (essentially behaving as a sticky control key). This works fine in normal mode, as well as in insert and command (by (ab)using the expression register to make the requisite function call). I run into issues when wanting to use this function in operator pending mode, because I can’t see a way to make make a call to the function that won’t clobber the operator (d,y, etc) expecting a range or motion. Is there a way to achieve this or am I trying to stretch vim too far?

One Answer

I'm not sure if you're having the issue with a mapping for an operator that takes a motion or a mapping for the motion itself...

Either way, you might want to try a different approach by using a :map <expr> together with a recursive mapping, which should be better than using feedkeys() as it's likely to produce less interferences with the following keypresses.

For example:

function! ControlKey()
    let l:key = getchar()
    let l:key = ((l:key >= 97 && l:key <= 122) ? l:key - 32 : l:key) - 64
    if l:key < 0 || l:key > 31
        echoerr "Invalid Key Combination! "
    endif
    return nr2char(l:key)
endfunction

nmap <expr> <Leader>, ControlKey()
omap <expr> <Leader>, ControlKey()

I believe something like this should work better. Try it and see if it solves the problem you're trying to solve.

am I trying to stretch vim too far?

In my opinion, yes. Vim mappings are great to act on Vim operations but not really that great to act on specific keystrokes.

You seem to be trying to replace the Ctrl key. I think it's better if you find a solution for that on your OS's keyboard driver instead. Then that would work regardless of context (Vim mappings depend on the specific context) and it would work not only in Vim, but in other applications as well.

Answered by filbranden on December 26, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP