Only move the cursor a line down on resize if the cursor line was split

This commit is contained in:
Kovid Goyal 2016-12-12 12:39:34 +05:30
parent 271e3360ff
commit 0797f159ad
6 changed files with 29 additions and 11 deletions

View File

@ -331,6 +331,7 @@ void line_set_char(Line *, unsigned int , uint32_t , unsigned int , Cursor *);
void line_right_shift(Line *, unsigned int , unsigned int ); void line_right_shift(Line *, unsigned int , unsigned int );
void line_add_combining_char(Line *, uint32_t , unsigned int ); void line_add_combining_char(Line *, uint32_t , unsigned int );
index_type line_as_ansi(Line *self, Py_UCS4 *buf, index_type buflen); index_type line_as_ansi(Line *self, Py_UCS4 *buf, index_type buflen);
unsigned int line_length(Line *self);
void linebuf_init_line(LineBuf *, index_type); void linebuf_init_line(LineBuf *, index_type);
void linebuf_clear(LineBuf *, char_type ch); void linebuf_clear(LineBuf *, char_type ch);

View File

@ -432,7 +432,8 @@ copy_old(LineBuf *self, PyObject *y) {
#include "rewrap.h" #include "rewrap.h"
void linebuf_rewrap(LineBuf *self, LineBuf *other, int *cursor_y_out, HistoryBuf *historybuf) { void
linebuf_rewrap(LineBuf *self, LineBuf *other, int *cursor_y_out, HistoryBuf *historybuf) {
index_type first, i; index_type first, i;
bool is_empty = true; bool is_empty = true;

View File

@ -24,7 +24,16 @@ dealloc(Line* self) {
Py_TYPE(self)->tp_free((PyObject*)self); Py_TYPE(self)->tp_free((PyObject*)self);
} }
PyObject* line_text_at(char_type ch, combining_type cc) { unsigned int
line_length(Line *self) {
for (int i = self->xnum - 1; i >= 0; i++) {
if ((self->chars[i] & CHAR_MASK) != 32) return i + 1;
}
return 0;
}
PyObject*
line_text_at(char_type ch, combining_type cc) {
PyObject *ans; PyObject *ans;
if (cc == 0) { if (cc == 0) {
ans = PyUnicode_New(1, ch); ans = PyUnicode_New(1, ch);

View File

@ -108,7 +108,17 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
LineBuf *n = realloc_lb(self->main_linebuf, lines, columns, &cursor_y, self->historybuf); LineBuf *n = realloc_lb(self->main_linebuf, lines, columns, &cursor_y, self->historybuf);
if (n == NULL) return false; if (n == NULL) return false;
Py_CLEAR(self->main_linebuf); self->main_linebuf = n; Py_CLEAR(self->main_linebuf); self->main_linebuf = n;
if (is_main) self->cursor->y = MAX(0, cursor_y); bool index_after_resize = false;
if (is_main) {
linebuf_init_line(self->main_linebuf, self->cursor->y);
if (is_x_shrink && (self->main_linebuf->continued_map[self->cursor->y] || line_length(self->main_linebuf->line) > columns)) {
// If the client is in line drawing mode, it will redraw the cursor
// line, this can cause rendering artifacts, so ensure that the
// cursor is on a new line
index_after_resize = true;
}
self->cursor->y = MAX(0, cursor_y);
}
cursor_y = -1; cursor_y = -1;
n = realloc_lb(self->alt_linebuf, lines, columns, &cursor_y, NULL); n = realloc_lb(self->alt_linebuf, lines, columns, &cursor_y, NULL);
if (n == NULL) return false; if (n == NULL) return false;
@ -129,6 +139,7 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
init_tabstops(self->main_tabstops, self->columns); init_tabstops(self->main_tabstops, self->columns);
init_tabstops(self->alt_tabstops, self->columns); init_tabstops(self->alt_tabstops, self->columns);
tracker_update_screen(self->change_tracker); tracker_update_screen(self->change_tracker);
if (index_after_resize) screen_index(self);
return true; return true;
} }

View File

@ -65,10 +65,6 @@ class Window:
def set_geometry(self, new_geometry): def set_geometry(self, new_geometry):
if self.needs_layout or new_geometry.xnum != self.screen.columns or new_geometry.ynum != self.screen.lines: if self.needs_layout or new_geometry.xnum != self.screen.columns or new_geometry.ynum != self.screen.lines:
self.screen.resize(new_geometry.ynum, new_geometry.xnum) self.screen.resize(new_geometry.ynum, new_geometry.xnum)
if self.screen.cursor.y > 0:
# We move the cursor once line down to prevent the shell from
# overwriting the contents of the last line
self.screen.index()
self.child.resize_pty(self.screen.columns, self.screen.lines) self.child.resize_pty(self.screen.columns, self.screen.lines)
self.char_grid.resize(new_geometry) self.char_grid.resize(new_geometry)
self.needs_layout = False self.needs_layout = False

View File

@ -243,14 +243,14 @@ class TestScreen(BaseTest):
s.resize(5, 1) s.resize(5, 1)
self.ae(str(s.line(0)), '4') self.ae(str(s.line(0)), '4')
hb = s.historybuf hb = s.historybuf
for i in range(s.lines): for i in range(hb.ynum):
self.ae(str(hb.line(i)), '3') self.ae(str(hb.line(i)), '4' if i == 0 else '3')
self.ae(str(hb.line(5)), '2')
s = self.create_screen(scrollback=6) s = self.create_screen(scrollback=6)
s.draw(''.join([str(i) * s.columns for i in range(s.lines*2)])) s.draw(''.join([str(i) * s.columns for i in range(s.lines*2)]))
self.ae(str(s.line(4)), '9'*5) self.ae(str(s.line(4)), '9'*5)
s.resize(5, 2) s.resize(5, 2)
self.ae(str(s.line(4)), '9 ') self.ae(str(s.line(3)), '9 ')
self.ae(str(s.line(4)), ' ')
def test_tab_stops(self): def test_tab_stops(self):
# Taken from vttest/main.c # Taken from vttest/main.c