Dont reflow the current prompt when resizing
This ensures that there is no leftover line when the shell redraws the prompt, by making the prompt a simple single character prompt before rewrapping.
This commit is contained in:
parent
f2ca0424a0
commit
196200d03f
4 changed files with 41 additions and 7 deletions
|
|
@ -266,11 +266,11 @@ clear_line_(Line *l, index_type xnum) {
|
|||
}
|
||||
|
||||
void
|
||||
linebuf_clear_line(LineBuf *self, index_type y) {
|
||||
linebuf_clear_line(LineBuf *self, index_type y, bool clear_attrs) {
|
||||
Line l;
|
||||
init_line(self, &l, self->line_map[y]);
|
||||
clear_line_(&l, self->xnum);
|
||||
self->line_attrs[y] = 0;
|
||||
if (clear_attrs) self->line_attrs[y] = 0;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
|
|
@ -278,7 +278,7 @@ clear_line(LineBuf *self, PyObject *val) {
|
|||
#define clear_line_doc "clear_line(y) -> Clear the specified line"
|
||||
index_type y = (index_type)PyLong_AsUnsignedLong(val);
|
||||
if (y >= self->ynum) { PyErr_SetString(PyExc_ValueError, "Out of bounds"); return NULL; }
|
||||
linebuf_clear_line(self, y);
|
||||
linebuf_clear_line(self, y, true);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ void linebuf_init_line(LineBuf *, index_type);
|
|||
void linebuf_clear(LineBuf *, char_type ch);
|
||||
void linebuf_index(LineBuf* self, index_type top, index_type bottom);
|
||||
void linebuf_reverse_index(LineBuf *self, index_type top, index_type bottom);
|
||||
void linebuf_clear_line(LineBuf *self, index_type y);
|
||||
void linebuf_clear_line(LineBuf *self, index_type y, bool clear_attrs);
|
||||
void linebuf_insert_lines(LineBuf *self, unsigned int num, unsigned int y, unsigned int bottom);
|
||||
void linebuf_delete_lines(LineBuf *self, index_type num, index_type y, index_type bottom);
|
||||
void linebuf_copy_line_to(LineBuf *, Line *, index_type);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
dest->line->has_dirty_text = true; \
|
||||
historybuf_add_line(historybuf, dest->line, as_ansi_buf); \
|
||||
}\
|
||||
linebuf_clear_line(dest, dest->ynum - 1); \
|
||||
linebuf_clear_line(dest, dest->ynum - 1, true); \
|
||||
} else dest_y++; \
|
||||
init_dest_line(dest_y); \
|
||||
set_dest_line_attrs(dest_y, continued);
|
||||
|
|
|
|||
|
|
@ -271,11 +271,44 @@ index_selection(const Screen *self, Selections *selections, bool up) {
|
|||
#define INDEX_DOWN \
|
||||
if (self->overlay_line.is_active) deactivate_overlay_line(self); \
|
||||
linebuf_reverse_index(self->linebuf, top, bottom); \
|
||||
linebuf_clear_line(self->linebuf, top); \
|
||||
linebuf_clear_line(self->linebuf, top, true); \
|
||||
INDEX_GRAPHICS(1) \
|
||||
self->is_dirty = true; \
|
||||
index_selection(self, &self->selections, false);
|
||||
|
||||
|
||||
static void
|
||||
prevent_current_prompt_from_rewrapping(Screen *self, index_type columns) {
|
||||
int y = self->cursor->y;
|
||||
while (y >= 0) {
|
||||
linebuf_init_line(self->main_linebuf, y);
|
||||
Line *line = self->linebuf->line;
|
||||
if (line->is_output_start) return;
|
||||
if (line->is_prompt_start) break;
|
||||
y--;
|
||||
}
|
||||
if (y < 0) return;
|
||||
// we have identified a prompt at which the cursor is present, the shell
|
||||
// will redraw this prompt. However when doing so it gets confused if the
|
||||
// cursor vertical position relative to the first prompt line changes. This
|
||||
// can easily be seen for instance in zsh when a right side prompt is used
|
||||
// so when resizing to smaller sizes, simply blank all lines after the current
|
||||
// prompt and trust the shell to redraw them
|
||||
for (; y < (int)self->main_linebuf->ynum; y++) {
|
||||
linebuf_mark_line_as_not_continued(self->main_linebuf, y);
|
||||
if (columns < self->columns) {
|
||||
linebuf_clear_line(self->main_linebuf, y, false);
|
||||
linebuf_init_line(self->main_linebuf, y);
|
||||
if (y <= (int)self->cursor->y) {
|
||||
// this is needed because screen_resize() checks to see if the cursor is beyond the content,
|
||||
// so insert some fake content
|
||||
Line *line = self->linebuf->line;
|
||||
line->cpu_cells[0].ch = '>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
|
||||
if (self->overlay_line.is_active) deactivate_overlay_line(self);
|
||||
|
|
@ -299,6 +332,7 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
|
|||
HistoryBuf *nh = realloc_hb(self->historybuf, self->historybuf->ynum, columns, &self->as_ansi_buf);
|
||||
if (nh == NULL) return false;
|
||||
Py_CLEAR(self->historybuf); self->historybuf = nh;
|
||||
if (is_main) prevent_current_prompt_from_rewrapping(self, columns);
|
||||
LineBuf *n = realloc_lb(self->main_linebuf, lines, columns, &num_content_lines_before, &num_content_lines_after, self->historybuf, &cursor, &main_saved_cursor, &self->as_ansi_buf);
|
||||
if (n == NULL) return false;
|
||||
Py_CLEAR(self->main_linebuf); self->main_linebuf = n;
|
||||
|
|
@ -1135,7 +1169,7 @@ screen_cursor_to_column(Screen *self, unsigned int column) {
|
|||
historybuf_add_line(self->historybuf, self->linebuf->line, &self->as_ansi_buf); \
|
||||
self->history_line_added_count++; \
|
||||
} \
|
||||
linebuf_clear_line(self->linebuf, bottom); \
|
||||
linebuf_clear_line(self->linebuf, bottom, true); \
|
||||
self->is_dirty = true; \
|
||||
index_selection(self, &self->selections, true);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue