readline icon indicating copy to clipboard operation
readline copied to clipboard

Readline unnecessarily redraws the last line in the terminal

Open knz opened this issue 7 years ago • 1 comments

At CockroachDB we are now using expect to test the SQL shell and this shows all the characters sent by the program to the terminal. In our expect traces we see things like this:

send: sending "select 1;\r" to { exp6 }                                                                                                                                                                                                                                                                                                                
expect: does ":26257>  \u0008" (spawn_id exp6) match glob pattern "1 row"? no
root@:26257> se
expect: does ":26257>  \u0008\u001b[J\u001b[2K\rroot@:26257> s\u001b[J\u001b[2K\rroot@:26257> se" (spawn_id exp6) match glob pattern "1 row"? no                                                                                                                                                                                                      root@:26257> selec
expect: does ":26257>  \u0008\u001b[J\u001b[2K\rroot@:26257> s\u001b[J\u001b[2K\rroot@:26257> se\u001b[J\u001b[2K\rroot@:26257> sel\u001b[J\u001b[2K\rroot@:26257> sele\u001b[J\u001b[2K\rroot@:26257> selec" (spawn_id exp6) match glob pattern "1 row"? no
root@:26257> select 1;
expect: does ":26257>  \u0008\u001b[J\u001b[2K\rroot@:26257> s\u001b[J\u001b[2K\rroot@:26257> se\u001b[J\u001b[2K\rroot@:26257> sel\u001b[J\u001b[2K\rroot@:26257> sele\u001b[J\u001b[2K\rroot@:26257> selec\u001b[J\u001b[2K\rroot@:26257> select\u001b[J\u001b[2K\rroot@:26257> select \u001b[J\u001b[2K\rroot@:26257> select 1\u001b[J\u001b[2K\rro
ot@:26257> select 1;" (spawn_id exp6) match glob pattern "1 row"? no
root@:26257> select 1;

What is happening here, is that after every character typed by the user (received by readline from the terminal), readline issues \033[J\033[2K\r to the terminal then redraws (re-outputs) the prompt and all the characters typed so far.

This is sub-optimal: a redraw should only be necessary when characters previously present in the readline buffer are modified (e.g. when using left-arrow, up-arrow etc). During normal input of non-special characters, this redraw is unnecessary.

Also on slow terminals (like over slow ssh connections) this redraw becomes clearly noticeable to the user for very long inputs.

knz avatar Oct 27 '16 08:10 knz

I can see some usefulness while doing line redraw such as highlighting: capture but the flickering can be somewhat annoying. @chzyer Before I knew this project I wrote a similar one that had the same issue which I solved by: \r*%s*\033[K (%s being the content or prompt + content) unlike \033[2K which deletes entire line, I simple move cursor back '\r', overwrite the content and finally \033[K deleting the rest of the line, no more input flickering

although I'm not sure about \033[K support across the terminals

stdiopt avatar Feb 23 '17 01:02 stdiopt