3

Foreword

I use UltiSnips and have the following definitions in my .vimrc file

let g:UltiSnipsExpandTrigger="<F8>"
let g:UltiSnipsJumpForwardTrigger="<F8>"
let g:UltiSnipsJumpBackwardTrigger="<S-F8>"

The problem

The third definition doesn't work; the strange behavior I witness is that +F8 switches the case of the letter under the cursor and that after it and move to the next char just as I had hit 2~ in normal mode.

Troubleshooting

Mindful of another strange keyboard behavior I experienced in the bash with fzf, I decided to investigate which escape sequence is sent when I press (shifted) function keys, by issuing them in the terminal prepended by +V. What I "discovered" is that +F8 sends ^[[32~, which is the same escape sequence sent by Esc[32~, which indeed does the following:

  • Esc exits UltiSnips' select mode, thus returning to normal mode
  • [3 do nothing since the latter "kills" the former, which doesn't expect a digit after it
  • 2~ switch the case of under-cursor and immediately-after-cursor letters and moves to next character

which is what I see happening everytime.

Furthermore, I've checked that function keys from F1 to F4 send ^[[11~ ^[[12~ ^[[13~ ^[[14~ whereas combinations from +F1 to +F4 send ^[[23~ ^[[24~ ^[[25~ ^[[26~; based on these escape sequences I'd expect all these keys to misbehave (in the same way too, except for the count), but they don't! Of the aforementioned 8 combinations, only +F3 switches the case of the following 5 letters (as the ^[[5~ escape sequence implies), and the others do nothing (they don't even exit the select mode!).

Info

I use URxvt, $TERM is rxvt-unicode-256color and Vim version is 8.1.

Related question(s) and pages

The first time I had this problem was long ago and I searched for an answer already; since then I've forgotted I had found a related (actually exactly the same) question but it was and is still unanswered (maybe this is way I've forgotten it).

Here is a related wikipage.

Here is a related issue on GitHub.

  • 1
    what happens if you do :set <s-f8>=^[[32~? to type this, type :set <s-f8>= then press ctrl-v shift-f8. this should make <s-f8> work properly – Mass Aug 30 '18 at 15:48
  • With the first shot, man! Can you explain me why is this necessary? After all, the misbehavior of some shifted function keys is "coherent" with the sequence they generate. What I mean is that I would have said that :set <s-f8>=^[[32~ does exactly what is already done. But it's clearly not the case, since your answer works! – Enrico Maria De Angelis Aug 30 '18 at 15:56
  • what terminal emulator do you use and what specific version of vim, and what is $TERM? the very short answer is that vim needs to guess what all the keys are and sometimes guesses wrong, and it's all not completely standardized. I can probably give more detail in an answer if I knew some more information – Mass Aug 30 '18 at 16:07
  • @Mass, added some info. – Enrico Maria De Angelis Aug 30 '18 at 16:10
3

The codes which keys produce varies wildly by terminal. vim tries to guess which escape sequences corresponds to which keycodes (<f1> etc) based on the $TERM variable and terminfo. The shifted f-keys are not standardized and they do not have termcap/terminfo entries. In this case, vim falls back to the xterm ones. Note, wherever ^[ is written, this means a literal escape character.

Changing vim's key codes

For many keys, vim has a key code for it of the form <..>. This includes the shifted f-keys, <s-f1>..<s-f37>. The way to change this for your terminal is through set (the following are equivalent):

set <s-f1>=^[[23~
execute "set <s-f1>=\<esc>[23~"

Some keys do not have a named key code, such as <s-enter>. In this case, vim provides many extra function keys, up to <f37> which you can use, if your terminal supports it. As usual, you can grab the key code by typing it after ctrl-v or with cat.

set <f37>=^[OM
execute "set <f37>=\<esc>OM"

Then you can use <f37> in place of <s-enter> whenever you want to use that key.

Explaining the original behavior

Below is a list of the keys in urxvt and xterm, produced by running cat in a shell then typing each key (except for f13/f14 which comes from infocmp).

In urxvt, shift-f1 and shift-f2 are exactly identical to f11 and f12. Therefore, by default, you cannot use both for different things. This also explains why shift-f1 and shift-f2 did not produce the case changing behavior you saw- vim thought they were some other key.

Likewise, shift-f4 in urvt is the same as f14. I'm not sure why but vim thinks this is the <undo> key, which is t_&8=^[[26;*~, close but not quite the same as f14.

Table

              urxvt       xterm

f1           ^[[11~       ^[OP
f2           ^[[12~       ^[OQ
f3           ^[[13~       ^[OR
f4           ^[[14~       ^[OS

f5           ^[[15~       ^[[15~
f6           ^[[17~       ^[[17~
f7           ^[[18~       ^[[18~
f8           ^[[19~       ^[[19~

f9           ^[[20~       ^[[20~
f10          ^[[21~       ^[[21~
f11          ^[[23~       ^[[23~
f12          ^[[24~       ^[[24~
f13          ^[[25~
f14          ^[[26~

shift-f1     ^[[23~       ^[[1;2P 
shift-f2     ^[[24~       ^[[1;2Q 
shift-f3     ^[[25~       ^[[1;2R 
shift-f4     ^[[26~       ^[[1;2S 

shift-f5     ^[[28~       ^[[15;2~
shift-f6     ^[[29~       ^[[17;2~
shift-f7     ^[[31~       ^[[18;2~
shift-f8     ^[[32~       ^[[19;2~

shift-f9     ^[[33~       ^[[20;2~
shift-f10    ^[[34~       ^[[21;2~
shift-f11    ^[[23$       ^[[23;2~
shift-f12    ^[[24$       ^[[24;2~
  • I notice that in the table there are more identical escape sequences than you referred to in Explaining the original behavior. Have you just picked some of them for brevity or am I missing something? – Enrico Maria De Angelis Sep 2 '18 at 7:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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