aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan de Boyne Pollard <J.deBoynePollard-newsgroups@NTLWorld.com>2017-05-28 00:55:04 +0100
committerJonathan de Boyne Pollard <J.deBoynePollard-newsgroups@NTLWorld.com>2017-06-03 18:53:28 +0100
commit24db94b1a6d821699222564856f8e1d89841dfa6 (patch)
tree1bd34877589abe7ddcf669fb38d2f1a454eb5189
parent0d537672748bfd49674a21fdd9cac2b79c2085a9 (diff)
downloadrneovim-24db94b1a6d821699222564856f8e1d89841dfa6.tar.gz
rneovim-24db94b1a6d821699222564856f8e1d89841dfa6.tar.bz2
rneovim-24db94b1a6d821699222564856f8e1d89841dfa6.zip
tui: Fix Interix and account for deferred wrap.
The Interix termcap entry is missing the carriage_return capability which nvim relies upon. And Interix is one of the few terminal emulators that does not defer automatic wrap at the right margin, which is now accounted for when moving the cursor left and when outputting whole lines at a time.
-rw-r--r--src/nvim/tui/tui.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 5c191d94a8..3d27758b01 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -76,6 +76,7 @@ typedef struct {
bool can_change_scroll_region;
bool can_set_lr_margin;
bool can_set_left_right_margin;
+ bool immediate_wrap_after_last_column;
bool mouse_enabled;
bool busy;
cursorentry_T cursor_shapes[SHAPE_IDX_COUNT];
@@ -184,6 +185,8 @@ static void terminfo_start(UI *ui)
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);
+ data->immediate_wrap_after_last_column =
+ term && STARTS_WITH(term, "interix");
// 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
@@ -423,6 +426,23 @@ static bool cheap_to_print(UI *ui, int row, int col, int next)
return true;
}
+/// The behaviour that this is checking for the absence of is undocumented,
+/// but is implemented in the majority of terminals and terminal emulators.
+/// Printing at the right margin does not cause an automatic wrap until the
+/// next character is printed, holding the cursor in place until then.
+static void check_final_column_wrap(UI *ui)
+{
+ TUIData *data = ui->data;
+ if (!data->immediate_wrap_after_last_column) {
+ return;
+ }
+ UGrid *grid = &data->grid;
+ if (grid->col == ui->width) {
+ grid->col = 0;
+ ++grid->row;
+ }
+}
+
/// This optimizes several cases where it is cheaper to do something other
/// than send a full cursor positioning control sequence. However, there are
/// some further optimizations that may seem obvious but that will not work.
@@ -460,6 +480,7 @@ static void cursor_goto(UI *ui, int row, int col)
grid->col, col - 1, {
print_cell(ui, cell);
++grid->col;
+ check_final_column_wrap(ui);
});
}
}
@@ -471,6 +492,9 @@ static void cursor_goto(UI *ui, int row, int col)
unibi_out(ui, unibi_cursor_left);
}
} else {
+ if (!data->immediate_wrap_after_last_column && grid->col >= ui->width) {
+ --n; // We have calculated one too many columns because of delayed wrap.
+ }
data->params[0].i = n;
unibi_out(ui, unibi_parm_left_cursor);
}
@@ -565,6 +589,7 @@ static void clear_region(UI *ui, int top, int bot, int left, int right)
cursor_goto(ui, row, col);
print_cell(ui, cell);
++grid->col;
+ check_final_column_wrap(ui);
});
}
@@ -879,6 +904,7 @@ static void tui_put(UI *ui, String text)
{
TUIData *data = ui->data;
print_cell(ui, ugrid_put(&data->grid, (uint8_t *)text.data, text.size));
+ check_final_column_wrap(ui);
}
static void tui_bell(UI *ui)
@@ -932,6 +958,7 @@ static void tui_flush(UI *ui)
cursor_goto(ui, row, col);
print_cell(ui, cell);
++grid->col;
+ check_final_column_wrap(ui);
});
}
@@ -2408,6 +2435,8 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
} else if (term && STARTS_WITH(term, "tmux")) {
unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_");
unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\");
+ } else if (term && STARTS_WITH(term, "interix")) {
+ unibi_set_if_empty(ut, unibi_carriage_return, "\x0d");
} else if (linuxvt) {
// No deviations from the vanilla terminfo.
} else if (term && STARTS_WITH(term, "putty")) {