I trying to bind Ctrl+LeftArrow to backward-word in terminal (no XWindowSystem).

But I observe, that Ctrl+LeftArrow and LeftArrow generate identically escape sequence in terminal:

  1. I press Ctrl+V
  2. I press LeftArrow
  3. I received ^[[D
  4. I press Ctrl+V
  5. I press Ctrl+LeftArrow
  6. I received ^[[D

Same problem with Ctrl+RightArrow. How I can fix it?

(Debian: Linux v4.19.0-8-amd64)

  • 1
    Have you tried using the left CTRL key or the right CTRL key? Possible duplicate here unix.stackexchange.com/questions/5293/…
    – ILMostro_7
    Commented Mar 1, 2020 at 4:09
  • I tried both keys: and left ctrl key and right ctrl key - results are same. Commented Mar 1, 2020 at 4:15
  • which keymap are you using for the console?
    – ILMostro_7
    Commented Mar 1, 2020 at 4:22
  • In my /etc/default/keyboard file KMAP variable is not defined, therefore I guess keymap is XKB layout (default value). Commented Mar 1, 2020 at 4:35
  • It seems that debian uses console-setup to allow you to configure that. Have you tried that?
    – ILMostro_7
    Commented Mar 1, 2020 at 4:49

2 Answers 2


I get ^[[D with left arrow.

Ctrl-left gives ^[[151 in linux VC, and ^[[1;5D in xterm

man keymaps has:

 Which  of  the actions bound to a given key is taken when it is pressed depends on what
   modifiers are in effect at that moment.  The  keyboard  driver  supports  9  modifiers.
   These  modifiers  are  labeled  (completely  arbitrarily)  Shift,  AltGr, Control, Alt,
   ShiftL, ShiftR, CtrlL, CtrlR and CapsShift.  Each of these modifiers has an  associated
   weight of power of two according to the following table:

          modifier            weight

          Shift                  1
          AltGr                  2
          Control                4
          Alt                    8
          ShiftL                16
          ShiftR                32
          CtrlL                 64
          CtrlR                128
          CapsShift            256

I changed it so both "Alt" keys do the same, like Shift and Control do:

Example: Keymaps-file for loadkeys:

# three modifiers -> 8 cols. (AltGr missing):
keymaps 0-1,4-5,8-9,12-13

and then:

# left modifiers
keycode  42 = Shift
keycode  29 = Control
keycode  56 = Alt
keycode  58 = Caps_Lock
# right side...just Alt
keycode  54 = Shift
keycode  97 = Control
keycode 100 = Alt

Normally it is 100=AltGr.

Then I put two additional actions behind the default "Left":

keycode 105 = Left F150 F151
  string F150 = "\033[150"
  string F151 = "\033[151"

this has to be in two steps..."F150" is just a label to connect the modified key with a string.

Now I have my arrow key (105) producing "Left" as before, but shift and control produce the chosen escape sequences.

and then in ~/.inputrc:

# Moving - modif. L+R Arrows in linux VC
# ascii codes in X / evdev / xterm
"\e[150":  backward-word
"\e[1;2D": backward-word
"\e[154":   forward-word
"\e[1;2C":  forward-word

"\e[151":  shell-backward-word
"\e[1;5D": shell-backward-word
"\e[155":   shell-forward-word
"\e[1;5C":  shell-forward-word

Looking back I should have chosen the 1;2D that X produces. That would have saved some inputrc-lines. But these escape sequences seemed a bit opaque to me, so I defined my own ones.

To illustrate the modifier mapping:

# "Print Screen Sys Rq" is Nr 99
keycode 99 =  F91 F92 F93 nul F95 F96
 string F91 = " --help\n"
 string F92 = " |less"
 string F93 = " |grep "
 string F95 = "()\033[D"
 string F96 = "echo \'\033[4~\'"

Now I can hit formerly unused "Print" key to write --help plus the Enter. This works only in linux VC, because X also neglects my "Print" key and I have not found out how to activate it in XKB.

The "nul" entry is the place for "Shift+Control", which by weight comes before "Alt".

keymaps 0-1,4-5,8-9,12-13: counting "0,1,4,5,8" puts weight "8" at fifth place, where "F95" is standing. "8" is defined as "Alt". The missing 2,3,6,7 are because I wanted to skip the AltGr-weight of value 2.

By combining say 10 F-keys with the 8 combinations of only Shift, Control and Alt (no left right) you can get 80 different key functions - if you want. But who wants Shift+Control-F6 to do one thing, and Control+Alt-F9 another?


You rewrite the terminal emulator program that is built into Linux, adding this functionality.

The built-in terminal emulator simply does not include modifier information in any control sequences. In particular, it does not include modifier information in the control sequences for the cursor keypad, as some GUI terminal emulators do.

You will find that there are lots of things that the terminal emulator programs built into operating system kernels, such as Linux and the BSD kernels, do not do compared to GUI terminal emulators and real terminals. (NetBSD's and OpenBSD's user manual for wscons goes into detail with a list of the things that a real DEC VT does that it does not. The doco for Linux is not so helpful.)

You can sort-of get around this by having a keyboard map that defines the cursor keys as (high numbered) programmable function keys, a different function key for each possible combination of modifier, and hand-code all of the function key strings as the appropriate control sequences. This is both tedious and ridiculous, and breaks DECCKM to boot (because the Linux built-in terminal emulator only applies DECCKM to keys that are actually specified as cursor keypad keys in the keyboard map).

There are several user-space terminal emulators that do not require X. I cannot speak for the others, not having checked them, but mine definitely supplies the modifier information in the control sequences. Here's what happens for the chords that you mention:

% cat -v
% console-decode-ecma48 --input
Control+CUB 1
Control+CUF 1
Control+CUU 1
Control+CUD 1
% setterm --appcursorkeys on ; console-decode-ecma48 --input
SS3 'D'
SS3 'C'
SS3 'A'
SS3 'B'
Control+CUB 1
Control+CUF 1
Control+CUU 1
Control+CUD 1

Further reading

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .