Skip to content

Commit

Permalink
More tests for multicell selections
Browse files Browse the repository at this point in the history
  • Loading branch information
kovidgoyal committed Jan 11, 2025
1 parent 1a2baaa commit 2c380a2
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 8 deletions.
2 changes: 2 additions & 0 deletions kitty/history.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ pagerhist_push(HistoryBuf *self, ANSIBuf *as_ansi_buf) {
Line l = {.xnum=self->xnum, .text_cache=self->text_cache};
init_line(self, self->start_of_data, &l);
ANSILineState s = {.output_buf=as_ansi_buf};
as_ansi_buf->len = 0;
line_as_ansi(&l, &s, 0, l.xnum, 0, true);
pagerhist_write_bytes(ph, (const uint8_t*)"\x1b[m", 3);
if (pagerhist_write_ucs4(ph, as_ansi_buf->buf, as_ansi_buf->len)) {
Expand Down Expand Up @@ -351,6 +352,7 @@ as_ansi(HistoryBuf *self, PyObject *callback) {
ANSIBuf output = {0}; ANSILineState s = {.output_buf=&output};
for(unsigned int i = 0; i < self->count; i++) {
init_line(self, i, &l);
output.len = 0;
line_as_ansi(&l, &s, 0, l.xnum, 0, true);
if (!l.cpu_cells[l.xnum - 1].next_char_was_wrapped) {
ensure_space_for(&output, buf, Py_UCS4, output.len + 1, capacity, 2048, false);
Expand Down
2 changes: 2 additions & 0 deletions kitty/line-buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,13 +470,15 @@ as_ansi(LineBuf *self, PyObject *callback) {
ANSIBuf output = {0}; ANSILineState s = {.output_buf=&output};
do {
init_line(self, &l, self->line_map[ylimit]);
output.len = 0;
line_as_ansi(&l, &s, 0, l.xnum, 0, true);
if (output.len) break;
ylimit--;
} while(ylimit > 0);

for(index_type i = 0; i <= ylimit; i++) {
bool output_newline = !linebuf_line_ends_with_continuation(self, i);
output.len = 0;
init_line(self, &l, self->line_map[i]);
line_as_ansi(&l, &s, 0, l.xnum, 0, true);
if (output_newline) {
Expand Down
18 changes: 11 additions & 7 deletions kitty/line.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,11 +364,17 @@ cell_as_utf8_for_fallback(const ListOfChars *lc, char *buf) {

bool
unicode_in_range(const Line *self, const index_type start, const index_type limit, const bool include_cc, const bool add_trailing_newline, const bool skip_zero_cells, bool skip_multiline_non_zero_lines, ANSIBuf *buf) {
static const size_t initial_cap = 4096;
ListOfChars lc;
if (!buf->buf) {
buf->buf = malloc(initial_cap * sizeof(buf->buf[0]));
if (!buf->buf) return false;
buf->capacity = initial_cap;
}
for (index_type i = start; i < limit; i++) {
lc.chars = buf->buf + buf->len; lc.capacity = buf->capacity - buf->len;
while (!text_in_cell_without_alloc(self->cpu_cells + i, self->text_cache, &lc)) {
size_t ns = MAX(4096u, 2 * buf->capacity);
size_t ns = MAX(initial_cap, 2 * buf->capacity);
char_type *np = realloc(buf->buf, ns);
if (!np) return false;
buf->capacity = ns; buf->buf = np;
Expand Down Expand Up @@ -485,7 +491,6 @@ write_mark_to_ansi_buf(ANSILineState *s, const char *m) {

bool
line_as_ansi(Line *self, ANSILineState *s, index_type start_at, index_type stop_before, char_type prefix_char, bool skip_multiline_non_zero_lines) {
s->output_buf->len = 0;
s->limit = MIN(stop_before, xlimit_for_line(self));
s->current_multicell_state = NULL;
s->escape_code_written = false;
Expand Down Expand Up @@ -554,11 +559,9 @@ set_wrapped_flag(Line* self, PyObject *is_wrapped) {
static PyObject*
__repr__(Line* self) {
RAII_ANSIBuf(buf);
PyObject *s = line_as_unicode(self, false, &buf);
if (s == NULL) return NULL;
PyObject *ans = PyObject_Repr(s);
Py_CLEAR(s);
return ans;
RAII_PyObject(s, line_as_unicode(self, false, &buf));
if (s != NULL) return PyObject_Repr(s);
return NULL;
}

static PyObject*
Expand Down Expand Up @@ -972,6 +975,7 @@ as_text_generic(PyObject *args, void *container, get_line_func get_line, index_t
Line *line = get_line(container, y);
if (!line) { if (PyErr_Occurred()) return NULL; break; }
if (need_newline) APPEND(nl);
ansibuf->len = 0;
if (as_ansi) {
// less has a bug where it resets colors when it sees a \r, so work
// around it by resetting SGR at the start of every line. This is
Expand Down
1 change: 0 additions & 1 deletion kitty/line.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

#include "text-cache.h"

// TODO: Handle selection with multicell
// TODO: URL detection with multicell

typedef union CellAttrs {
Expand Down
17 changes: 17 additions & 0 deletions kitty_tests/multicell.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,18 +630,35 @@ def asa(*expected, strip_trailing_whitespace=False):
ss(p(), p(x=1, in_left_half_of_cell=False))
asl((0, 0, 2))
ast('ab')
asa(f'a\x1b]{TEXT_SIZE_CODE};w=2;b\x07', '\x1b[m')
ss(p(x=2), p(x=3, in_left_half_of_cell=False))
asl((0, 1, 3))
ast('bc')
asa(f'\x1b]{TEXT_SIZE_CODE};w=2;b\x07c', '\x1b[m')

s.reset()
s.draw('a'), multicell(s, 'b', scale=2), s.draw('c'), multicell(s, 'd', scale=2)
ss(p(), p(x=4, in_left_half_of_cell=False))
asl((0, 0, 5), (1, 1, 2), (1, 4, 5))
ast('abcd')
asa(f'a\x1b]{TEXT_SIZE_CODE};w=1:s=2;b\x07c\x1b]{TEXT_SIZE_CODE};w=1:s=2;d\x07', '\x1b[m')
ss(p(y=1, x=1), p(y=1, x=1, in_left_half_of_cell=False))
asl((0, 1, 2), (1, 1, 2))
ast('b')
asa(f'\x1b]{TEXT_SIZE_CODE};w=1:s=2;b\x07', '\x1b[m')
ss(p(y=1, x=0), p(y=1, x=1, in_left_half_of_cell=False)) # empty leading cell before multiline on y=1
asl((0, 1, 2), (1, 0, 2))
ast(' b')
asa(f' \x1b]{TEXT_SIZE_CODE};w=1:s=2;b\x07', '\x1b[m')

s.reset()
multicell(s, 'X', scale=2), s.draw('123456abcd')
for x in (0, 1, 2):
ss(p(x=x), p(x=3, y=1, in_left_half_of_cell=False))
asl((0, 0, 7), (1, 0, 3))
ast('X123456', 'ab')
asa(f'\x1b]{TEXT_SIZE_CODE};w=1:s=2;X\x07123456', 'ab', '\x1b[m')
ss(p(y=1), p(y=1, x=3, in_left_half_of_cell=False))
asl((0, 0, 1), (1, 0, 3))
ast('Xab')
asa(f'\x1b]{TEXT_SIZE_CODE};w=1:s=2;X\x07ab', '\x1b[m')

0 comments on commit 2c380a2

Please sign in to comment.