aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/tui/tui.c69
1 files changed, 42 insertions, 27 deletions
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 4c22495d8e..5614a1738f 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -82,7 +82,7 @@ typedef struct {
UGrid grid;
kvec_t(Rect) invalid_regions;
int out_fd;
- bool can_use_terminal_scroll;
+ bool scroll_region_is_full_screen;
bool mouse_enabled;
bool busy;
cursorentry_T cursor_shapes[SHAPE_IDX_COUNT];
@@ -96,6 +96,7 @@ typedef struct {
int set_cursor_color;
int enable_focus_reporting, disable_focus_reporting;
int resize_screen;
+ int reset_scroll_region;
} unibi_ext;
} TUIData;
@@ -147,7 +148,7 @@ UI *tui_start(void)
static void terminfo_start(UI *ui)
{
TUIData *data = ui->data;
- data->can_use_terminal_scroll = true;
+ data->scroll_region_is_full_screen = true;
data->bufpos = 0;
data->bufsize = sizeof(data->buf) - CNORM_COMMAND_MAX_SIZE;
data->showing_mode = SHAPE_IDX_N;
@@ -159,6 +160,7 @@ static void terminfo_start(UI *ui)
data->unibi_ext.enable_focus_reporting = -1;
data->unibi_ext.disable_focus_reporting = -1;
data->unibi_ext.resize_screen = -1;
+ data->unibi_ext.reset_scroll_region = -1;
data->out_fd = 1;
data->out_isatty = os_isatty(data->out_fd);
// setup unibilium
@@ -424,6 +426,19 @@ static void clear_region(UI *ui, int top, int bot, int left, int right)
unibi_goto(ui, grid->row, grid->col);
}
+static void reset_scroll_region(UI *ui)
+{
+ TUIData *data = ui->data;
+
+ if (0 <= data->unibi_ext.reset_scroll_region) {
+ unibi_out(ui, data->unibi_ext.reset_scroll_region);
+ } else {
+ data->params[0].i = 0;
+ data->params[1].i = ui->height - 1;
+ unibi_out(ui, unibi_change_scroll_region);
+ }
+}
+
static void tui_resize(UI *ui, Integer width, Integer height)
{
TUIData *data = ui->data;
@@ -433,6 +448,10 @@ static void tui_resize(UI *ui, Integer width, Integer height)
data->params[0].i = (int)height;
data->params[1].i = (int)width;
unibi_out(ui, data->unibi_ext.resize_screen);
+ // DECSLPP does not reset the scroll region.
+ if (data->scroll_region_is_full_screen) {
+ reset_scroll_region(ui);
+ }
} else { // Already handled the SIGWINCH signal; avoid double-resize.
got_winch = false;
}
@@ -619,10 +638,9 @@ static void tui_set_scroll_region(UI *ui, Integer top, Integer bot,
TUIData *data = ui->data;
ugrid_set_scroll_region(&data->grid, (int)top, (int)bot,
(int)left, (int)right);
- data->can_use_terminal_scroll =
+ data->scroll_region_is_full_screen =
left == 0 && right == ui->width - 1
- && ((top == 0 && bot == ui->height - 1)
- || unibi_get_str(data->ut, unibi_change_scroll_region));
+ && top == 0 && bot == ui->height - 1;
}
static void tui_scroll(UI *ui, Integer count)
@@ -632,31 +650,28 @@ static void tui_scroll(UI *ui, Integer count)
int clear_top, clear_bot;
ugrid_scroll(grid, (int)count, &clear_top, &clear_bot);
- if (data->can_use_terminal_scroll) {
+ if (data->scroll_region_is_full_screen || 0 <= unibi_change_scroll_region) {
// Change terminal scroll region and move cursor to the top
- data->params[0].i = grid->top;
- data->params[1].i = grid->bot;
- unibi_out(ui, unibi_change_scroll_region);
+ if (!data->scroll_region_is_full_screen) {
+ data->params[0].i = grid->top;
+ data->params[1].i = grid->bot;
+ unibi_out(ui, unibi_change_scroll_region);
+ }
unibi_goto(ui, grid->top, grid->left);
// also set default color attributes or some terminals can become funny
HlAttrs clear_attrs = EMPTY_ATTRS;
clear_attrs.foreground = grid->fg;
clear_attrs.background = grid->bg;
update_attrs(ui, clear_attrs);
- }
- if (count > 0) {
- if (data->can_use_terminal_scroll) {
+ if (count > 0) {
if (count == 1) {
unibi_out(ui, unibi_delete_line);
} else {
data->params[0].i = (int)count;
unibi_out(ui, unibi_parm_delete_line);
}
- }
-
- } else {
- if (data->can_use_terminal_scroll) {
+ } else {
if (count == -1) {
unibi_out(ui, unibi_insert_line);
} else {
@@ -664,13 +679,11 @@ static void tui_scroll(UI *ui, Integer count)
unibi_out(ui, unibi_parm_insert_line);
}
}
- }
- if (data->can_use_terminal_scroll) {
// Restore terminal scroll region and cursor
- data->params[0].i = 0;
- data->params[1].i = ui->height - 1;
- unibi_out(ui, unibi_change_scroll_region);
+ if (!data->scroll_region_is_full_screen) {
+ reset_scroll_region(ui);
+ }
unibi_goto(ui, grid->row, grid->col);
if (grid->bg != -1) {
@@ -1015,6 +1028,8 @@ static void fix_terminfo(TUIData *data)
unibi_set_if_empty(ut, unibi_change_scroll_region, "\x1b[%i%p1%d;%p2%dr");
unibi_set_if_empty(ut, unibi_clear_screen, "\x1b[H\x1b[2J");
unibi_set_if_empty(ut, unibi_from_status_line, "\x07");
+ data->unibi_ext.reset_scroll_region = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[r");
}
data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
@@ -1044,13 +1059,13 @@ static void fix_terminfo(TUIData *data)
}
// Only define this capability for terminal types that we know understand it.
- if (data->term == kTermDTTerm // originated this extension
- || data->term == kTermXTerm // per xterm ctlseqs doco
- || data->term == kTermKonsole // per commentary in VT102Emulation.cpp
- || data->term == kTermTeraTerm // per TeraTerm "Supported Control Functions" doco
- || data->term == kTermRxvt) { // per command.C
+ if (data->term == kTermDTTerm // originated this extension
+ || data->term == kTermXTerm // per xterm ctlseqs doc
+ || data->term == kTermKonsole // per commentary in VT102Emulation.cpp
+ || data->term == kTermTeraTerm // per "Supported Control Functions" doc
+ || data->term == kTermRxvt) { // per command.C
data->unibi_ext.resize_screen = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[8;%p1%d;%p2%dt");
+ "\x1b[8;%p1%d;%p2%dt");
}
end: