drmikehenry / vim-fixkey

https://github.com/drmikehenry/
125 stars 10 forks source link

C-F12 not working in vim #12

Closed boulderob closed 4 years ago

boulderob commented 4 years ago

hello. i came here via a stack post. i'm using vim8 on mac sierra. i'm trying to get it to recognize but it doesn't recognize that combo with the modifier key Ctl.

i can see that this combo produces ^[[24^ in my stock terminal and in insert mode in vim. i can also see that the mac terminal is generating that key sequence in it's own profile config.

instead of installing and using your plugin which is overkill for the one key seq i want to configure for vim, i want to borrow from it and just use the one line i need which is this (btw i believe you documented this in your stack post as well)

the problem is when i try to use this incantation, vim doesn't recognize the line as a valid line because it thinks it's an invalid option no matter how many different ways i've tried to enter it.

 set <C-F12>=^[[24^
 set <C-F12>=\e[24^
 execute "set <C-F12>=^[[24^"
 execute "set <C-F12>=\e[24^"

it obviously is tripping up on the fact that <C-F12> doesn't look like a known vim option and i would agree but your entire plugin is based on it working! :) i'm probably missing something really simple.

any and all thoughts greatly appreciated thx

drmikehenry commented 4 years ago

Vim support for key codes can be spotty. In :help terminal-key-codes there is a (partial) list of key codes that can be configured using the set command. Function keys that are completely unmodified are supported (<F12>, for example), as are shifted function keys (<S-F12>); but function keys with the control modifier aren't supported. As shown in :help xterm-modifier-keys, Vim tries to avoid defining all combinations of modifiers for all keys, and instead uses a special sequence (;*X) at the end of the corresponding unmodified key.

For Xterm on my Linux system, the default key code for <F12> is shown as follows:

set <F12>

This displays as:

^[[24;*~

The first two characters (^[) are shown in a different color, indicating that they represent pressing control with [; this is another name for the Escape character. Note the extra ;*~ at the end of the sequence. This means that Xterm uses <Escape>[24~ for the unmodified key, and that modifiers will extend this sequence based on the particular modifier. For the shift modifier, the result is <Escape>[24;2~ (there is an extra ;2 inserted before the final character of the key code).

For key codes that Vim supports directly using the :set command, teaching Vim how to recognize a key code is mostly straightforward. As an example, make the following two mappings to make it easy to see when <F5> and <F6> are pressed:

:map <F5> :echo '<F5>'<CR>
:map <F6> :echo '<F6>'<CR>

Now pressing <F5> or <F6> should echo the key name.

Typing :set <F5> yields ^[[15;*~, and :set <F6> yields ^[[17;*~. For demonstration purposes, these codes may be swapped as follows:

:execute "set <F5>=\e[17;*~"
:execute "set <F6>=\e[15;*~"

Note the use of execute above. This is just for the convenience of using double-quoted strings that expand the two characters \e into the Escape code, rather than having to enter the actual key code directly (by pressing CTRL-v Escape, for example).

You should be able to do the same thing on your Mac, adjusting for whatever key codes these keys produce.

Things get harder for keys whose key codes aren't directly supported with :set. Function keys using the control modifier fall in this category, so it's not possible to do :set <C-F12>. This is despite the fact that the syntax <C-F12> is valid within mappings, because mappings and key codes are two different things to Vim.

The hack I use in Fixkey is to find a key that isn't used on typical keyboards, change the key code for that key, and then map that key to the unsupported key. For historical reasons, Vim supports numbered function keys beyond <F12>. The keys <F13> through <F-37> known to Vim, along with their shifted counterparts. Modern keyboards lack these keys, so Fixkey uses them as described above.

For your case, you might be able to make <C-F12> work by setting the key code for <F13> to be your sequence ^[[24^, and then map <F13> to <C-F12>:

:execute "set <F13>=\e[24^"
:map <F13> <C-F12>
:map! <F13> <C-F12>

As before, execute allows the use of \e for Escape. The :map and :map! combination ensures mapping in all of Vim's modes. Within Fixkey itself, the function Fixkey_setNewKey() allocates a spare key from the range of unused function keys, sets the desired key code using :set, then performs the two mappings as shown above.

boulderob commented 4 years ago

@drmikehenry much appreciate your very detailed followup! while i was waiting for your reply, i actually dug a bit deeper on my own and actually came to the same conclusion and wound up doing exactly what you suggested above except that i instead mapped SF12 which i wasn't actually using in vim but vim supported to a terminal key code that was assigned to C-F12. that was the glue that tied it together and made it work.

the example i just described was just a test to see if i could do it but it actually winds up eating up a valid S-F12. the fact that i can use the F13 and greater keys as you describe is a great way to trick vim into doing what i want though without burning up S-F<#> keys that i might use for other purposes.

two final questions:

i had to change a lot of keys in my mac terminal profile b/c unlike vim, tmux expects certain chars to already be mapped to what i would call certain "logical key combos".. so you can't set the key codes in tmux, you have to remap what the terminal app sends to match what tmux wants.

i haven't crossed this bridge yet but my question is, do you have any suggestions on how to best configure or handle the platform specific terminal key settings for different console / terminal apps? i can create different profiles for mac terminal.. but i'm not sure where it even saves them or if i can manually edit them in a text file?.. instead i had to click on a each set of keys i wanted to change in the terminal app individually and manually set each one. it's slow and prone to error.

like i said i'm envisioning having to do this for multiple terminal apps on multiple platforms and want a way to just have a single text file i can edit by hand for each terminal / platform configuration? i'm mostly a grand consumer of terminals and consoles for two decades and i've never had to screw with any of this key stuff until now so i'm not sure what configuration actually exists for what i want to do. since it's linux my guess is it's available though.

any thoughts welcome if you've crossed this bridge already. regardless thanks for the information above.

drmikehenry commented 4 years ago

@boulderob I replied a few days ago but it looks like I did something wrong and the comment didn't take. The quick summary of my lost comment is that I think I probably first heard about function keys beyond F12 from the Vim mailing list, but I expect I confirmed the range from the Vim source, e.g.: https://github.com/vim/vim/blob/c6d539b67181ad573452e919e58ecbfa362f4c49/src/keymap.h#L313-L352

For my own needs, KDE Konsole works well enough without configuration, so I've just stuck with that terminal emulator. I don't blame you for wanting a command-line interface for configuring your terminal(s) of choice, but the best I've got is to suggest searching on the terminal name and keywords like configuration, command line, and perhaps plist on OS X.

boulderob commented 4 years ago

thx @drmikehenry once again for the followup. have a great year!

drmikehenry commented 4 years ago

@boulderob You're welcome, and good luck in your quest for terminal happiness :-)