5

I was writing a small plugin, when I decided that I should give the option of customizing which key triggers the plugin's function. Here is an example of this:

let g:foo_key = "\<Tab>"

While this works for part of the plugin's functionality, I also need that variable as a literal string, which would be '\<Tab>' in this case. Is it possible to convert from the resulting key code to a literal string? Is there a standard way of handling this kind of option?

5
  • I'm not sure I understand your question, but you might find useful the string() function. Combined with eval(), it makes it easy to pass things around without bending over backwards to quote values. You can see it at work f.i. here.
    – lcd047
    Commented May 28, 2015 at 13:50
  • I was afraid that I hadn't worded the question properly, but I don't really know how to make it clearer. Feel free to edit it. Commented May 28, 2015 at 13:55
  • Sorry, that wasn't a snark, I'm genuinely not sure I understand what you're trying to do (so I wouldn't know how to edit your question). Just pointing to string() as useful in general, not necessarily here.
    – lcd047
    Commented May 28, 2015 at 13:58
  • If this helps at all, I am essentially wanting to convert a literal string (in single quotes) to a normal string (in double quotes) or vice versa. The difference between literal strings and normal strings is that normal strings allow for special characters, whereas literal strings don't. Commented May 28, 2015 at 14:11
  • That's a level of indirection I always try to avoid. It's usually possible, with string(): assignment: let foobar="foo\tbar", direct use: :echo foobar, passing it along: :exec 'echo ' . string(foobar). Things can get hairy when writing complicated sort functions, or functions for filter(), map(), and the like. But even then, string() avoids a lot of complexity.
    – lcd047
    Commented May 28, 2015 at 14:45

1 Answer 1

4

The hex value of g:foo_key will be 0x09 (a tab). You can use the strtrans() function to get a readable representation of this:

:echo strtrans("\<Tab>")
<09>

Note that this prints <09>, and not <Tab>. They are the same, and there is no way to know which one the user has entered. It may also show up as ^I (depends on value of display).
Getting the key name is not something I can figure out how to do with a simple function call, but in the key_name_entry struct in misc2.c you can find a list of keynames; making a function for this is easy:

let g:chars = {
    \ '<09>': '<Tab>',
    \ '<1b>': '<Esc>',
\ }

fun! StringTrans(char)
    if get(g:chars, a:char, -1) != -1
        return g:chars[a:char]
    else
        return strtrans(a:char)
    endif
endfun

You probably want to expand g:chars; note that you have to type the literal hex value with <C-v><Tab>, <C-v><Esc>, etc.

Note that this still won't return exactly what the user has typed, since there are multiple names for some characters (for example <NL>, <LF>, <Newline>, and <Linefeed> are all the same).


Doing the reverse with eval() is perhaps easier:

:let foo = '\<Tab>'
:echo foo
\<Tab>

:let foo_expanded =  eval('"' . foo . '"')
:echo strtrans(foo_expanded)
<09>
1
  • I figured that it would just be easier to use a literal string in the first place. Very helpful! Commented May 28, 2015 at 13:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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