简体   繁体   中英

Terminfo: left arrow is mapped to backspace code (8) on default OSX terminal. Why is it so? And how to change it?

I am writing simple terminal so I am trying to understand some basic things about control symbols, escape sequences and how all that is related to terminfo and termios.

What I find awkward is that according to the input I have from tty and according to tput left key is mapped to Backspace code (ASCII code 8)

tput cub1 | od -tx1
0000000    08                                                            
0000001

while I would expect it to be \\033[D because

$ tput cuf1 | od -tx1
0000000    1b  5b  43                                                    
0000003

which is \\033[C code that is right key indeed according to various documents about terminal codes.

So the absence of symmetry here is quite confusing to me. Is there a specific reason behind it?

The second question: is there way to change it?

I have created example of raw terminal which demonstrates this behaviour: RawTerminal .

The cub1 capability is not left arrow , but instead a cursor movement capability. Referring to terminfo(5) , you may find

   cursor_left               cub1   le   move left one space

which is named similarly to the key marked "left-arrow":

   key_left                  kcub1  kl   left-arrow key

The cursor-movement capabilities do just that: move the cursor around on the screen. In some cases, the similarly-named cursor-movement and cursor-keys have the same string, just because (long ago) it was useful to have keys which one could setup to echo locally (rather than send to a host application).

In this particular case, the two are different because the main use of these terminal descriptions is for curses applications, which minimize the number of characters sent to the screen (as well as minimizing the time spent sending the characters). Making cub1 send an ASCII backspace is fewer characters than the escape sequence.

While there is no requirement, longstanding convention tells you that terminfo capabilities which begin with "k" are probably for the keyboard.

bash uses readline for reading keys and updating the line which you are typing on. Checking its source-code, eg, from bash-4.2 I am looking at lib/readline/terminal.c, it has a table of the termcap strings that it may use:

    static const struct _tc_string tc_strings[] =
    {
      { "@7", &_rl_term_at7 },
      { "DC", &_rl_term_DC },
      { "IC", &_rl_term_IC },
      { "ce", &_rl_term_clreol },
      { "cl", &_rl_term_clrpag },
      { "cr", &_rl_term_cr },
      { "dc", &_rl_term_dc },
      { "ei", &_rl_term_ei },
      { "ic", &_rl_term_ic },
      { "im", &_rl_term_im },
      { "kD", &_rl_term_kD },        /* delete */
      { "kH", &_rl_term_kH },        /* home down ?? */
      { "kI", &_rl_term_kI },        /* insert */
      { "kd", &_rl_term_kd },
      { "ke", &_rl_term_ke },        /* end keypad mode */
      { "kh", &_rl_term_kh },        /* home */
      { "kl", &_rl_term_kl },
      { "kr", &_rl_term_kr },
      { "ks", &_rl_term_ks },        /* start keypad mode */
      { "ku", &_rl_term_ku },
      { "le", &_rl_term_backspace },
      { "mm", &_rl_term_mm },
      { "mo", &_rl_term_mo },
      { "nd", &_rl_term_forward_char },
      { "pc", &_rl_term_pc },
      { "up", &_rl_term_up },
      { "vb", &_rl_visible_bell },
      { "vs", &_rl_term_vs },
      { "ve", &_rl_term_ve },
    };

Using "infocmp -Cr xterm", I can see this:

xterm|xterm terminal emulator (X Window System):\
        :am:bs:km:mi:msn:\
        :co#80:it#8:li#24:\
        :AL=\E[%dLC=\E[%dPL=\E[%dMO=\E[%dB:IC=\E[%d@:\
        :K2=\EOE:LE=\E[%dD:RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:\
        :UP=\E[%dA:ae=\E(B:al=\E[L:as=\E(0:bl=^G:bt=\E[Z:cd=\E[J:\
        :ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\
        :cs=\E[%i%d;%dr:ct=\E[3gc=\E[Pl=\E[Mo=^J:ec=\E[%dX:\
        :ei=\E[4l:ho=\E[H:im=\E[4h:is=\E[!p\E[?3;4l\E[4l\E>:\
        :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:\
        :k7=\E[18~:k8=\E[19~:k9=\E[20~:kD=\E[3~:kI=\E[2~:kN=\E[6~:\
        :kP=\E[5~:kb=\177:kd=\EOB:ke=\E[?1l\E>:kh=\EOH:kl=\EOD:\
        :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:mb=\E[5m:md=\E[1m:\
        :me=\E[0m:mh=\E[2m:mm=\E[?1034h:mo=\E[?1034l:mr=\E[7m:\
        :nd=\E[C:rc=\E8:sc=\E7:se=\E[27m:sf=^J:so=\E[7m:sr=\EM:\
        :st=\EH:ta=^I:te=\E[?1049l:ti=\E[?1049h:ue=\E[24m:up=\E[A:\
        :us=\E[4m:vb=\E[?5h\E[?5l:ve=\E[?12l\E[?25h:vi=\E[?25l:\
        :vs=\E[?12;25h:

or with "infocmp -Cr nsterm":

nsterm|Apple_Terminal|AppKit Terminal.app:\
        :am:hs:mi:msno:\
        :co#80:it#8:li#24:ws#50:\
        :AL=\E[%dLC=\E[%dPL=\E[%dMO=\E[%dB:IC=\E[%d@:\
        :K1=\EOq:K2=\EOr:K3=\EOs:K4=\EOp:K5=\EOn:LE=\E[%dD:\
        :RI=\E[%dC:UP=\E[%dA:ae=^O:al=\E[L:as=^N:bl=^G:cd=\E[J:\
        :ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\
        :ct=\E[3gc=\E[Pl=\E[Mo=^Js=\E]2;\007:ei=\E[4l:\
        :fs=^G:ho=\E[H:ic=\E[@:im=\E[4h:k1=\EOP:k2=\EOQ:k3=\EOR:\
        :k4=\EOS:k5=\E[15~:k6=\E[17~:k7=\E[18~:k8=\E[19~:\
        :k9=\E[20~:kD=\E[3~:kN=\E[6~:kP=\E[5~:kb=\177:kd=\EOB:\
        :ke=\E[?1l\E>:kh=\EOH:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:\
        :ku=\EOA:le=^H:mb=\E[5m:md=\E[1m:me=\E[0m:mh=\E[2m:\
        :mr=\E[7m:nd=\E[C:rc=\E8:\
        :rs=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:sc=\E7:se=\E[m:\
        :sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:te=\E[2J\E[?47l\E8:\
        :ti=\E7\E[?47h:ts=\E]2;:ue=\E[m:up=\E[A:us=\E[4m:\
        :vb=\E[?5h\E[?5l:ve=\E[?25h:vi=\E[?25l:

The ":le=^H:" part is what you are seeing.

From (ncurses) terminfo(5):

   cursor_left                   cub1       le        move left one space

if you made a termcap (for "xterm") setting that to \\e[D, then bash should echo back \\e[D rather than ^H . But ncurses uses ^H to reduce the number of characters from from 3 ( \\e[D ) to 1 ( ^H )

Rather than modify the terminal description, you should modify your program, eg, to read the termcap strings and handle those.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM