diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-11-01 07:09:35 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-11-01 07:09:35 -0700 |
commit | 2c6829c7fdda6d45722dc93e510e2ebbc80ce7bb (patch) | |
tree | 1b80192635f2c88da7a28b7ddd070094195f4a29 | |
parent | bf85503bb9d2a52d9d3ddb86ae08fe6de0705e1f (diff) | |
download | txr-2c6829c7fdda6d45722dc93e510e2ebbc80ce7bb.tar.gz txr-2c6829c7fdda6d45722dc93e510e2ebbc80ce7bb.tar.bz2 txr-2c6829c7fdda6d45722dc93e510e2ebbc80ce7bb.zip |
linenoise: avoid refresh in paren matching.
* linenoise/linenoise.c (move_cursor_multiline, move_cursor):
New functions.
(paren_jump): Use move_cursor rather than refresh_line.
In multi-line mode, this calculates the required cursor
movement and emits the escape sequences to make it happen,
without issuing a refresh, sending way less data to the
terminal.
-rw-r--r-- | linenoise/linenoise.c | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/linenoise/linenoise.c b/linenoise/linenoise.c index 4d89591e..817d1698 100644 --- a/linenoise/linenoise.c +++ b/linenoise/linenoise.c @@ -1237,6 +1237,51 @@ static void refresh_line(lino_t *ls) { ls->need_refresh = 0; } +static void move_cursor_multiline(lino_t *l, int npos) +{ + wchar_t seq[64]; + struct abuf ab; + struct row_values ro = (sync_data_to_buf(l), + screen_rows(l->buf, l->pos, l->cols)); + int odp = l->pos; + struct row_values rn = (l->dpos = npos, + sync_data_to_buf(l), + screen_rows(l->buf, l->pos, l->cols)); + int ndp = l->pos; + int orow = ro.rows[1]; + int nrow = rn.rows[1]; + int ocol = col_offset_in_str(l->buf, odp, l->cols); + int ncol = col_offset_in_str(l->buf, ndp, l->cols); + + ab_init(&ab); + + if (nrow != orow) { + wcsnprintf(seq, 64, L"\x1b[%d%S", abs(orow - nrow), + (nrow < orow) ? L"A" : L"B"); + ab_append(&ab, seq, wcslen(seq)); + } + + if (ncol != ocol) { + wcsnprintf(seq, 64, L"\x1b[%d%S", abs(ocol - ncol), + (ncol < ocol) ? L"D" : L"C"); + ab_append(&ab, seq, wcslen(seq)); + } + + (void) lino_os.puts_fn(l->tty_ofs, ab.b); + ab_free(&ab); + l->dpos = npos; +} + +static void move_cursor(lino_t *l, int npos) +{ + if (l->mlmode) { + move_cursor_multiline(l, npos); + } else { + l->dpos = npos; + refresh_line(l); + } +} + static int scan_match_rev(const wchar_t *s, int i, wchar_t mch) { while (i > 0) { @@ -1404,11 +1449,13 @@ static void paren_jump(lino_t *l) if (pos != -1) { int dp = l->dpos; - l->dpos = pos; - refresh_line(l); + if (usec_delay(l, 0)) + return; + if (l->need_refresh) + refresh_line(l); + move_cursor(l, pos); usec_delay(l, LINENOISE_PAREN_DELAY); - l->dpos = dp; - l->need_refresh = 1; + move_cursor(l, dp); } } |