From c60a941d1be8cc111c73a74efc0960d04395db03 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 3 Jun 2021 12:29:27 +0530 Subject: [PATCH] Allow rewrap_inner to track multiple positions --- kitty/history.c | 6 +++--- kitty/line-buf.c | 4 +++- kitty/rewrap.h | 24 +++++++++++++++++------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/kitty/history.c b/kitty/history.c index f47bf6b4a..ef8fd9541 100644 --- a/kitty/history.c +++ b/kitty/history.c @@ -536,7 +536,8 @@ HistoryBuf *alloc_historybuf(unsigned int lines, unsigned int columns, unsigned #include "rewrap.h" -void historybuf_rewrap(HistoryBuf *self, HistoryBuf *other, ANSIBuf *as_ansi_buf) { +void +historybuf_rewrap(HistoryBuf *self, HistoryBuf *other, ANSIBuf *as_ansi_buf) { while(other->num_segments < self->num_segments) add_segment(other); if (other->xnum == self->xnum && other->ynum == self->ynum) { // Fast path @@ -551,9 +552,8 @@ void historybuf_rewrap(HistoryBuf *self, HistoryBuf *other, ANSIBuf *as_ansi_buf if (other->pagerhist && other->xnum != self->xnum && ringbuf_bytes_used(other->pagerhist->ringbuf)) other->pagerhist->rewrap_needed = true; other->count = 0; other->start_of_data = 0; - index_type x = 0, y = 0; if (self->count > 0) { - rewrap_inner(self, other, self->count, NULL, &x, &y, as_ansi_buf); + rewrap_inner(self, other, self->count, NULL, NULL, as_ansi_buf); for (index_type i = 0; i < other->count; i++) *attrptr(other, (other->start_of_data + i) % other->ynum) |= TEXT_DIRTY_MASK; } } diff --git a/kitty/line-buf.c b/kitty/line-buf.c index f0d18156a..04343e902 100644 --- a/kitty/line-buf.c +++ b/kitty/line-buf.c @@ -574,7 +574,9 @@ linebuf_rewrap(LineBuf *self, LineBuf *other, index_type *num_content_lines_befo return; } - rewrap_inner(self, other, first + 1, historybuf, track_x, track_y, as_ansi_buf); + TrackCursor tcarr[2] = {{.x = *track_x, .y = *track_y }, {.is_sentinel = true}}; + rewrap_inner(self, other, first + 1, historybuf, (TrackCursor*)tcarr, as_ansi_buf); + *track_x = tcarr[0].x; *track_y = tcarr[0].y; *num_content_lines_after = other->line->ynum + 1; for (i = 0; i < *num_content_lines_after; i++) other->line_attrs[i] |= TEXT_DIRTY_MASK; *num_content_lines_before = first + 1; diff --git a/kitty/rewrap.h b/kitty/rewrap.h index af2954449..da77d3805 100644 --- a/kitty/rewrap.h +++ b/kitty/rewrap.h @@ -48,31 +48,41 @@ copy_range(Line *src, index_type src_at, Line* dest, index_type dest_at, index_t memcpy(dest->gpu_cells + dest_at, src->gpu_cells + src_at, num * sizeof(GPUCell)); } +typedef struct TrackCursor { + index_type x, y; + bool is_tracked_line, is_sentinel; +} TrackCursor; + static void -rewrap_inner(BufType *src, BufType *dest, const index_type src_limit, HistoryBuf UNUSED *historybuf, index_type *track_x, index_type *track_y, ANSIBuf *as_ansi_buf) { +rewrap_inner(BufType *src, BufType *dest, const index_type src_limit, HistoryBuf UNUSED *historybuf, TrackCursor *track, ANSIBuf *as_ansi_buf) { bool src_line_is_continued = false; index_type src_y = 0, src_x = 0, dest_x = 0, dest_y = 0, num = 0, src_x_limit = 0; + TrackCursor tc_end = {.is_sentinel = true }; + if (!track) track = &tc_end; first_dest_line; do { - bool is_tracked_line = src_y == *track_y; + for (TrackCursor *t = track; !t->is_sentinel; t++) t->is_tracked_line = src_y == t->y; init_src_line(src_y); src_line_is_continued = is_src_line_continued(src_y); src_x_limit = src->xnum; if (!src_line_is_continued) { // Trim trailing blanks since there is a hard line break at the end of this line while(src_x_limit && (src->line->cpu_cells[src_x_limit - 1].ch) == BLANK_CHAR) src_x_limit--; - } - if (is_tracked_line && *track_x >= src_x_limit) *track_x = MAX(1u, src_x_limit) - 1; + for (TrackCursor *t = track; !t->is_sentinel; t++) { + if (t->is_tracked_line && t->x >= src_x_limit) t->x = MAX(1u, src_x_limit) - 1; + } while (src_x < src_x_limit) { if (dest_x >= dest->xnum) { next_dest_line(true); dest_x = 0; } num = MIN(src->line->xnum - src_x, dest->xnum - dest_x); copy_range(src->line, src_x, dest->line, dest_x, num); - if (is_tracked_line && src_x <= *track_x && *track_x < src_x + num) { - *track_y = dest_y; - *track_x = dest_x + (*track_x - src_x + 1); + for (TrackCursor *t = track; !t->is_sentinel; t++) { + if (t->is_tracked_line && src_x <= t->x && t->x < src_x + num) { + t->y = dest_y; + t->x = dest_x + (t->x - src_x + 1); + } } src_x += num; dest_x += num; }