TUI applications or more generally applications that handle keyboard input by themselves have to disable both the line discipline own line editor (ICANON
) and local echo (ECHO
) as they need to read the characters sent upon key presses as them come and do their own echo
.
Those applications, upon startup change the termios settings and upon leaving (or suspension) restore them.
readline (the line editor used by bash) and zle (the zsh line editor) are no exception.
Those line editors are started when the shell issues its prompt and stopped when you execute a command.
So, when you run stty -a
or any other command, you don't see the termios setting as used within readline / zle, you see the ones as restored by them when they left.
When ECHO
is on, input from the terminal is echoed back, but for control characters there are two other things to take into account, and a third one for arrow keys specifically:
- if
ICANON
is on (as it is by default), the line discipline internal line editor will intercept some control characters such as BS or DEL, ^W
, ^U
for their own line editing. ESC (the first character sent upon arrow keys is generally not of those though).
- if
ECHOCTL
is also on (which it also generally is by default), control chacters are echoed as ^X
instead of as-is.
- terminals often can send different escape sequences whether they're in "keypad transmit" mode or not. You'll notice that after
tput smkx
, the Up key sends \eOA
and after tput rmkx
, it sends the \e[A
sequence, which happens to correspond to the sequence to move the cursor up (same as sent by tput cuu1
). There are other modes supported by some terminals that affect what is send upon key presses which we won't discuss here.
So, for the terminal discipline local echo to move the cursor around when you press the arrow keys, you'd need:
tput rmkx; stty -icanon echo -echoctl; cat > /dev/null
stty -echo
, the terminal will just not print back what you are writting. if you writereset
and enter it will just execute the reset commands and restore the eco setting. ZSH: it just set echo again (the|
means set, which may be the reset you are writing, but let's be explicit: it always set echo)