From 174a404dfa323a17852414dfc70b36976eddf6f3 Mon Sep 17 00:00:00 2001 From: Steve Bennett Date: Wed, 25 Jul 2018 20:00:12 +1000 Subject: [PATCH] Re-add delete char optimisation When backspacing at the end of the line, if the row wouldn't change and the previous chars is a simple ascii char and there is no hint to display, simply output \b space \b Signed-off-by: Steve Bennett --- linenoise.c | 56 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/linenoise.c b/linenoise.c index fceecf4..91451f4 100644 --- a/linenoise.c +++ b/linenoise.c @@ -182,7 +182,8 @@ struct current { int cols; /* Size of the window, in chars */ int nrows; /* How many rows are being used in multiline mode (>= 1) */ int rpos; /* The current row containing the cursor - multiline mode only */ - int availcols; /* refreshLine() caches available cols after the prompt here */ + int colsright; /* refreshLine() cached cols for insert_char() optimisation */ + int colsleft; /* refreshLine() cached cols for remove_char() optimisation */ const char *prompt; stringbuf *capture; /* capture buffer, or NULL for none. Always null terminated */ stringbuf *output; /* used only during refreshLine() - output accumulator */ @@ -1217,19 +1218,22 @@ static void refreshLineAlt(struct current *current, const char *prompt, const ch cursorrow = displayrow; } - DRL("\nafter buf: displaycol=%d, displayrow=%d, cursorcol=%d, cursorrow=%d\n\n", displaycol, displayrow, cursorcol, cursorrow); + DRL("\nafter buf: displaycol=%d, displayrow=%d, cursorcol=%d, cursorrow=%d\n", displaycol, displayrow, cursorcol, cursorrow); /* (f) show hints */ hint = refreshShowHints(current, buf, current->cols - displaycol, 1); /* Remember how many many cols are available for insert optimisation */ if (prompt == current->prompt && hint == 0) { - current->availcols = current->cols - displaycol; + current->colsright = current->cols - displaycol; + current->colsleft = displaycol; } else { /* Can't optimise */ - current->availcols = 0; + current->colsright = 0; + current->colsleft = 0; } + DRL("\nafter hints: colsleft=%d, colsright=%d\n\n", current->colsleft, current->colsright); refreshEndChars(current); @@ -1274,16 +1278,47 @@ static int remove_char(struct current *current, int pos) if (pos >= 0 && pos < sb_chars(current->buf)) { int offset = utf8_index(sb_str(current->buf), pos); int nbytes = utf8_index(sb_str(current->buf) + offset, 1); + int rc = 1; - /* Note that we no longer try to optimise the remove-at-end case - * since control characters and wide characters mess - * up the simple count + /* Now we try to optimise in the simple but very common case that: + * - we are remove the char at EOL + * - the buffer is not empty + * - there are columns available to the left + * - the char being deleted is not a wide or utf-8 character + * - no hints are being shown */ + if (current->pos == pos + 1 && current->pos == sb_chars(current->buf) && pos > 0) { +#ifdef USE_UTF8 + /* Could implement utf8_prev_len() but simplest just to not optimise this case */ + char last = sb_str(current->buf)[offset]; +#else + char last = 0; +#endif + if (current->colsleft > 0 && (last & 0x80) == 0) { + /* Have cols on the left and not a UTF-8 char or continuation */ + /* Yes, can optimise */ + current->colsleft--; + current->colsright++; + rc = 2; + } + } + sb_delete(current->buf, offset, nbytes); if (current->pos > pos) { current->pos--; } + if (rc == 2) { + if (refreshShowHints(current, sb_str(current->buf), current->colsright, 0)) { + /* A hint needs to be shown, so can't optimise after all */ + rc = 1; + } + else { + /* optimised output */ + outputChars(current, "\b \b", 3); + } + } + return rc; return 1; } return 0; @@ -1313,9 +1348,10 @@ static int insert_char(struct current *current, int pos, int ch) */ if (pos == current->pos && pos == sb_chars(current->buf)) { int width = char_display_width(ch); - if (current->availcols > width) { + if (current->colsright > width) { /* Yes, can optimise */ - current->availcols -= width; + current->colsright -= width; + current->colsleft -= width; rc = 2; } } @@ -1324,7 +1360,7 @@ static int insert_char(struct current *current, int pos, int ch) current->pos++; } if (rc == 2) { - if (refreshShowHints(current, sb_str(current->buf), current->availcols, 0)) { + if (refreshShowHints(current, sb_str(current->buf), current->colsright, 0)) { /* A hint needs to be shown, so can't optimise after all */ rc = 1; } -- 2.44.0