mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-25 17:52:02 +02:00
Fix #8741
This commit is contained in:
@@ -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]
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
21
kitty/line.c
21
kitty/line.c
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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')
|
||||||
|
|||||||
Reference in New Issue
Block a user