Preserve prompt markings when copying lines and rewrapping them

This commit is contained in:
Kovid Goyal 2021-07-12 17:59:10 +05:30
parent 0d4237f802
commit d4dd226d8f
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 21 additions and 9 deletions

View File

@ -181,7 +181,7 @@ typedef struct {
GPUCell *gpu_cells;
CPUCell *cpu_cells;
index_type xnum, ynum;
bool continued, needs_free, has_dirty_text;
bool continued, needs_free, has_dirty_text, is_prompt_start, is_output_start;
} Line;

View File

@ -149,6 +149,8 @@ init_line(HistoryBuf *self, index_type num, Line *l) {
l->gpu_cells = gpu_lineptr(self, num);
l->continued = *attrptr(self, num) & CONTINUED_MASK;
l->has_dirty_text = *attrptr(self, num) & TEXT_DIRTY_MASK ? true : false;
l->is_output_start = *attrptr(self, num) & OUTPUT_START_MASK ? true : false;
l->is_prompt_start = *attrptr(self, num) & PROMPT_START_MASK ? true : false;
}
void
@ -248,7 +250,7 @@ void
historybuf_add_line(HistoryBuf *self, const Line *line, ANSIBuf *as_ansi_buf) {
index_type idx = historybuf_push(self, as_ansi_buf);
copy_line(line, self->line);
*attrptr(self, idx) = (line->continued & CONTINUED_MASK) | (line->has_dirty_text ? TEXT_DIRTY_MASK : 0);
*attrptr(self, idx) = (line->continued & CONTINUED_MASK) | (line->has_dirty_text ? TEXT_DIRTY_MASK : 0) | (line->is_output_start ? OUTPUT_START_MASK : 0) | (line->is_output_start ? PROMPT_START_MASK : 0);
}
bool
@ -530,7 +532,7 @@ HistoryBuf *alloc_historybuf(unsigned int lines, unsigned int columns, unsigned
#define is_src_line_continued(src_y) (map_src_index(src_y) < src->ynum - 1 ? (*attrptr(src, map_src_index(src_y + 1)) & CONTINUED_MASK) : false)
#define next_dest_line(cont) *attrptr(dest, historybuf_push(dest, as_ansi_buf)) = cont & CONTINUED_MASK; dest->line->continued = cont;
#define next_dest_line(cont) *attrptr(dest, historybuf_push(dest, as_ansi_buf)) = (cont ? CONTINUED_MASK : 0) | (src->line->is_output_start ? OUTPUT_START_MASK : 0) | (src->line->is_prompt_start ? PROMPT_START_MASK : 0); dest->line->continued = cont;
#define first_dest_line next_dest_line(false);

View File

@ -143,6 +143,8 @@ linebuf_init_line(LineBuf *self, index_type idx) {
self->line->xnum = self->xnum;
self->line->continued = self->line_attrs[idx] & CONTINUED_MASK ? true : false;
self->line->has_dirty_text = self->line_attrs[idx] & TEXT_DIRTY_MASK ? true : false;
self->line->is_prompt_start = self->line_attrs[idx] & PROMPT_START_MASK ? true : false;
self->line->is_output_start = self->line_attrs[idx] & OUTPUT_START_MASK ? true : false;
init_line(self, self->line, self->line_map[idx]);
}
@ -232,6 +234,8 @@ create_line_copy_inner(LineBuf* self, index_type y) {
line->ynum = y;
line->continued = self->line_attrs[y] & CONTINUED_MASK ? true : false;
line->has_dirty_text = self->line_attrs[y] & TEXT_DIRTY_MASK ? true : false;
line->is_output_start = self->line_attrs[y] & OUTPUT_START_MASK ? true : false;
line->is_prompt_start = self->line_attrs[y] & PROMPT_START_MASK ? true : false;
init_line(self, &src, self->line_map[y]);
copy_line(&src, line);
return (PyObject*)line;
@ -255,6 +259,8 @@ copy_line_to(LineBuf *self, PyObject *args) {
dest->ynum = y;
dest->continued = self->line_attrs[y] & CONTINUED_MASK;
dest->has_dirty_text = self->line_attrs[y] & TEXT_DIRTY_MASK;
dest->is_output_start = self->line_attrs[y] & OUTPUT_START_MASK;
dest->is_prompt_start = self->line_attrs[y] & PROMPT_START_MASK;
init_line(self, &src, self->line_map[y]);
copy_line(&src, dest);
Py_RETURN_NONE;
@ -413,7 +419,7 @@ void
linebuf_copy_line_to(LineBuf *self, Line *line, index_type where) {
init_line(self, self->line, self->line_map[where]);
copy_line(line, self->line);
self->line_attrs[where] = TEXT_DIRTY_MASK | (line->continued ? CONTINUED_MASK : 0);
self->line_attrs[where] = TEXT_DIRTY_MASK | (line->continued ? CONTINUED_MASK : 0) | (line->is_output_start ? OUTPUT_START_MASK : 0) | (line->is_prompt_start ? PROMPT_START_MASK : 0);
}
static PyObject*

View File

@ -16,11 +16,13 @@
#endif
#ifndef init_dest_line
#define init_dest_line(dest_y) init_line(dest, dest->line, dest->line_map[dest_y]); dest->line->continued = dest->line_attrs[dest_y];
#define init_dest_line(dest_y) init_line(dest, dest->line, dest->line_map[dest_y]); dest->line->continued = dest->line_attrs[dest_y] & CONTINUED_MASK ? true : false; dest->line->is_output_start = dest->line_attrs[dest_y] & OUTPUT_START_MASK ? true : false; dest->line->is_prompt_start = dest->line_attrs[dest_y] & PROMPT_START_MASK ? true : false;
#endif
#define set_dest_line_attrs(dest_y, continued) dest->line_attrs[dest_y] = (continued ? CONTINUED_MASK : 0) | (src->line->is_output_start ? OUTPUT_START_MASK : 0) | (src->line->is_prompt_start ? PROMPT_START_MASK : 0);
#ifndef first_dest_line
#define first_dest_line init_dest_line(0)
#define first_dest_line init_dest_line(0); set_dest_line_attrs(0, false)
#endif
#ifndef next_dest_line
@ -35,7 +37,7 @@
linebuf_clear_line(dest, dest->ynum - 1); \
} else dest_y++; \
init_dest_line(dest_y); \
dest->line_attrs[dest_y] = continued ? CONTINUED_MASK : 0;
set_dest_line_attrs(dest_y, continued);
#endif
#ifndef is_src_line_continued
@ -56,12 +58,11 @@ typedef struct TrackCursor {
static void
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, is_first_line = true;
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 {
for (TrackCursor *t = track; !t->is_sentinel; t++) t->is_tracked_line = src_y == t->y;
init_src_line(src_y);
@ -74,6 +75,9 @@ rewrap_inner(BufType *src, BufType *dest, const index_type src_limit, HistoryBuf
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;
}
if (is_first_line) {
first_dest_line; is_first_line = false;
}
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);