On a newly installed archlinux, my shells (bash, zsh, tcsh) don’t distinguish arrow key and Ctrl+arrow keys, or Shift+arrow keys.

cat command shows the same code for left arrow, Ctrl+Left arrow or Shift+Left arrow: ^[[D

This is annoying because it prevents me to configure the word-by-word displacement, and the selection of text in shells, but it is not a crucial matter since I still can navigate character by character.

In nano however Ctrl and Shift+arrow work well, with word-by-word displacement and text selection without any trouble.

I precise that it is my first arch-linux install, and I may have forgot basic configuration responsible for this problem.

How make Ctrl/Shift+Arrow detected in my shells?

-- edit to add required information --

zle-line-init() echoti smkx don't solve the problem,

echoti smkx; STTY='-icanon -echo min 0 time 20' od -vtc -tx1 output the following :

no such terminfo capability: smkx
00000000 033    [    D
          1b   5b   44

for both left and ctrl+left,

and for echoti rmkx; STTY='-icanon -echo min 0 time 20' od -vtc -tx1 :

no such terminfo capability: rmkx
00000000 033    [    D
          1b   5b   44

for both left and ctrl+left

I use the default Terminal of Arch-linux, which if my understanding is correct, is call linux (echo $TERM output linux and I have no /etc/inittabl that could mask the true terminal)


2 Answers 2


As the question is posed, this is probably related to the ncurses FAQ My cursor keys do not work.

nano initializes the terminal to application mode, while the shells do not, leaving them in normal mode.

You're not identifying the terminal (emulator), but likely its "normal" mode is incorrectly using CSI (escape-[) rather than SS3 (escape-O).

However, from followup comments, conflicting information is given. The programs (bash, tcsh, zsh) which are given as non-working are unsurprising since none of them uses the terminal database to obtain information on modified keys. Some of this is documented in the xterm manual (Special keys). None of that is documented in any of the shell's manuals. To the extent that it "works", they rely upon literal strings in their configuration. Since zsh (tries to) use the terminal database, but does not read the extended information—see source—there's no luck there.

In a GUI, the default "Terminal" likely is gnome-terminal... which sets TERM to xterm-256color. That (mostly) works, though if there were documentation for gnome-terminal, one would expect to find its quirks duly noted.

nano uses the terminal description; grep'ing for (calls to the function calling) tigetstr shows how it uses this information (see source):

src/nano.c:1233:int get_keycode(const char *keyname, const int standard)
src/nano.c:2389:        controlleft = get_keycode("kLFT5", CONTROL_LEFT);
src/nano.c:2390:        controlright = get_keycode("kRIT5", CONTROL_RIGHT);
src/nano.c:2391:        controlup = get_keycode("kUP5", CONTROL_UP);
src/nano.c:2392:        controldown = get_keycode("kDN5", CONTROL_DOWN);
src/nano.c:2394:        controlhome = get_keycode("kHOM5", CONTROL_HOME);
src/nano.c:2395:        controlend = get_keycode("kEND5", CONTROL_END);
src/nano.c:2397:        controldelete = get_keycode("kDC5", CONTROL_DELETE);
src/nano.c:2398:        controlshiftdelete = get_keycode("kDC6", CONTROL_SHIFT_DELETE);
src/nano.c:2400:        shiftup = get_keycode("kUP", SHIFT_UP);
src/nano.c:2401:        shiftdown = get_keycode("kDN", SHIFT_DOWN);
src/nano.c:2403:        shiftcontrolleft = get_keycode("kLFT6", SHIFT_CONTROL_LEFT);
src/nano.c:2404:        shiftcontrolright = get_keycode("kRIT6", SHIFT_CONTROL_RIGHT);
src/nano.c:2405:        shiftcontrolup = get_keycode("kUP6", SHIFT_CONTROL_UP);
src/nano.c:2406:        shiftcontroldown = get_keycode("kDN6", SHIFT_CONTROL_DOWN);
src/nano.c:2408:        shiftcontrolhome = get_keycode("kHOM6", SHIFT_CONTROL_HOME);
src/nano.c:2409:        shiftcontrolend = get_keycode("kEND6", SHIFT_CONTROL_END);
src/nano.c:2411:        altleft = get_keycode("kLFT3", ALT_LEFT);
src/nano.c:2412:        altright = get_keycode("kRIT3", ALT_RIGHT);
src/nano.c:2413:        altup = get_keycode("kUP3", ALT_UP);
src/nano.c:2414:        altdown = get_keycode("kDN3", ALT_DOWN);
src/nano.c:2416:        altpageup = get_keycode("kPRV3", ALT_PAGEUP);
src/nano.c:2417:        altpagedown = get_keycode("kNXT3", ALT_PAGEDOWN);
src/nano.c:2418:        altinsert = get_keycode("kIC3", ALT_INSERT);
src/nano.c:2419:        altdelete = get_keycode("kDC3", ALT_DELETE);
src/nano.c:2421:        shiftaltleft = get_keycode("kLFT4", SHIFT_ALT_LEFT);
src/nano.c:2422:        shiftaltright = get_keycode("kRIT4", SHIFT_ALT_RIGHT);
src/nano.c:2423:        shiftaltup = get_keycode("kUP4", SHIFT_ALT_UP);
src/nano.c:2424:        shiftaltdown = get_keycode("kDN4", SHIFT_ALT_DOWN);
  • ncurses problem seem to prevent any displacement of the cursor, I don't think this is my problem. The cursor is working in shell and I can use arrow keys to displace the cursor in the commande line. however, ctlr+arrow is interpreted as a single arrow and will displace the cursor from one charactère. I will edit my question to clarify this point. If I have misunderstood the FAQ, could you tell me if I can do anything to correct this problem ?
    – Halphasten
    Dec 16, 2022 at 12:22

I write here the answer provided by Thomas Dickey in comment: what I wanted to do (using ctrl + arrow) is not possible in Linux kernel terminal.

After installing a desktop environment (KDE plasma) and opening a terminal emulator (Konsole) I was able to use modified keys without any problem.

Thank everyone for your help.

You must log in to answer this question.

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