From e06b774174649fd79cd7bc8ca946879ba4829c7a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 13 Feb 2022 17:33:13 +0530 Subject: [PATCH] Avoid double scan of output to look for escape codes --- kitty/line.c | 10 ++++++---- kitty/lineops.h | 2 +- kitty/screen.c | 5 +---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/kitty/line.c b/kitty/line.c index 082affee5..db2942093 100644 --- a/kitty/line.c +++ b/kitty/line.c @@ -302,17 +302,18 @@ write_hyperlink(hyperlink_id_type hid, ANSIBuf *output) { } -void +bool line_as_ansi(Line *self, ANSIBuf *output, const GPUCell** prev_cell, index_type start_at, index_type stop_before, char_type prefix_char) { #define ENSURE_SPACE(extra) ensure_space_for(output, buf, Py_UCS4, output->len + extra, capacity, 2048, false); -#define WRITE_SGR(val) { ENSURE_SPACE(128); write_sgr(val, output); } +#define WRITE_SGR(val) { ENSURE_SPACE(128); escape_code_written = true; write_sgr(val, output); } #define WRITE_CH(val) { ENSURE_SPACE(1); output->buf[output->len++] = val; } -#define WRITE_HYPERLINK(val) { ENSURE_SPACE(2256); write_hyperlink(val, output); } +#define WRITE_HYPERLINK(val) { ENSURE_SPACE(2256); escape_code_written = true; write_hyperlink(val, output); } + bool escape_code_written = false; output->len = 0; index_type limit = MIN(stop_before, xlimit_for_line(self)); char_type previous_width = 0; if (prefix_char) { WRITE_CH(prefix_char); previous_width = wcwidth_std(prefix_char); } - if (limit <= start_at) return; + if (limit <= start_at) return escape_code_written; static const GPUCell blank_cell = { 0 }; GPUCell *cell; @@ -354,6 +355,7 @@ line_as_ansi(Line *self, ANSIBuf *output, const GPUCell** prev_cell, index_type } previous_width = cell->attrs.width; } + return escape_code_written; #undef CMP_ATTRS #undef CMP #undef WRITE_SGR diff --git a/kitty/lineops.h b/kitty/lineops.h index 839402b16..9c654c4fe 100644 --- a/kitty/lineops.h +++ b/kitty/lineops.h @@ -84,7 +84,7 @@ void line_add_combining_char(Line *, uint32_t , unsigned int ); index_type line_url_start_at(Line *self, index_type x); index_type line_url_end_at(Line *self, index_type x, bool, char_type, bool); bool line_startswith_url_chars(Line*); -void line_as_ansi(Line *self, ANSIBuf *output, const GPUCell**, index_type start_at, index_type stop_before, char_type prefix_char) __attribute__((nonnull)); +bool line_as_ansi(Line *self, ANSIBuf *output, const GPUCell**, index_type start_at, index_type stop_before, char_type prefix_char) __attribute__((nonnull)); unsigned int line_length(Line *self); size_t cell_as_unicode(CPUCell *cell, bool include_cc, Py_UCS4 *buf, char_type); size_t cell_as_unicode_for_fallback(CPUCell *cell, Py_UCS4 *buf); diff --git a/kitty/screen.c b/kitty/screen.c index 7ddaf039c..a90ae3426 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -2479,13 +2479,10 @@ ansi_for_range(Screen *self, const Selection *sel, bool insert_newlines, bool st } } } - line_as_ansi(line, &output, &prev_cell, xr.x, x_limit, prefix_char); + if (line_as_ansi(line, &output, &prev_cell, xr.x, x_limit, prefix_char)) has_escape_codes = true; PyObject *t = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output.buf, output.len); if (!t) return NULL; PyTuple_SET_ITEM(ans, i, t); - if (!has_escape_codes) { - for (size_t i = 0; i < output.len; i++) { if (output.buf[i] == 0x1b) { has_escape_codes = true; break; } } - } } PyObject *t = PyUnicode_FromFormat("%s%s", has_escape_codes ? "\x1b[m" : "", output.active_hyperlink_id ? "\x1b]8;;\x1b\\" : ""); if (!t) return NULL;