@@ -57,6 +57,25 @@ STATIC char *str_dup_maybe(const char *str) {
5757 return s2 ;
5858}
5959
60+ STATIC void move_cursor_back (uint pos ) {
61+ if (pos <= 4 ) {
62+ // fast path for most common case of 1 step back
63+ stdout_tx_strn ("\b\b\b\b" , pos );
64+ } else {
65+ char vt100_command [6 ];
66+ // snprintf needs space for the terminating null character
67+ int n = snprintf (& vt100_command [0 ], sizeof (vt100_command ), "\x1b[%u" , pos );
68+ if (n > 0 ) {
69+ vt100_command [n ] = 'D' ; // replace null char
70+ stdout_tx_strn (vt100_command , n + 1 );
71+ }
72+ }
73+ }
74+
75+ STATIC void erase_line_from_cursor (void ) {
76+ stdout_tx_strn ("\x1b[K" , 3 );
77+ }
78+
6079typedef struct _readline_t {
6180 vstr_t * line ;
6281 int orig_line_len ;
@@ -66,7 +85,7 @@ typedef struct _readline_t {
6685 char escape_seq_buf [1 ];
6786} readline_t ;
6887
69- readline_t rl ;
88+ STATIC readline_t rl ;
7089
7190int readline_process_char (int c ) {
7291 int last_line_len = rl .line -> len ;
@@ -215,30 +234,20 @@ int readline_process_char(int c) {
215234 }
216235
217236 // redraw command prompt, efficiently
218- // TODO we can probably use some more sophisticated VT100 commands here
219237 if (redraw_step_back > 0 ) {
220- for (int i = 0 ; i < redraw_step_back ; i ++ ) {
221- stdout_tx_str ("\b" );
222- }
238+ move_cursor_back (redraw_step_back );
223239 rl .cursor_pos -= redraw_step_back ;
224240 }
225241 if (redraw_from_cursor ) {
226242 if (rl .line -> len < last_line_len ) {
227243 // erase old chars
228- for (int i = rl .cursor_pos ; i < last_line_len ; i ++ ) {
229- stdout_tx_str (" " );
230- }
231- // step back
232- for (int i = rl .cursor_pos ; i < last_line_len ; i ++ ) {
233- stdout_tx_str ("\b" );
234- }
244+ // (number of chars to erase: last_line_len - rl.cursor_pos)
245+ erase_line_from_cursor ();
235246 }
236247 // draw new chars
237248 stdout_tx_strn (rl .line -> buf + rl .cursor_pos , rl .line -> len - rl .cursor_pos );
238249 // move cursor forward if needed (already moved forward by length of line, so move it back)
239- for (int i = rl .cursor_pos + redraw_step_forward ; i < rl .line -> len ; i ++ ) {
240- stdout_tx_str ("\b" );
241- }
250+ move_cursor_back (rl .line -> len - (rl .cursor_pos + redraw_step_forward ));
242251 rl .cursor_pos += redraw_step_forward ;
243252 } else if (redraw_step_forward > 0 ) {
244253 // draw over old chars to move cursor forwards
0 commit comments