mirror of
https://github.com/neovim/neovim.git
synced 2025-09-13 23:08:16 +00:00
mouse.c: Adjust clicked column if chars are concealed (#5087)
syntax.c: Added syn_get_concealed_id() tests: Added tests for mouse clicks on concealed text.
This commit is contained in:

committed by
Justin M. Keyes

parent
56f178058a
commit
1f7304b846
@@ -6,6 +6,7 @@
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/strings.h"
|
||||
#include "nvim/screen.h"
|
||||
#include "nvim/syntax.h"
|
||||
#include "nvim/ui.h"
|
||||
#include "nvim/os_unix.h"
|
||||
#include "nvim/fold.h"
|
||||
@@ -303,6 +304,10 @@ retnomove:
|
||||
mouse_past_bottom = true;
|
||||
}
|
||||
|
||||
if (!(flags & MOUSE_RELEASED) && which_button == MOUSE_LEFT) {
|
||||
col = mouse_adjust_click(curwin, row, col);
|
||||
}
|
||||
|
||||
// Start Visual mode before coladvance(), for when 'sel' != "old"
|
||||
if ((flags & MOUSE_MAY_VIS) && !VIsual_active) {
|
||||
check_visual_highlight();
|
||||
@@ -597,3 +602,74 @@ bool mouse_scroll_horiz(int dir)
|
||||
|
||||
return leftcol_changed();
|
||||
}
|
||||
|
||||
// Adjust the clicked column position if there are concealed characters
|
||||
// before the current column. But only when it's absolutely necessary.
|
||||
static int mouse_adjust_click(win_T *wp, int row, int col)
|
||||
{
|
||||
if (!(wp->w_p_cole > 0 && curbuf->b_p_smc > 0
|
||||
&& wp->w_leftcol < curbuf->b_p_smc && conceal_cursor_line(wp))) {
|
||||
return col;
|
||||
}
|
||||
|
||||
int end = (colnr_T)STRLEN(ml_get(wp->w_cursor.lnum));
|
||||
int vend = getviscol2(end, 0);
|
||||
|
||||
if (col >= vend) {
|
||||
return col;
|
||||
}
|
||||
|
||||
int i = wp->w_leftcol;
|
||||
|
||||
if (row > 0) {
|
||||
i += row * (wp->w_width - win_col_off(wp) - win_col_off2(wp)
|
||||
- wp->w_leftcol) + wp->w_skipcol;
|
||||
}
|
||||
|
||||
int start_col = i;
|
||||
int matchid;
|
||||
int last_matchid;
|
||||
int bcol = end - (vend - col);
|
||||
|
||||
while (i < bcol) {
|
||||
matchid = syn_get_concealed_id(wp, wp->w_cursor.lnum, i);
|
||||
|
||||
if (matchid != 0) {
|
||||
if (wp->w_p_cole == 3) {
|
||||
bcol++;
|
||||
} else {
|
||||
if (row > 0 && i == start_col) {
|
||||
// Check if the current concealed character is actually part of
|
||||
// the previous wrapped row's conceal group.
|
||||
last_matchid = syn_get_concealed_id(wp, wp->w_cursor.lnum,
|
||||
i - 1);
|
||||
if (last_matchid == matchid) {
|
||||
bcol++;
|
||||
}
|
||||
} else if (wp->w_p_cole == 1
|
||||
|| (wp->w_p_cole == 2
|
||||
&& (lcs_conceal != NUL
|
||||
|| syn_get_sub_char() != NUL))) {
|
||||
// At least one placeholder character will be displayed.
|
||||
bcol--;
|
||||
}
|
||||
|
||||
last_matchid = matchid;
|
||||
|
||||
// Adjust for concealed text that spans more than one character.
|
||||
do {
|
||||
i++;
|
||||
bcol++;
|
||||
matchid = syn_get_concealed_id(wp, wp->w_cursor.lnum, i);
|
||||
} while (last_matchid == matchid);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return getviscol2(bcol, 0);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user