mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-18 06:25:13 +02:00
Start work on rewrapping multicells
This commit is contained in:
@@ -84,6 +84,8 @@ typedef struct Rewrap {
|
|||||||
init_line_func_t init_line;
|
init_line_func_t init_line;
|
||||||
first_dest_line_func_t first_dest_line;
|
first_dest_line_func_t first_dest_line;
|
||||||
next_dest_line_func_t next_dest_line;
|
next_dest_line_func_t next_dest_line;
|
||||||
|
LineBuf *scratch;
|
||||||
|
bool current_dest_line_has_multiline_cells, current_src_line_has_multline_cells, prev_src_line_ended_with_wrap;
|
||||||
} Rewrap;
|
} Rewrap;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -93,7 +95,7 @@ copy_range(Line *src, index_type src_at, Line* dest, index_type dest_at, index_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_line(TextCache *tc, index_type xnum, Line *l) {
|
setup_line(TextCache *tc, index_type xnum, Line *l) {
|
||||||
l->text_cache = tc;
|
l->text_cache = tc;
|
||||||
l->xnum = xnum;
|
l->xnum = xnum;
|
||||||
}
|
}
|
||||||
@@ -102,6 +104,18 @@ static void
|
|||||||
next_dest_line(Rewrap *r, bool continued) {
|
next_dest_line(Rewrap *r, bool continued) {
|
||||||
r->dest_y = r->next_dest_line(r->dest_buf, r->historybuf, r->as_ansi_buf, &r->src, r->dest_y, &r->dest, continued);
|
r->dest_y = r->next_dest_line(r->dest_buf, r->historybuf, r->as_ansi_buf, &r->src, r->dest_y, &r->dest, continued);
|
||||||
r->dest_x = 0;
|
r->dest_x = 0;
|
||||||
|
r->current_dest_line_has_multiline_cells = false;
|
||||||
|
if (r->scratch->line_attrs[0].has_dirty_text) {
|
||||||
|
CPUCell *cpu_cells; GPUCell *gpu_cells;
|
||||||
|
linebuf_init_cells(r->scratch, 0, &cpu_cells, &gpu_cells);
|
||||||
|
memcpy(r->dest.cpu_cells, cpu_cells, r->dest_xnum * sizeof(cpu_cells[0]));
|
||||||
|
memcpy(r->dest.gpu_cells, gpu_cells, r->dest_xnum * sizeof(gpu_cells[0]));
|
||||||
|
r->current_dest_line_has_multiline_cells = true;
|
||||||
|
}
|
||||||
|
linebuf_index(r->scratch, 0, r->scratch->ynum - 1);
|
||||||
|
if (r->scratch->line_attrs[r->scratch->ynum - 1].has_dirty_text) {
|
||||||
|
linebuf_clear_line(r->scratch, r->scratch->ynum - 1, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -109,45 +123,52 @@ first_dest_line(Rewrap *r) {
|
|||||||
r->dest_y = r->first_dest_line(r->dest_buf, r->as_ansi_buf, &r->src, &r->dest);
|
r->dest_y = r->first_dest_line(r->dest_buf, r->as_ansi_buf, &r->src, &r->dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
init_src_line(Rewrap *r) {
|
||||||
|
bool newline_needed = !r->prev_src_line_ended_with_wrap;
|
||||||
|
r->init_line(r->src_buf, r->src_y, &r->src);
|
||||||
|
r->src_x_limit = r->src_xnum;
|
||||||
|
if (!r->src.cpu_cells[r->src_xnum-1].next_char_was_wrapped) {
|
||||||
|
// Trim trailing blanks since there is a hard line break at the end of this line
|
||||||
|
while(r->src_x_limit && r->src.cpu_cells[r->src_x_limit - 1].ch_and_idx == BLANK_CHAR) r->src_x_limit--;
|
||||||
|
}
|
||||||
|
r->prev_src_line_ended_with_wrap = r->src.cpu_cells[r->src_xnum - 1].next_char_was_wrapped;
|
||||||
|
r->src.cpu_cells[r->src_xnum - 1].next_char_was_wrapped = false;
|
||||||
|
r->src_x = 0;
|
||||||
|
for (TrackCursor *t = r->cursors; !t->is_sentinel; t++) {
|
||||||
|
if (r->src_y == t->y) {
|
||||||
|
t->is_tracked_line = true;
|
||||||
|
if (t->x >= r->src_x_limit) t->x = MAX(1u, r->src_x_limit) - 1;
|
||||||
|
} else t->is_tracked_line = false;
|
||||||
|
}
|
||||||
|
return newline_needed;
|
||||||
|
}
|
||||||
|
|
||||||
static index_type
|
static index_type
|
||||||
rewrap_inner(Rewrap r) {
|
rewrap_inner(Rewrap r) {
|
||||||
init_line(r.text_cache, r.src_xnum, &r.src); init_line(r.text_cache, r.dest_xnum, &r.dest);
|
setup_line(r.text_cache, r.src_xnum, &r.src); setup_line(r.text_cache, r.dest_xnum, &r.dest);
|
||||||
static TrackCursor tc_end = {.is_sentinel = true };
|
static TrackCursor tc_end = {.is_sentinel = true };
|
||||||
if (!r.cursors) r.cursors = &tc_end;
|
if (!r.cursors) r.cursors = &tc_end;
|
||||||
bool is_first_line = true, src_line_is_continued = false;
|
r.scratch = alloc_linebuf(SCALE_BITS << 1, r.dest_xnum, r.text_cache);
|
||||||
while (r.src_y < r.src_limit) {
|
if (!r.scratch) fatal("Out of memory");
|
||||||
for (TrackCursor *t = r.cursors; !t->is_sentinel; t++) t->is_tracked_line = r.src_y == t->y;
|
RAII_PyObject(scratch, (PyObject*)r.scratch);
|
||||||
r.init_line(r.src_buf, r.src_y, &r.src);
|
for (; r.src_y < r.src_limit; r.src_y++) {
|
||||||
r.src_x_limit = r.src.xnum;
|
if (init_src_line(&r)) {
|
||||||
if (!src_line_is_continued) {
|
if (r.src_y) next_dest_line(&r, false);
|
||||||
if (is_first_line) { is_first_line = false; first_dest_line(&r); }
|
else first_dest_line(&r);
|
||||||
else next_dest_line(&r, false);
|
|
||||||
}
|
}
|
||||||
src_line_is_continued = r.src.cpu_cells[r.src.xnum-1].next_char_was_wrapped;
|
while (r.src_x < r.src_x_limit) {
|
||||||
if (!src_line_is_continued) {
|
if (r.dest_x >= r.dest_xnum) next_dest_line(&r, true);
|
||||||
// Trim trailing blanks since there is a hard line break at the end of this line
|
index_type num = MIN(r.src.xnum - r.src_x, r.dest_xnum - r.dest_x);
|
||||||
while(r.src_x_limit && r.src.cpu_cells[r.src_x_limit - 1].ch_and_idx == BLANK_CHAR) r.src_x_limit--;
|
copy_range(&r.src, r.src_x, &r.dest, r.dest_x, num);
|
||||||
} else {
|
|
||||||
r.src.cpu_cells[r.src.xnum-1].next_char_was_wrapped = false;
|
|
||||||
}
|
|
||||||
if (r.src_x_limit) {
|
|
||||||
for (TrackCursor *t = r.cursors; !t->is_sentinel; t++) {
|
for (TrackCursor *t = r.cursors; !t->is_sentinel; t++) {
|
||||||
if (t->is_tracked_line && t->x >= r.src_x_limit) t->x = MAX(1u, r.src_x_limit) - 1;
|
if (t->is_tracked_line && r.src_x <= t->x && t->x < r.src_x + num) {
|
||||||
}
|
t->y = r.dest_y;
|
||||||
while (r.src_x < r.src_x_limit) {
|
t->x = r.dest_x + (t->x - r.src_x + (t->x > 0));
|
||||||
if (r.dest_x >= r.dest.xnum) next_dest_line(&r, true);
|
|
||||||
index_type num = MIN(r.src.xnum - r.src_x, r.dest.xnum - r.dest_x);
|
|
||||||
copy_range(&r.src, r.src_x, &r.dest, r.dest_x, num);
|
|
||||||
for (TrackCursor *t = r.cursors; !t->is_sentinel; t++) {
|
|
||||||
if (t->is_tracked_line && r.src_x <= t->x && t->x < r.src_x + num) {
|
|
||||||
t->y = r.dest_y;
|
|
||||||
t->x = r.dest_x + (t->x - r.src_x + (t->x > 0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
r.src_x += num; r.dest_x += num;
|
|
||||||
}
|
}
|
||||||
|
r.src_x += num; r.dest_x += num;
|
||||||
}
|
}
|
||||||
r.src_y++; r.src_x = 0;
|
|
||||||
}
|
}
|
||||||
return r.dest_y;
|
return r.dest_y;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user