aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/grid.c
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-03-17 07:26:39 +0800
committerGitHub <noreply@github.com>2024-03-17 07:26:39 +0800
commitd114dbe9f79c1382298b04319b7ded88e95e3ee8 (patch)
treea3ed5239b72332bef8e42afa2b9ba095c74d7afe /src/nvim/grid.c
parent34b57508a78b0a980e898ee35d950db0a90368ca (diff)
downloadrneovim-d114dbe9f79c1382298b04319b7ded88e95e3ee8.tar.gz
rneovim-d114dbe9f79c1382298b04319b7ded88e95e3ee8.tar.bz2
rneovim-d114dbe9f79c1382298b04319b7ded88e95e3ee8.zip
vim-patch:9.1.0184: Cursor pos wrong when clicking with conceal and wrap (#27890)
Problem: Cursor position wrong when clicking with conceal and wrap. Solution: Use the virtual column of the last char for ScreenCols[] in boguscols. Remove use of MAXCOL in ScreenCols[]. Rename third argument of wlv_screen_line() to "clear_end" as that's clearer what it does (zeertzjq). related: 14192 closes: vim/vim#14200 https://github.com/vim/vim/commit/d0c1b7723f7e73763597af2f97a53d94ab7ed020 Rename win_put_linebuf() to wlv_put_linebuf().
Diffstat (limited to 'src/nvim/grid.c')
-rw-r--r--src/nvim/grid.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/src/nvim/grid.c b/src/nvim/grid.c
index e386853022..e911e6ad21 100644
--- a/src/nvim/grid.c
+++ b/src/nvim/grid.c
@@ -1,3 +1,6 @@
+// Low-level functions to manipulate individual character cells on the
+// screen grid.
+//
// Most of the routines in this file perform screen (grid) manipulations. The
// given operation is performed physically on the screen. The corresponding
// change is also made to the internal screen image. In this way, the editor
@@ -338,7 +341,7 @@ static int grid_line_first = INT_MAX;
static int grid_line_last = 0;
static int grid_line_clear_to = 0;
static int grid_line_clear_attr = 0;
-static bool grid_line_rl = false;
+static int grid_line_flags = 0;
/// Start a group of grid_line_puts calls that builds a single grid line.
///
@@ -358,7 +361,7 @@ void grid_line_start(ScreenGrid *grid, int row)
grid_line_last = 0;
grid_line_clear_to = 0;
grid_line_clear_attr = 0;
- grid_line_rl = false;
+ grid_line_flags = 0;
assert((size_t)grid_line_maxcol <= linebuf_size);
@@ -515,7 +518,7 @@ void grid_line_mirror(void)
return;
}
linebuf_mirror(&grid_line_first, &grid_line_last, &grid_line_clear_to, grid_line_maxcol);
- grid_line_rl = true;
+ grid_line_flags |= SLF_RIGHTLEFT;
}
void linebuf_mirror(int *firstp, int *lastp, int *clearp, int maxcol)
@@ -568,7 +571,7 @@ void grid_line_flush(void)
}
grid_put_linebuf(grid, grid_line_row, grid_line_coloff, grid_line_first, grid_line_last,
- grid_line_clear_to, grid_line_rl, grid_line_clear_attr, false);
+ grid_line_clear_to, grid_line_clear_attr, -1, grid_line_flags);
}
/// flush grid line but only if on a valid row
@@ -619,17 +622,21 @@ static int grid_char_needs_redraw(ScreenGrid *grid, int col, size_t off_to, int
/// Move one buffered line to the window grid, but only the characters that
/// have actually changed. Handle insert/delete character.
-/// "coloff" gives the first column on the grid for this line.
-/// "endcol" gives the columns where valid characters are.
-/// "clear_width" is the width of the window. It's > 0 if the rest of the line
-/// needs to be cleared, negative otherwise.
-/// "rl" is true for rightleft text, like a window with 'rightleft' option set
-/// When true and "clear_width" > 0, clear columns 0 to "endcol"
-/// When false and "clear_width" > 0, clear columns "endcol" to "clear_width"
-/// If "wrap" is true, then hint to the UI that "row" contains a line
-/// which has wrapped into the next row.
+///
+/// @param coloff gives the first column on the grid for this line.
+/// @param endcol gives the columns where valid characters are.
+/// @param clear_width see SLF_RIGHTLEFT.
+/// @param flags can have bits:
+/// - SLF_RIGHTLEFT rightleft text, like a window with 'rightleft' option set:
+/// - When false, clear columns "endcol" to "clear_width".
+/// - When true, clear columns "col" to "endcol".
+/// - SLF_WRAP hint to UI that "row" contains a line wrapped into the next row.
+/// - SLF_INC_VCOL:
+/// - When false, use "last_vcol" for grid->vcols[] of the columns to clear.
+/// - When true, use an increasing sequence starting from "last_vcol + 1" for
+/// grid->vcols[] of the columns to clear.
void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol, int clear_width,
- bool rl, int bg_attr, bool wrap)
+ int bg_attr, colnr_T last_vcol, int flags)
{
bool redraw_next; // redraw_this for next character
bool clear_next = false;
@@ -659,7 +666,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
}
int clear_start = endcol;
- if (rl) {
+ if (flags & SLF_RIGHTLEFT) {
clear_start = col;
col = endcol;
endcol = clear_width;
@@ -758,17 +765,17 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
}
clear_end = col + 1;
}
- grid->vcols[off] = MAXCOL;
+ grid->vcols[off] = (flags & SLF_INC_VCOL) ? ++last_vcol : last_vcol;
col++;
}
- if (rl && start_dirty != -1 && clear_dirty_start != -1) {
+ if ((flags & SLF_RIGHTLEFT) && start_dirty != -1 && clear_dirty_start != -1) {
if (grid->throttled || clear_dirty_start >= start_dirty - 5) {
// cannot draw now or too small to be worth a separate "clear" event
start_dirty = clear_dirty_start;
} else {
ui_line(grid, row, invalid_row, coloff + clear_dirty_start, coloff + clear_dirty_start,
- coloff + clear_end, bg_attr, wrap);
+ coloff + clear_end, bg_attr, flags & SLF_WRAP);
}
clear_end = end_dirty;
} else {
@@ -785,7 +792,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
if (clear_end > start_dirty) {
if (!grid->throttled) {
ui_line(grid, row, invalid_row, coloff + start_dirty, coloff + end_dirty, coloff + clear_end,
- bg_attr, wrap);
+ bg_attr, flags & SLF_WRAP);
} else if (grid->dirty_col) {
// TODO(bfredl): really get rid of the extra pseudo terminal in message.c
// by using a linebuf_char copy for "throttled message line"