Is there some way that I can convert the string <C-a> into the key code that's presented by \<C-a> dynamically in Vimscript? I want to make <C-a> an option the user can specify for a binding, but detect \<C-a> at runtime by examining the result of getchar(). Is this possible?
1 Answer
I do not understand, what’s the problem with getchar()? If you need string out of it you usually write something like
let char=getchar()
if type(char)==type(0)
let char=nr2char(char)
endif
and compare it as usual:
if char is# "\<C-a>"
…
endif
. If you need the right side of comparison be some user-defined variable it is not a problem, just tell users to use let g:var="\<C-a>" in place of let g:var="<C-a>". Though using latter is also possible: the following trick will transform "<C-a>" into "\<C-a>":
let string=eval('"'.escape(string, '\"<').'"')
4 Comments
terryma
Thanks! I wanted to do exactly
let g:var="<C-a>" instead of let g:var="\<C-a>" since I want to use the variable in a map command as well as comparing it with the result of getchar() like you described above. Your last command works perfectly! Didn't know about eval() before. I ended up using exec 'let string = "\'.'<C-a>'.'"' which also seems to work, but I like your way much better!ZyX
@terryma
noremap ^A (where ^A is raw control character) works just as good as noremap <C-a>. You don’t need to use <> notation in *map commands. In fact, they even will not work if some vi compatibility settings are turned on (never seen them turned on on other people setups though).ZyX
@terryma The only case where you will be forced to use
<> notation is space in lhs.terryma
This didn't work for some users of my plugin when they tried to map command key in Mac. For example
"\<D-D>" was causing issues for some users and <D-D> worked. The only way I found to resolve their issue was to let them map <D-D> but convert it to "\<D-D>" inside the plugin where I need to compare it with the result of getchar()