Mercurial > vim
diff src/mouse.c @ 32824:22a08166a876 v9.0.1725
patch 9.0.1725: cursor pos wrong after concealed text with 'virtualedit'
Commit: https://github.com/vim/vim/commit/e500ae8e29ad921378085f5d70ee5c0c537be1ba
Author: zeertzjq <zeertzjq@outlook.com>
Date: Thu Aug 17 22:35:26 2023 +0200
patch 9.0.1725: cursor pos wrong after concealed text with 'virtualedit'
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>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 17 Aug 2023 22:45:04 +0200 |
parents | 4545f58c8490 |
children | def9fc5c92d1 |
line wrap: on
line diff
--- 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,41 +2098,47 @@ 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 || curwin->w_cursor.col != old_cursor.col)