Allow rewrap_inner to track multiple positions

This commit is contained in:
Kovid Goyal 2021-06-03 12:29:27 +05:30
parent e2197c586b
commit c60a941d1b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 23 additions and 11 deletions

View File

@ -536,7 +536,8 @@ HistoryBuf *alloc_historybuf(unsigned int lines, unsigned int columns, unsigned
#include "rewrap.h" #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); while(other->num_segments < self->num_segments) add_segment(other);
if (other->xnum == self->xnum && other->ynum == self->ynum) { if (other->xnum == self->xnum && other->ynum == self->ynum) {
// Fast path // 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)) if (other->pagerhist && other->xnum != self->xnum && ringbuf_bytes_used(other->pagerhist->ringbuf))
other->pagerhist->rewrap_needed = true; other->pagerhist->rewrap_needed = true;
other->count = 0; other->start_of_data = 0; other->count = 0; other->start_of_data = 0;
index_type x = 0, y = 0;
if (self->count > 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; for (index_type i = 0; i < other->count; i++) *attrptr(other, (other->start_of_data + i) % other->ynum) |= TEXT_DIRTY_MASK;
} }
} }

View File

@ -574,7 +574,9 @@ linebuf_rewrap(LineBuf *self, LineBuf *other, index_type *num_content_lines_befo
return; 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; *num_content_lines_after = other->line->ynum + 1;
for (i = 0; i < *num_content_lines_after; i++) other->line_attrs[i] |= TEXT_DIRTY_MASK; for (i = 0; i < *num_content_lines_after; i++) other->line_attrs[i] |= TEXT_DIRTY_MASK;
*num_content_lines_before = first + 1; *num_content_lines_before = first + 1;

View File

@ -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)); 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 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; 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; 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; first_dest_line;
do { 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); init_src_line(src_y);
src_line_is_continued = is_src_line_continued(src_y); src_line_is_continued = is_src_line_continued(src_y);
src_x_limit = src->xnum; src_x_limit = src->xnum;
if (!src_line_is_continued) { if (!src_line_is_continued) {
// Trim trailing blanks since there is a hard line break at the end of this line // 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--; 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) { while (src_x < src_x_limit) {
if (dest_x >= dest->xnum) { next_dest_line(true); dest_x = 0; } if (dest_x >= dest->xnum) { next_dest_line(true); dest_x = 0; }
num = MIN(src->line->xnum - src_x, dest->xnum - dest_x); num = MIN(src->line->xnum - src_x, dest->xnum - dest_x);
copy_range(src->line, src_x, dest->line, dest_x, num); copy_range(src->line, src_x, dest->line, dest_x, num);
if (is_tracked_line && src_x <= *track_x && *track_x < src_x + num) { for (TrackCursor *t = track; !t->is_sentinel; t++) {
*track_y = dest_y; if (t->is_tracked_line && src_x <= t->x && t->x < src_x + num) {
*track_x = dest_x + (*track_x - src_x + 1); t->y = dest_y;
t->x = dest_x + (t->x - src_x + 1);
}
} }
src_x += num; dest_x += num; src_x += num; dest_x += num;
} }