diff --git a/kitty/data-types.h b/kitty/data-types.h index c7ded49c0..36908f6e3 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -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; diff --git a/kitty/history.c b/kitty/history.c index d9652b845..793ba5bac 100644 --- a/kitty/history.c +++ b/kitty/history.c @@ -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); diff --git a/kitty/line-buf.c b/kitty/line-buf.c index 8367f6391..d075b145a 100644 --- a/kitty/line-buf.c +++ b/kitty/line-buf.c @@ -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* diff --git a/kitty/rewrap.h b/kitty/rewrap.h index da77d3805..d331d39bf 100644 --- a/kitty/rewrap.h +++ b/kitty/rewrap.h @@ -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);