Preserve prompt markings when copying lines and rewrapping them
This commit is contained in:
parent
0d4237f802
commit
d4dd226d8f
@ -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;
|
||||
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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*
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user