aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/tui
diff options
context:
space:
mode:
authorRicky Zhou <ricky@rzhou.org>2018-08-25 15:07:52 -0700
committerRicky Zhou <ricky@rzhou.org>2018-09-03 03:25:02 -0700
commit8fd3725cc8d54bced0a8fe1474986d93e9ef0b5b (patch)
tree30370753fb95186f9259db5809bff30f13453634 /src/nvim/tui
parent7ff63fcdc0ba1ce2b8500641f3742d5ada68d496 (diff)
downloadrneovim-8fd3725cc8d54bced0a8fe1474986d93e9ef0b5b.tar.gz
rneovim-8fd3725cc8d54bced0a8fe1474986d93e9ef0b5b.tar.bz2
rneovim-8fd3725cc8d54bced0a8fe1474986d93e9ef0b5b.zip
tui: Hint wrapped lines to terminals.
Previously, when neovim would wrap a line across multiple lines, terminal emulators could not detect that the lines represent a single wrapped line as opposed to several separate lines. As a result, many terminals' selection/copying functionality would treat a wrapped line as several newline-delimited lines. Fix this by reenabling a "special trick" from Vim. When a line is wrapped, write the last character of that line followed by the first character of the next line to the terminal. This hints to the terminal that the next line is a continuation of the current line. Extends the raw_line event with a "wrap" parameter which controls when to do wrap hinting.
Diffstat (limited to 'src/nvim/tui')
-rw-r--r--src/nvim/tui/tui.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 0781b03965..841294aaad 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -1191,7 +1191,8 @@ static void tui_option_set(UI *ui, String name, Object value)
static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol,
Integer endcol, Integer clearcol, Integer clearattr,
- const schar_T *chunk, const sattr_T *attrs)
+ Boolean wrap, const schar_T *chunk,
+ const sattr_T *attrs)
{
TUIData *data = ui->data;
UGrid *grid = &data->grid;
@@ -1212,6 +1213,21 @@ static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol,
clear_region(ui, (int)linerow, (int)linerow, (int)endcol, (int)clearcol-1,
cl_attrs);
}
+
+ if (wrap && ui->width == grid->width && linerow + 1 < grid->height) {
+ // Only do line wrapping if the grid width is equal to the terminal
+ // width and the line continuation is within the grid.
+
+ if (endcol != grid->width) {
+ // Print the last cell of the row, if we haven't already done so.
+ cursor_goto(ui, (int)linerow, grid->width - 1);
+ print_cell(ui, &grid->cells[linerow][grid->width - 1]);
+ }
+
+ // Wrap the cursor over to the next line. The next line will be
+ // printed immediately without an intervening newline.
+ final_column_wrap(ui);
+ }
}
static void invalidate(UI *ui, int top, int bot, int left, int right)