mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 11:28:22 +00:00
fix(mouse): click after eol with conceal and virtual text (#27897)
Problem: Wrong cursor position when clicking after end of line with 'virtualedit', conceal and virtual text. Solution: Always fill linebuf_vcol[] for the columns to clear.
This commit is contained in:
@@ -300,7 +300,6 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
|
|||||||
if (vt->pos == kVPosEndOfLine && do_eol) {
|
if (vt->pos == kVPosEndOfLine && do_eol) {
|
||||||
state->eol_col = col + 1;
|
state->eol_col = col + 1;
|
||||||
}
|
}
|
||||||
// TODO(zeertzjq): set values in linebuf_vcol[]
|
|
||||||
*end_col = MAX(*end_col, col);
|
*end_col = MAX(*end_col, col);
|
||||||
}
|
}
|
||||||
if (!vt || !(vt->flags & kVTRepeatLinebreak)) {
|
if (!vt || !(vt->flags & kVTRepeatLinebreak)) {
|
||||||
@@ -2571,6 +2570,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
decor_redraw_eol(wp, &decor_state, &wlv.line_attr, wlv.col + eol_skip);
|
decor_redraw_eol(wp, &decor_state, &wlv.line_attr, wlv.col + eol_skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = wlv.col; i < grid->cols; i++) {
|
||||||
|
linebuf_vcol[wlv.off + (i - wlv.col)] = wlv.vcol + (i - wlv.col);
|
||||||
|
}
|
||||||
|
|
||||||
if (((wp->w_p_cuc
|
if (((wp->w_p_cuc
|
||||||
&& wp->w_virtcol >= vcol_hlc(wlv) - eol_hl_off
|
&& wp->w_virtcol >= vcol_hlc(wlv) - eol_hl_off
|
||||||
&& wp->w_virtcol < grid->cols * (ptrdiff_t)(wlv.row - startrow + 1) + start_col
|
&& wp->w_virtcol < grid->cols * (ptrdiff_t)(wlv.row - startrow + 1) + start_col
|
||||||
@@ -2596,8 +2599,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
|
|
||||||
while (wlv.col < grid->cols) {
|
while (wlv.col < grid->cols) {
|
||||||
linebuf_char[wlv.off] = schar_from_ascii(' ');
|
linebuf_char[wlv.off] = schar_from_ascii(' ');
|
||||||
linebuf_vcol[wlv.off] = wlv.vcol;
|
|
||||||
wlv.col++;
|
|
||||||
advance_color_col(&wlv, vcol_hlc(wlv));
|
advance_color_col(&wlv, vcol_hlc(wlv));
|
||||||
|
|
||||||
int col_attr = base_attr;
|
int col_attr = base_attr;
|
||||||
@@ -2616,7 +2618,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
col_attr = hl_combine_attr(col_attr, wlv.line_attr);
|
col_attr = hl_combine_attr(col_attr, wlv.line_attr);
|
||||||
|
|
||||||
linebuf_attr[wlv.off] = col_attr;
|
linebuf_attr[wlv.off] = col_attr;
|
||||||
|
// linebuf_vcol[] already filled by the for loop above
|
||||||
wlv.off++;
|
wlv.off++;
|
||||||
|
wlv.col++;
|
||||||
|
|
||||||
if (vcol_hlc(wlv) >= rightmost_vcol) {
|
if (vcol_hlc(wlv) >= rightmost_vcol) {
|
||||||
break;
|
break;
|
||||||
@@ -2857,13 +2861,17 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
|||||||
|
|
||||||
int draw_col = wlv.col - wlv.boguscols;
|
int draw_col = wlv.col - wlv.boguscols;
|
||||||
|
|
||||||
|
for (int i = draw_col; i < grid->cols; i++) {
|
||||||
|
linebuf_vcol[wlv.off + (i - draw_col)] = wlv.vcol - 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Apply 'cursorline' highlight.
|
// Apply 'cursorline' highlight.
|
||||||
if (wlv.boguscols != 0 && (wlv.line_attr_lowprio != 0 || wlv.line_attr != 0)) {
|
if (wlv.boguscols != 0 && (wlv.line_attr_lowprio != 0 || wlv.line_attr != 0)) {
|
||||||
int attr = hl_combine_attr(wlv.line_attr_lowprio, wlv.line_attr);
|
int attr = hl_combine_attr(wlv.line_attr_lowprio, wlv.line_attr);
|
||||||
while (draw_col < grid->cols) {
|
while (draw_col < grid->cols) {
|
||||||
linebuf_char[wlv.off] = schar_from_char(' ');
|
linebuf_char[wlv.off] = schar_from_char(' ');
|
||||||
linebuf_attr[wlv.off] = attr;
|
linebuf_attr[wlv.off] = attr;
|
||||||
linebuf_vcol[wlv.off] = wlv.vcol - 1;
|
// linebuf_vcol[] already filled by the for loop above
|
||||||
wlv.off++;
|
wlv.off++;
|
||||||
draw_col++;
|
draw_col++;
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,7 @@ describe('ui/mouse/input', function()
|
|||||||
[6] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red },
|
[6] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red },
|
||||||
[7] = { bold = true, foreground = Screen.colors.SeaGreen4 },
|
[7] = { bold = true, foreground = Screen.colors.SeaGreen4 },
|
||||||
[8] = { foreground = Screen.colors.Brown },
|
[8] = { foreground = Screen.colors.Brown },
|
||||||
|
[9] = { background = Screen.colors.DarkGrey, foreground = Screen.colors.LightGrey },
|
||||||
})
|
})
|
||||||
command('set mousemodel=extend')
|
command('set mousemodel=extend')
|
||||||
feed('itesting<cr>mouse<cr>support and selection<esc>')
|
feed('itesting<cr>mouse<cr>support and selection<esc>')
|
||||||
@@ -1638,6 +1639,59 @@ describe('ui/mouse/input', function()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('virtual text does not change cursor placement on concealed line', function()
|
||||||
|
command('%delete')
|
||||||
|
insert('aaaaaaaaaa|hidden|bbbbbbbbbb|hidden|cccccccccc')
|
||||||
|
command('syntax match test /|hidden|/ conceal cchar=X')
|
||||||
|
command('set conceallevel=2 concealcursor=n virtualedit=all')
|
||||||
|
screen:expect([[
|
||||||
|
aaaaaaaaaa{9:X}bbbbbbb |
|
||||||
|
bbb{9:X}ccccccccc^c |
|
||||||
|
{0:~ }|*2
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
api.nvim_input_mouse('left', 'press', '', 0, 0, 22)
|
||||||
|
screen:expect([[
|
||||||
|
aaaaaaaaaa{9:X}bbbbbb^b |
|
||||||
|
bbb{9:X}cccccccccc |
|
||||||
|
{0:~ }|*2
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
api.nvim_input_mouse('left', 'press', '', 0, 1, 16)
|
||||||
|
screen:expect([[
|
||||||
|
aaaaaaaaaa{9:X}bbbbbbb |
|
||||||
|
bbb{9:X}cccccccccc ^ |
|
||||||
|
{0:~ }|*2
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
|
||||||
|
api.nvim_buf_set_extmark(0, api.nvim_create_namespace(''), 0, 0, {
|
||||||
|
virt_text = { { '?', 'ErrorMsg' } },
|
||||||
|
virt_text_pos = 'right_align',
|
||||||
|
virt_text_repeat_linebreak = true,
|
||||||
|
})
|
||||||
|
screen:expect([[
|
||||||
|
aaaaaaaaaa{9:X}bbbbbbb {6:?}|
|
||||||
|
bbb{9:X}cccccccccc ^ {6:?}|
|
||||||
|
{0:~ }|*2
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
api.nvim_input_mouse('left', 'press', '', 0, 0, 22)
|
||||||
|
screen:expect([[
|
||||||
|
aaaaaaaaaa{9:X}bbbbbb^b {6:?}|
|
||||||
|
bbb{9:X}cccccccccc {6:?}|
|
||||||
|
{0:~ }|*2
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
api.nvim_input_mouse('left', 'press', '', 0, 1, 16)
|
||||||
|
screen:expect([[
|
||||||
|
aaaaaaaaaa{9:X}bbbbbbb {6:?}|
|
||||||
|
bbb{9:X}cccccccccc ^ {6:?}|
|
||||||
|
{0:~ }|*2
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end)
|
||||||
|
|
||||||
it('getmousepos() works correctly', function()
|
it('getmousepos() works correctly', function()
|
||||||
local winwidth = api.nvim_get_option_value('winwidth', {})
|
local winwidth = api.nvim_get_option_value('winwidth', {})
|
||||||
-- Set winwidth=1 so that window sizes don't change.
|
-- Set winwidth=1 so that window sizes don't change.
|
||||||
|
Reference in New Issue
Block a user