Skip to content

Commit

Permalink
patch 9.0.0048: cursor in wrong column with mouse click after conceal…
Browse files Browse the repository at this point in the history
…ed text

Problem:    Cursor in wrong column with mouse click after concealed text.
Solution:   Store the text column when drawing text.
  • Loading branch information
brammool committed Jul 9, 2022
1 parent fee0c4a commit b908188
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 43 deletions.
29 changes: 18 additions & 11 deletions src/drawline.c
Expand Up @@ -779,7 +779,7 @@ win_line(
trailcol = (colnr_T)STRLEN(ptr);
while (trailcol > (colnr_T)0 && VIM_ISWHITE(ptr[trailcol - 1]))
--trailcol;
trailcol += (colnr_T) (ptr - line);
trailcol += (colnr_T)(ptr - line);
}
// find end of leading whitespace
if (wp->w_lcs_chars.lead || wp->w_lcs_chars.leadmultispace != NULL)
Expand All @@ -792,7 +792,7 @@ win_line(
leadcol = (colnr_T)0;
else
// keep track of the first column not filled with spaces
leadcol += (colnr_T) (ptr - line) + 1;
leadcol += (colnr_T)(ptr - line) + 1;
}
}

Expand Down Expand Up @@ -1027,12 +1027,14 @@ win_line(
// Repeat for the whole displayed line.
for (;;)
{
char_u *prev_ptr = ptr;
#if defined(FEAT_CONCEAL) || defined(FEAT_SEARCH_EXTRA)
int has_match_conc = 0; // match wants to conceal
int has_match_conc = 0; // match wants to conceal
#endif
#ifdef FEAT_CONCEAL
int did_decrement_ptr = FALSE;
int did_decrement_ptr = FALSE;
#endif

// Skip this quickly when working on the text.
if (draw_state != WL_LINE)
{
Expand Down Expand Up @@ -1392,6 +1394,7 @@ win_line(
&match_conc, did_line_attr, lcs_eol_one,
&on_last_col);
ptr = line + v; // "line" may have been changed
prev_ptr = ptr;

// Do not allow a conceal over EOL otherwise EOL will be missed
// and bad things happen.
Expand Down Expand Up @@ -1553,6 +1556,7 @@ win_line(
// have made it invalid.
line = ml_get_buf(wp->w_buffer, lnum, FALSE);
ptr = line + v;
prev_ptr = ptr;
# ifdef FEAT_CONCEAL
// no concealing past the end of the line, it interferes
// with line highlighting
Expand Down Expand Up @@ -1733,9 +1737,10 @@ win_line(
else
{
#ifdef FEAT_LINEBREAK
int c0;
int c0;
#endif
VIM_CLEAR(p_extra_free);
prev_ptr = ptr;

// Get a character from the line itself.
c = *ptr;
Expand Down Expand Up @@ -1942,17 +1947,12 @@ win_line(
# endif
can_spell))
{
char_u *prev_ptr, *p;
char_u *p;
int len;
hlf_T spell_hlf = HLF_COUNT;

if (has_mbyte)
{
prev_ptr = ptr - mb_l;
v -= mb_l - 1;
}
else
prev_ptr = ptr - 1;

// Use nextline[] if possible, it has the start of the
// next line concatenated.
Expand Down Expand Up @@ -2771,6 +2771,7 @@ win_line(
}
#endif
ScreenAttrs[off] = char_attr;
ScreenCols[off] = MAXCOL;
#ifdef FEAT_RIGHTLEFT
if (wp->w_p_rl)
{
Expand Down Expand Up @@ -2839,6 +2840,7 @@ win_line(
ScreenLines[off] = ' ';
if (enc_utf8)
ScreenLinesUC[off] = 0;
ScreenCols[off] = MAXCOL;
++col;
if (draw_color_col)
draw_color_col = advance_color_col(VCOL_HLC,
Expand Down Expand Up @@ -2992,6 +2994,8 @@ win_line(
else
ScreenAttrs[off] = char_attr;

ScreenCols[off] = (colnr_T)(prev_ptr - line);

if (has_mbyte && (*mb_char2cells)(mb_c) > 1)
{
// Need to fill two screen columns.
Expand All @@ -3013,6 +3017,9 @@ win_line(
// the character, otherwise highlighting won't stop.
if (tocol == vcol)
++tocol;

ScreenCols[off] = (colnr_T)(prev_ptr - line);

#ifdef FEAT_RIGHTLEFT
if (wp->w_p_rl)
{
Expand Down
6 changes: 4 additions & 2 deletions src/globals.h
Expand Up @@ -32,15 +32,17 @@ EXTERN long Columns INIT(= 80); // nr of columns in the screen
* The characters that are currently on the screen are kept in ScreenLines[].
* It is a single block of characters, the size of the screen plus one line.
* The attributes for those characters are kept in ScreenAttrs[].
* The byte offset in the line is kept in ScreenCols[].
*
* "LineOffset[n]" is the offset from ScreenLines[] for the start of line 'n'.
* The same value is used for ScreenLinesUC[] and ScreenAttrs[].
* The same value is used for ScreenLinesUC[], ScreenAttrs[] and ScreenCols[].
*
* Note: before the screen is initialized and when out of memory these can be
* NULL.
*/
EXTERN schar_T *ScreenLines INIT(= NULL);
EXTERN sattr_T *ScreenAttrs INIT(= NULL);
EXTERN colnr_T *ScreenCols INIT(= NULL);
EXTERN unsigned *LineOffset INIT(= NULL);
EXTERN char_u *LineWraps INIT(= NULL); // line wraps to next line

Expand All @@ -62,7 +64,7 @@ EXTERN int Screen_mco INIT(= 0); // value of p_mco used when
EXTERN schar_T *ScreenLines2 INIT(= NULL);

/*
* Buffer for one screen line (characters and attributes).
* One screen line to be displayed. Points into ScreenLines.
*/
EXTERN schar_T *current_ScreenLine INIT(= NULL);

Expand Down
69 changes: 50 additions & 19 deletions src/mouse.c
Expand Up @@ -1543,8 +1543,9 @@ jump_to_mouse(
int first;
int row = mouse_row;
int col = mouse_col;
colnr_T col_from_screen = -1;
#ifdef FEAT_FOLDING
int mouse_char;
int mouse_char = ' ';
#endif

mouse_past_bottom = FALSE;
Expand Down Expand Up @@ -1626,16 +1627,6 @@ jump_to_mouse(
if (flags & MOUSE_SETPOS)
goto retnomove; // ugly goto...

#ifdef FEAT_FOLDING
// Remember the character under the mouse, it might be a '-' or '+' in the
// fold column.
if (row >= 0 && row < Rows && col >= 0 && col <= Columns
&& ScreenLines != NULL)
mouse_char = ScreenLines[LineOffset[row] + col];
else
mouse_char = ' ';
#endif

old_curwin = curwin;
old_cursor = curwin->w_cursor;

Expand Down Expand Up @@ -1969,6 +1960,22 @@ jump_to_mouse(
}
}

if (prev_row >= 0 && prev_row < Rows && prev_col >= 0 && prev_col <= Columns
&& ScreenLines != NULL)
{
int off = LineOffset[prev_row] + prev_col;

// Only use ScreenCols[] after the window was redrawn. Mainly matters
// for tests, a user would not click before redrawing.
if (curwin->w_redr_type <= VALID_NO_UPDATE)
col_from_screen = ScreenCols[off];
#ifdef FEAT_FOLDING
// Remember the character under the mouse, it might be a '-' or '+' in
// the fold column.
mouse_char = ScreenLines[off];
#endif
}

#ifdef FEAT_FOLDING
// Check for position outside of the fold column.
if (
Expand Down Expand Up @@ -2001,16 +2008,40 @@ jump_to_mouse(
redraw_cmdline = TRUE; // show visual mode later
}

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 (col_from_screen >= 0)
{
// Use the column from ScreenCols[], it is accurate also after
// concealed characters.
curwin->w_cursor.col = col_from_screen;
if (col_from_screen == 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;
}
else
{
curwin->w_set_curswant = TRUE;
if (inclusive != NULL)
*inclusive = FALSE;
}
check_cursor_col();
}
else
{
if (inclusive != NULL)
*inclusive = TRUE;
mouse_past_eol = TRUE;
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;
}
else if (inclusive != NULL)
*inclusive = FALSE;

count = IN_BUFFER;
if (curwin != old_curwin || curwin->w_cursor.lnum != old_cursor.lnum
Expand Down

0 comments on commit b908188

Please sign in to comment.