You are not logged in.

#1 2016-11-02 17:32:22

belette
Member
Registered: 2014-11-17
Posts: 121

CTRL arrow keys in terminal emulation vs pure tty (virtual console)

Hi,

I am moving to an environment without X but I have some issue regarding key mapping.
On my xfce terminal (xterm) in X I can use arrow keys, Fn arrow keys and cntrl arrow key.
up key is ^[[A
fn up key is ^[[5~
ctrl up key is ^[[1;5A

Doing the same thing in terminal without X (from virtual console)
up key is ^[[A
fn up key is ^[[5~
ctrl up key is ^[[A

Same character are sent regardless if control key is pushed or not.
I have tried different terminal, the default Linux, screen-256color or xterm-256color (from kmscon) but I got the same issue...
I read some topics regarding inputrc but I have tried and no change, I don't know if it is a good direction to solve my issue..

Any idea?
Many thanks

Offline

#2 2016-12-02 20:33:32

hexd
Member
Registered: 2016-06-02
Posts: 3

Re: CTRL arrow keys in terminal emulation vs pure tty (virtual console)

I wanted the Ctrl + left/right arrow keys to behave like Alt+b / Alt+f (the "forward-word" and "backward-word" Emacs functions), and probably the description of what I did to solve that is enough for you to solve that Ctrl + Up problem.

There are 2 places that should be configured for that to work:

  1. You have to map the keys to some specific escape code, creating your own key map and using it as the KEYMAP in /etc/vconsole.conf, this is what your system is probably missing

  2. Every escape code have to be further mapped to a command like "forward-word" and "backward-word", that seems [almost] fine for the codes I'm talking about but perhaps you'll need to update these as well

These are some escaping codes in my /etc/inputrc (I've just included some comments):

# Alt + Right
"\e\e[C": forward-word
# Alt + Left
"\e\e[D": backward-word
# Ctrl + Right
"\e[1;5C": forward-word
# Ctrl + Left
"\e[1;5D": backward-word

I'm not sure why, but it also had these 2 lines:

# Right 5x
"\e[1;5C": forward-word
# Left 5x
"\e[1;5D": backward-word

The behavior when testing these last ones with printf shows they are like pressing the left/arrow keys five times:

$ printf "1234512345\e[5Dabc\n"
12345abc45

The same is written on the Wikipedia page on ANSI escaping. It means that 5 is a magical number that means "a word", does anyone know why?

Anyway, that just gets some ANSI escaping codes and call the matching Emacs function, your problem seem to be the escaping code themselves, not the functions on /etc/inputrc.

When you call:

sudo loadkeys -s br-abnt2

That opens the /usr/share/kbd/keymaps/i386/qwerty/br-abnt2.map.gz file. You can see it in the standard output with:

gzip -cd /usr/share/kbd/keymaps/i386/qwerty/br-abnt2.map.gz

On the other hand, the codes for the arrows that comes from the keybord are the ASCII for "glji":

===== ====== ======= ==== =====
Key   Escape Decimal Hex  ASCII
===== ====== ======= ==== =====
Up    "\e[A" 103     0x67 g
Down  "\e[B" 108     0x6c l
Right "\e[C" 106     0x6a j
Left  "\e[D" 105     0x69 i
===== ====== ======= ==== =====

Let's map the Control + Left combination to the string "Nooooo!", calling loadkeys again:

sudo loadkeys -s br-abnt2 - <<EOF
control keycode 0x69 = F100
string F100 = "Nooooo!"
EOF

That makes Control + Left print that string when pressed. The F100 is an arbitrary unused "key" I saw as an example in "man 5 keymaps".

What you want is simply to change the string to one of the above escaping codes, namely:

sudo loadkeys -s br-abnt2 - <<EOF
control keycode 103 = F103
control keycode 108 = F108
control keycode 106 = F106
control keycode 105 = F105
string F103 = "\033[1;5A"
string F108 = "\033[1;5B"
string F106 = "\033[1;5C"
string F105 = "\033[1;5D"
EOF

The octal "\033" (ASCII 0x11, decimal 27) is the ESC (escape). You can use a simple "\e" when typing in a shell but that didn't work for me when I tried to load the same content from a key map file.

In my case, I solved the problem by matching the key combination with another combination directly instead of using the escaping codes:

gzip > ~/br-abnt2-hexd.map.gz <<EOF
include "br-abnt2.map.gz"
control keycode 0x6a = Meta_f
control keycode 0x69 = Meta_b
EOF

Moving it to /usr/share/kbd/keymaps/i386/qwerty/br-abnt2-hexd.map.gz or creating a symbolic link there is enough to make this /etc/vconsole.conf entry:

KEYMAP=br-abnt2-hexd

Which means it will load that new keymap as default.

Offline

Board footer

Powered by FluxBB