summaryrefslogtreecommitdiffstats
path: root/src/mouse.c
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-08-17 22:35:26 +0200
committerChristian Brabandt <cb@256bit.org>2023-08-17 22:35:26 +0200
commite500ae8e29ad921378085f5d70ee5c0c537be1ba (patch)
treeb0359471c2dd4bb6920edc9b98107e3730eff8a9 /src/mouse.c
parent2261c89a49ff2115e1ccc9ab9211e9f0d5a37578 (diff)
patch 9.0.1725: cursor pos wrong after concealed text with 'virtualedit'v9.0.1725
Problem: Wrong cursor position when clicking after concealed text with 'virtualedit'. Solution: Store virtual columns in ScreenCols[] instead of text columns, and always use coladvance() when clicking. This also fixes incorrect curswant when clicking on a TAB, so now Test_normal_click_on_ctrl_char() asserts the same results as the ones before patch 9.0.0048. closes: #12808 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Diffstat (limited to 'src/mouse.c')
-rw-r--r--src/mouse.c62
1 files changed, 34 insertions, 28 deletions
diff --git a/src/mouse.c b/src/mouse.c
index 4e8dd4d230..c9e96c9cab 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -2060,7 +2060,7 @@ retnomove:
// Only use ScreenCols[] after the window was redrawn. Mainly matters
// for tests, a user would not click before redrawing.
// Do not use when 'virtualedit' is active.
- if (curwin->w_redr_type <= UPD_VALID_NO_UPDATE && !virtual_active())
+ if (curwin->w_redr_type <= UPD_VALID_NO_UPDATE)
col_from_screen = ScreenCols[off];
#ifdef FEAT_FOLDING
// Remember the character under the mouse, it might be a '-' or '+' in
@@ -2098,40 +2098,46 @@ retnomove:
redraw_cmdline = TRUE; // show visual mode later
}
- if (col_from_screen >= 0)
+ if (col_from_screen == MAXCOL)
{
- // Use the column from ScreenCols[], it is accurate also after
- // concealed characters.
- curwin->w_cursor.col = col_from_screen;
- if (col_from_screen == MAXCOL)
+ // When clicking after end of line, still need to set correct curswant
+ int off_l = LineOffset[prev_row];
+ if (ScreenCols[off_l] < MAXCOL)
{
- curwin->w_curswant = col_from_screen;
- curwin->w_set_curswant = FALSE; // May still have been TRUE
- mouse_past_eol = TRUE;
- if (inclusive != NULL)
- *inclusive = TRUE;
+ // Binary search to find last char in line
+ int off_r = off_l + prev_col;
+ int off_click = off_r;
+ while (off_l < off_r)
+ {
+ int off_m = (off_l + off_r + 1) / 2;
+ if (ScreenCols[off_m] < MAXCOL)
+ off_l = off_m;
+ else
+ off_r = off_m - 1;
+ }
+ col = ScreenCols[off_r] + (off_click - off_r);
}
else
- {
- curwin->w_set_curswant = TRUE;
- if (inclusive != NULL)
- *inclusive = FALSE;
- }
- check_cursor_col();
+ // Shouldn't normally happen
+ col = MAXCOL;
}
- else
+ else if (col_from_screen >= 0)
{
- curwin->w_curswant = col;
- curwin->w_set_curswant = FALSE; // May still have been TRUE
- if (coladvance(col) == FAIL) // Mouse click beyond end of line
- {
- if (inclusive != NULL)
- *inclusive = TRUE;
- mouse_past_eol = TRUE;
- }
- else if (inclusive != NULL)
- *inclusive = FALSE;
+ // Use the virtual column from ScreenCols[], it is accurate also after
+ // concealed characters.
+ col = col_from_screen;
+ }
+
+ curwin->w_curswant = col;
+ curwin->w_set_curswant = FALSE; // May still have been TRUE
+ if (coladvance(col) == FAIL) // Mouse click beyond end of line
+ {
+ if (inclusive != NULL)
+ *inclusive = TRUE;
+ mouse_past_eol = TRUE;
}
+ else if (inclusive != NULL)
+ *inclusive = FALSE;
count = IN_BUFFER;
if (curwin != old_curwin || curwin->w_cursor.lnum != old_cursor.lnum