aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/tui/tui.c108
1 files changed, 93 insertions, 15 deletions
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 5614a1738f..736d50ee8b 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -83,6 +83,9 @@ typedef struct {
kvec_t(Rect) invalid_regions;
int out_fd;
bool scroll_region_is_full_screen;
+ bool can_change_scroll_region;
+ bool can_set_lr_margin;
+ bool can_set_left_right_margin;
bool mouse_enabled;
bool busy;
cursorentry_T cursor_shapes[SHAPE_IDX_COUNT];
@@ -92,6 +95,7 @@ typedef struct {
struct {
int enable_mouse, disable_mouse;
int enable_bracketed_paste, disable_bracketed_paste;
+ int enable_lr_margin, disable_lr_margin;
int set_rgb_foreground, set_rgb_background;
int set_cursor_color;
int enable_focus_reporting, disable_focus_reporting;
@@ -157,6 +161,8 @@ static void terminfo_start(UI *ui)
data->unibi_ext.set_cursor_color = -1;
data->unibi_ext.enable_bracketed_paste = -1;
data->unibi_ext.disable_bracketed_paste = -1;
+ data->unibi_ext.enable_lr_margin = -1;
+ data->unibi_ext.disable_lr_margin = -1;
data->unibi_ext.enable_focus_reporting = -1;
data->unibi_ext.disable_focus_reporting = -1;
data->unibi_ext.resize_screen = -1;
@@ -171,6 +177,13 @@ static void terminfo_start(UI *ui)
data->ut = unibi_dummy();
}
fix_terminfo(data);
+ data->can_change_scroll_region =
+ !!unibi_get_str(data->ut, unibi_change_scroll_region);
+ data->can_set_lr_margin =
+ !!unibi_get_str(data->ut, unibi_set_lr_margin);
+ data->can_set_left_right_margin =
+ !!unibi_get_str(data->ut, unibi_set_left_margin_parm)
+ && !!unibi_get_str(data->ut, unibi_set_right_margin_parm);
// Set 't_Co' from the result of unibilium & fix_terminfo.
t_colors = unibi_get_num(data->ut, unibi_max_colors);
// Enter alternate screen and clear
@@ -426,9 +439,46 @@ static void clear_region(UI *ui, int top, int bot, int left, int right)
unibi_goto(ui, grid->row, grid->col);
}
+static bool can_use_scroll(UI * ui)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+
+ return data->scroll_region_is_full_screen
+ || (data->can_change_scroll_region
+ && ((grid->left == 0 && grid->right == ui->width - 1)
+ || data->can_set_lr_margin
+ || data->can_set_left_right_margin));
+}
+
+static void set_scroll_region(UI *ui)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+
+ data->params[0].i = grid->top;
+ data->params[1].i = grid->bot;
+ unibi_out(ui, unibi_change_scroll_region);
+ if (grid->left != 0 || grid->right != ui->width - 1) {
+ unibi_out(ui, data->unibi_ext.enable_lr_margin);
+ if (data->can_set_lr_margin) {
+ data->params[0].i = grid->left;
+ data->params[1].i = grid->right;
+ unibi_out(ui, unibi_set_lr_margin);
+ } else {
+ data->params[0].i = grid->left;
+ unibi_out(ui, unibi_set_left_margin_parm);
+ data->params[0].i = grid->right;
+ unibi_out(ui, unibi_set_right_margin_parm);
+ }
+ }
+ unibi_goto(ui, grid->row, grid->col);
+}
+
static void reset_scroll_region(UI *ui)
{
TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
if (0 <= data->unibi_ext.reset_scroll_region) {
unibi_out(ui, data->unibi_ext.reset_scroll_region);
@@ -437,6 +487,20 @@ static void reset_scroll_region(UI *ui)
data->params[1].i = ui->height - 1;
unibi_out(ui, unibi_change_scroll_region);
}
+ if (grid->left != 0 || grid->right != ui->width - 1) {
+ if (data->can_set_lr_margin) {
+ data->params[0].i = 0;
+ data->params[1].i = ui->width - 1;
+ unibi_out(ui, unibi_set_lr_margin);
+ } else {
+ data->params[0].i = 0;
+ unibi_out(ui, unibi_set_left_margin_parm);
+ data->params[0].i = ui->width - 1;
+ unibi_out(ui, unibi_set_right_margin_parm);
+ }
+ unibi_out(ui, data->unibi_ext.disable_lr_margin);
+ }
+ unibi_goto(ui, grid->row, grid->col);
}
static void tui_resize(UI *ui, Integer width, Integer height)
@@ -650,19 +714,22 @@ static void tui_scroll(UI *ui, Integer count)
int clear_top, clear_bot;
ugrid_scroll(grid, (int)count, &clear_top, &clear_bot);
- if (data->scroll_region_is_full_screen || 0 <= unibi_change_scroll_region) {
+ if (can_use_scroll(ui)) {
+ bool scroll_clears_to_current_colour =
+ unibi_get_bool(data->ut, unibi_back_color_erase);
+
// Change terminal scroll region and move cursor to the top
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);
+ set_scroll_region(ui);
}
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 (scroll_clears_to_current_colour) {
+ HlAttrs clear_attrs = EMPTY_ATTRS;
+ clear_attrs.foreground = grid->fg;
+ clear_attrs.background = grid->bg;
+ update_attrs(ui, clear_attrs);
+ }
if (count > 0) {
if (count == 1) {
@@ -686,11 +753,9 @@ static void tui_scroll(UI *ui, Integer count)
}
unibi_goto(ui, grid->row, grid->col);
- if (grid->bg != -1) {
- // Update the cleared area of the terminal if its builtin scrolling
- // facility was used and the background color is not the default. This is
- // required because scrolling may leave wrong background in the cleared
- // area.
+ if (!scroll_clears_to_current_colour) {
+ // This is required because scrolling will leave wrong background in the
+ // cleared area on non-bge terminals.
clear_region(ui, clear_top, clear_bot, grid->left, grid->right);
}
} else {
@@ -1025,13 +1090,21 @@ static void fix_terminfo(TUIData *data)
unibi_set_if_empty(ut, unibi_cursor_invisible, "\x1b[?25l");
unibi_set_if_empty(ut, unibi_flash_screen, "\x1b[?5h$<100/>\x1b[?5l");
unibi_set_if_empty(ut, unibi_exit_attribute_mode, "\x1b(B\x1b[m");
+ unibi_set_if_empty(ut, unibi_set_tb_margin, "\x1b[%i%p1%d;%p2%dr");
+ unibi_set_if_empty(ut, unibi_set_lr_margin, "\x1b[%i%p1%d;%p2%ds");
+ unibi_set_if_empty(ut, unibi_set_left_margin_parm, "\x1b[%i%p1%ds");
+ unibi_set_if_empty(ut, unibi_set_right_margin_parm, "\x1b[%i;%p2%ds");
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");
+ unibi_set_bool(ut, unibi_back_color_erase, true);
}
+ data->unibi_ext.enable_lr_margin = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[?69h");
+ data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[?69l");
+
data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
"\x1b[?2004h");
data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
@@ -1068,6 +1141,11 @@ static void fix_terminfo(TUIData *data)
"\x1b[8;%p1%d;%p2%dt");
}
+ if (data->term == kTermXTerm || data->term == kTermRxvt) {
+ data->unibi_ext.reset_scroll_region = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[r");
+ }
+
end:
// Fill some empty slots with common terminal strings
if (data->term == kTermiTerm) {