This commit is contained in:
Kovid Goyal
2025-06-20 20:11:23 +05:30
parent c7fcd44ecf
commit bca017fa4c
4 changed files with 22 additions and 11 deletions

View File

@@ -128,6 +128,8 @@ Detailed list of changes
- Fix a regression in 0.40.0 that broke rendering of VS15 variation selectors in some circumstances (:iss:`8731`) - Fix a regression in 0.40.0 that broke rendering of VS15 variation selectors in some circumstances (:iss:`8731`)
- Fix a regression in 0.40.0 that broke serialization of tab characters as ANSI text (:iss:`8741`)
0.42.1 [2025-05-17] 0.42.1 [2025-05-17]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -111,10 +111,11 @@ multicell_is_continuation_of_previous(const CPUCell *prev, const CPUCell *curr)
return prev->width == curr->width && !curr->natural_width; return prev->width == curr->width && !curr->natural_width;
} }
static void static index_type
text_in_cell_ansi(ANSILineState *s, const CPUCell *c, TextCache *tc, bool skip_multiline_non_zero_lines) { text_in_cell_ansi(ANSILineState *s, const CPUCell *c, TextCache *tc, bool skip_multiline_non_zero_lines) {
index_type num_cells_to_skip_for_tab = 0;
if (c->is_multicell) { if (c->is_multicell) {
if (c->x || (skip_multiline_non_zero_lines && c->y)) return; if (c->x || (skip_multiline_non_zero_lines && c->y)) return num_cells_to_skip_for_tab;
if (s->current_multicell_state) { if (s->current_multicell_state) {
if (!multicell_is_continuation_of_previous(s->current_multicell_state, c)) { if (!multicell_is_continuation_of_previous(s->current_multicell_state, c)) {
close_multicell(s); close_multicell(s);
@@ -134,18 +135,15 @@ text_in_cell_ansi(ANSILineState *s, const CPUCell *c, TextCache *tc, bool skip_m
switch (s->output_buf->buf[pos]) { switch (s->output_buf->buf[pos]) {
case 0: s->output_buf->buf[pos] = ' '; break; case 0: s->output_buf->buf[pos] = ' '; break;
case '\t': { case '\t': {
unsigned num_cells_to_skip_for_tab = 0, n = s->output_buf->len - pos; index_type n = s->output_buf->len - pos;
if (n - pos > 1) { if (n > 1) {
num_cells_to_skip_for_tab = s->output_buf->buf[s->output_buf->len - n + 1]; num_cells_to_skip_for_tab = s->output_buf->buf[s->output_buf->len - n + 1];
s->output_buf->len -= n - 1; s->output_buf->len -= n - 1;
} }
const CPUCell *next = c + 1;
while (num_cells_to_skip_for_tab && pos + 1 < s->limit && cell_is_char(next, ' ')) {
num_cells_to_skip_for_tab--; pos++; next++;
}
} break; } break;
} }
} }
return num_cells_to_skip_for_tab;
} }
@@ -596,8 +594,13 @@ line_as_ansi(Line *self, ANSILineState *s, index_type start_at, index_type stop_
if (*sgr) write_sgr_to_ansi_buf(s, sgr); if (*sgr) write_sgr_to_ansi_buf(s, sgr);
} }
text_in_cell_ansi(s, self->cpu_cells + s->pos, self->text_cache, skip_multiline_non_zero_lines); index_type num_cells_to_skip_for_tab = text_in_cell_ansi(
s, self->cpu_cells + s->pos, self->text_cache, skip_multiline_non_zero_lines);
s->prev_gpu_cell = cell; s->prev_gpu_cell = cell;
const CPUCell *next = self->cpu_cells + s->pos + 1;
while (num_cells_to_skip_for_tab && s->pos + 1 < s->limit && cell_is_char(next, ' ')) {
num_cells_to_skip_for_tab--; s->pos++; next++;
}
} }
close_multicell(s); close_multicell(s);
return s->escape_code_written; return s->escape_code_written;

View File

@@ -535,8 +535,6 @@ class TestDataTypes(BaseTest):
if saved[k] is not None: if saved[k] is not None:
os.environ[k] = saved[k] os.environ[k] = saved[k]
def test_historybuf(self): def test_historybuf(self):
lb = filled_line_buf() lb = filled_line_buf()
hb = HistoryBuf(5, 5) hb = HistoryBuf(5, 5)

View File

@@ -105,6 +105,14 @@ class TestScreen(BaseTest):
self.ae(str(s.line(4)), 'a\u0306b1\u030623') self.ae(str(s.line(4)), 'a\u0306b1\u030623')
self.ae((s.cursor.x, s.cursor.y), (2, 4)) self.ae((s.cursor.x, s.cursor.y), (2, 4))
# Test drawing of tabs
s = self.create_screen(cols=32)
txt = 'a\tb'
s.draw(txt)
ln = s.line(0)
self.ae(txt, ln.as_ansi())
def test_rep(self): def test_rep(self):
s = self.create_screen() s = self.create_screen()
s.draw('a') s.draw('a')