From c8c930ea785aa393ebc819139913a9e05f0ccd45 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Sat, 11 Feb 2023 10:24:46 +0100 Subject: refactor: reduce scope of locals as per the style guide (#22206) --- src/nvim/mouse.c | 43 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 950b025e53..60efd6a72a 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -86,15 +86,11 @@ static int get_mouse_class(char *p) /// Move "pos" back to the start of the word it's in. static void find_start_of_word(pos_T *pos) { - char *line; - int cclass; - int col; - - line = ml_get(pos->lnum); - cclass = get_mouse_class(line + pos->col); + char *line = ml_get(pos->lnum); + int cclass = get_mouse_class(line + pos->col); while (pos->col > 0) { - col = pos->col - 1; + int col = pos->col - 1; col -= utf_head_off(line, line + col); if (get_mouse_class(line + col) != cclass) { break; @@ -109,7 +105,6 @@ static void find_end_of_word(pos_T *pos) { char *line; int cclass; - int col; line = ml_get(pos->lnum); if (*p_sel == 'e' && pos->col > 0) { @@ -118,7 +113,7 @@ static void find_end_of_word(pos_T *pos) } cclass = get_mouse_class(line + pos->col); while (line[pos->col] != NUL) { - col = pos->col + utfc_ptr2len(line + pos->col); + int col = pos->col + utfc_ptr2len(line + pos->col); if (get_mouse_class(line + col) != cclass) { if (*p_sel == 'e') { pos->col = col; @@ -296,18 +291,16 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) bool in_status_line; // mouse in status line static bool in_tab_line = false; // mouse clicked in tab line bool in_sep_line; // mouse in vertical separator line - int c1, c2; - pos_T save_cursor; + int c1; win_T *old_curwin = curwin; static pos_T orig_cursor; colnr_T leftcol, rightcol; pos_T end_visual; - long diff; int old_active = VIsual_active; int old_mode = VIsual_mode; int regname; - save_cursor = curwin->w_cursor; + pos_T save_cursor = curwin->w_cursor; for (;;) { which_button = get_mouse_button(KEY2TERMCAP1(c), &is_click, &is_drag); @@ -731,6 +724,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) } if (start_visual.lnum) { // right click in visual mode + long diff; // When ALT is pressed make Visual mode blockwise. if (mod_mask & MOD_MASK_ALT) { VIsual_mode = Ctrl_V; @@ -800,6 +794,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) // Middle mouse click: Put text before cursor. if (which_button == MOUSE_MIDDLE) { + int c2; if (regname == 0 && eval_has_provider("clipboard")) { regname = '*'; } @@ -888,13 +883,13 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) // A double click selects a word or a block. if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) { pos_T *pos = NULL; - int gc; if (is_click) { // If the character under the cursor (skipping white space) is // not a word character, try finding a match and select a (), // {}, [], #if/#endif, etc. block. end_visual = curwin->w_cursor; + int gc; while (gc = gchar_pos(&end_visual), ascii_iswhite(gc)) { inc(&end_visual); } @@ -1388,16 +1383,14 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) { int col = *colp; int row = *rowp; - linenr_T lnum; bool retval = false; - int off; int count; if (win->w_p_rl) { col = win->w_width_inner - 1 - col; } - lnum = win->w_topline; + linenr_T lnum = win->w_topline; while (row > 0) { // Don't include filler lines in "count" @@ -1429,7 +1422,7 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) if (!retval) { // Compute the column without wrapping. - off = win_col_off(win) - win_col_off2(win); + int off = win_col_off(win) - win_col_off2(win); if (col < off) { col = off; } @@ -1467,9 +1460,7 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp) return NULL; } - frame_T *fp; - - fp = topframe; + frame_T *fp = topframe; *rowp -= firstwin->w_winrow; for (;;) { if (fp->fr_layout == FR_LEAF) { @@ -1716,10 +1707,8 @@ static int mouse_adjust_click(win_T *wp, int row, int col) ptr_end += utfc_ptr2len(ptr_end); } - int matchid; int prev_matchid; int nudge = 0; - int cwidth = 0; vcol = offset; @@ -1727,7 +1716,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) #define DECR() nudge--; ptr_end -= utfc_ptr2len((char *)ptr_end) while (ptr < ptr_end && *ptr != NUL) { - cwidth = win_chartabsize(curwin, ptr, vcol); + int cwidth = win_chartabsize(curwin, ptr, vcol); vcol += cwidth; if (cwidth > 1 && *ptr == '\t' && nudge > 0) { // A tab will "absorb" any previous adjustments. @@ -1738,7 +1727,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) } } - matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line)); + int matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line)); if (matchid != 0) { if (wp->w_p_cole == 3) { INCR(); @@ -1780,9 +1769,7 @@ int mouse_check_fold(void) int max_col = Columns; int multigrid = ui_has(kUIMultigrid); - win_T *wp; - - wp = mouse_find_win(&click_grid, &click_row, &click_col); + win_T *wp = mouse_find_win(&click_grid, &click_row, &click_col); if (wp && multigrid) { max_row = wp->w_grid_alloc.rows; max_col = wp->w_grid_alloc.cols; -- cgit From d6ecead36406233cc56353dd05f3380f0497630f Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 14 Mar 2023 11:49:46 +0100 Subject: refactor(screen): screen.c delenda est drawscreen.c vs screen.c makes absolutely no sense. The screen exists only to draw upon it, therefore helper functions are distributed randomly between screen.c and the file that does the redrawing. In addition screen.c does a lot of drawing on the screen. It made more sense for vim/vim as our grid.c is their screen.c Not sure if we want to dump all the code for option chars into optionstr.c, so keep these in a optionchar.c for now. --- src/nvim/mouse.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 60efd6a72a..95fe4d70d3 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -35,7 +35,6 @@ #include "nvim/option.h" #include "nvim/plines.h" #include "nvim/pos.h" -#include "nvim/screen.h" #include "nvim/search.h" #include "nvim/state.h" #include "nvim/statusline.h" -- cgit From 84a4319545ad280d48a41e4cafaf0622c4278a16 Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Tue, 18 Apr 2023 02:00:49 +0200 Subject: fix(mouse): cmdline click registered as statuscolumn (#23163) --- src/nvim/mouse.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 95fe4d70d3..28b40994a1 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1097,7 +1097,8 @@ retnomove: return IN_UNKNOWN; } - on_status_line = (grid == DEFAULT_GRID_HANDLE && row + wp->w_winbar_height >= wp->w_height) + bool below_window = grid == DEFAULT_GRID_HANDLE && row + wp->w_winbar_height >= wp->w_height; + on_status_line = (below_window) ? row + wp->w_winbar_height - wp->w_height + 1 == 1 : false; @@ -1105,7 +1106,7 @@ retnomove: ? wp->w_winbar_height != 0 : false; - on_statuscol = !on_status_line && !on_winbar && col < win_col_off(wp) + on_statuscol = !below_window && !on_status_line && !on_winbar && col < win_col_off(wp) ? *wp->w_p_stc != NUL : false; @@ -1144,7 +1145,7 @@ retnomove: dragwin = NULL; // winpos and height may change in win_enter()! - if (grid == DEFAULT_GRID_HANDLE && row + wp->w_winbar_height >= wp->w_height) { + if (below_window) { // In (or below) status line status_line_offset = row + wp->w_winbar_height - wp->w_height + 1; dragwin = wp; -- cgit From a4b2400804355e99813f39a6b38d8f38667f8bdd Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Tue, 25 Apr 2023 05:05:04 +0200 Subject: fix(statusline): also allow right click when 'mousemodel' is "popup*" (#23258) Problem: The 'statusline'-format ui elements do not receive right click events when "mousemodel" is "popup*" Solution: Do not draw popupmenu and handle click event instead. --- src/nvim/mouse.c | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 28b40994a1..c00ccdd51a 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -212,22 +212,31 @@ static int get_fpos_of_mouse(pos_T *mpos) if (wp == NULL) { return IN_UNKNOWN; } + int winrow = row; + int wincol = col; + + // compute the position in the buffer line from the posn on the screen + bool below_buffer = mouse_comp_pos(wp, &row, &col, &mpos->lnum); + + if (!below_buffer && *wp->w_p_stc != NUL && mouse_col < win_col_off(wp)) { + return MOUSE_STATUSCOL; + } // winpos and height may change in win_enter()! - if (row + wp->w_winbar_height >= wp->w_height) { // In (or below) status line + if (winrow + wp->w_winbar_height >= wp->w_height) { // In (or below) status line return IN_STATUS_LINE; } - if (col >= wp->w_width) { // In vertical separator line - return IN_SEP_LINE; + + if (winrow == -1 && wp->w_winbar_height != 0) { + return MOUSE_WINBAR; } - if (wp != curwin) { - return IN_UNKNOWN; + if (wincol >= wp->w_width) { // In vertical separator line + return IN_SEP_LINE; } - // compute the position in the buffer line from the posn on the screen - if (mouse_comp_pos(curwin, &row, &col, &mpos->lnum)) { - return IN_STATUS_LINE; // past bottom + if (wp != curwin || below_buffer) { + return IN_UNKNOWN; } mpos->col = vcol2col(wp, mpos->lnum, col); @@ -530,6 +539,11 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) // shift-left button -> right button // alt-left button -> alt-right button if (mouse_model_popup()) { + pos_T m_pos; + int m_pos_flag = get_fpos_of_mouse(&m_pos); + if (m_pos_flag & (IN_STATUS_LINE|MOUSE_WINBAR|MOUSE_STATUSCOL)) { + goto popupexit; + } if (which_button == MOUSE_RIGHT && !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))) { if (!is_click) { @@ -539,17 +553,14 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) } jump_flags = 0; if (strcmp(p_mousem, "popup_setpos") == 0) { - // First set the cursor position before showing the popup - // menu. + // First set the cursor position before showing the popup menu. if (VIsual_active) { - pos_T m_pos; - // set MOUSE_MAY_STOP_VIS if we are outside the - // selection or the current window (might have false - // negative here) + // set MOUSE_MAY_STOP_VIS if we are outside the selection + // or the current window (might have false negative here) if (mouse_row < curwin->w_winrow || mouse_row > (curwin->w_winrow + curwin->w_height)) { jump_flags = MOUSE_MAY_STOP_VIS; - } else if (get_fpos_of_mouse(&m_pos) != IN_BUFFER) { + } else if (m_pos_flag != IN_BUFFER) { jump_flags = MOUSE_MAY_STOP_VIS; } else { if (VIsual_mode == 'V') { @@ -593,6 +604,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) mod_mask &= ~MOD_MASK_SHIFT; } } +popupexit: if ((State & (MODE_NORMAL | MODE_INSERT)) && !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))) { @@ -644,7 +656,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) in_sep_line = (jump_flags & IN_SEP_LINE); if ((in_winbar || in_status_line || in_statuscol) && is_click) { - // Handle click event on window bar or status lin + // Handle click event on window bar, status line or status column int click_grid = mouse_grid; int click_row = mouse_row; int click_col = mouse_col; @@ -672,7 +684,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) call_click_def_func(click_defs, click_col, which_button); break; default: - assert(false && "winbar and statusline only support %@ for clicks"); + assert(false && "winbar, statusline and statuscolumn only support %@ for clicks"); break; } } -- cgit From 3b0df1780e2c8526bda5dead18ee7cc45925caba Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Wed, 26 Apr 2023 23:23:44 +0200 Subject: refactor: uncrustify Notable changes: replace all infinite loops to `while(true)` and remove `int` from `unsigned int`. --- src/nvim/mouse.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index c00ccdd51a..e03eec184f 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -310,7 +310,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) pos_T save_cursor = curwin->w_cursor; - for (;;) { + while (true) { which_button = get_mouse_button(KEY2TERMCAP1(c), &is_click, &is_drag); if (is_drag) { // If the next character is the same mouse event then use that @@ -1474,7 +1474,7 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp) frame_T *fp = topframe; *rowp -= firstwin->w_winrow; - for (;;) { + while (true) { if (fp->fr_layout == FR_LEAF) { break; } @@ -1580,7 +1580,7 @@ static colnr_T scroll_line_len(linenr_T lnum) colnr_T col = 0; char *line = ml_get(lnum); if (*line != NUL) { - for (;;) { + while (true) { int numchar = win_chartabsize(curwin, line, col); MB_PTR_ADV(line); if (*line == NUL) { // don't count the last character -- cgit From 7c1921e9d69e008781c9fb16c11e843f7bd9099a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 2 May 2023 15:25:41 +0800 Subject: fix(mouse): fix popup_setpos position check with ext_multigrid (#23436) --- src/nvim/mouse.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index e03eec184f..09352b370e 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -223,7 +223,7 @@ static int get_fpos_of_mouse(pos_T *mpos) } // winpos and height may change in win_enter()! - if (winrow + wp->w_winbar_height >= wp->w_height) { // In (or below) status line + if (winrow + wp->w_winbar_height >= wp->w_height_inner) { // In (or below) status line return IN_STATUS_LINE; } @@ -231,7 +231,7 @@ static int get_fpos_of_mouse(pos_T *mpos) return MOUSE_WINBAR; } - if (wincol >= wp->w_width) { // In vertical separator line + if (wincol >= wp->w_width_inner) { // In vertical separator line return IN_SEP_LINE; } @@ -557,10 +557,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) if (VIsual_active) { // set MOUSE_MAY_STOP_VIS if we are outside the selection // or the current window (might have false negative here) - if (mouse_row < curwin->w_winrow - || mouse_row > (curwin->w_winrow + curwin->w_height)) { - jump_flags = MOUSE_MAY_STOP_VIS; - } else if (m_pos_flag != IN_BUFFER) { + if (m_pos_flag != IN_BUFFER) { jump_flags = MOUSE_MAY_STOP_VIS; } else { if (VIsual_mode == 'V') { -- cgit From 26a9f0e94eb62047f0c2bb99401a8ac09840d0dd Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Thu, 27 Apr 2023 19:08:20 +0200 Subject: vim-patch:9.0.0901: setting w_leftcol and handling side effects is confusing Problem: Setting w_leftcol and handling side effects is confusing. Solution: Use a function to set w_leftcol() and handle side effects. https://github.com/vim/vim/commit/0c34d562647f029faca40f7733ccfb7b5377672b Co-authored-by: Bram Moolenaar --- src/nvim/mouse.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 09352b370e..ead8dc2195 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1648,8 +1648,6 @@ bool mouse_scroll_horiz(int dir) return false; } - curwin->w_leftcol = (colnr_T)leftcol; - // When the line of the cursor is too short, move the cursor to the // longest visible line. if (!virtual_active() @@ -1658,7 +1656,7 @@ bool mouse_scroll_horiz(int dir) curwin->w_cursor.col = 0; } - return leftcol_changed(); + return set_leftcol(leftcol); } /// Adjusts the clicked column position when 'conceallevel' > 0 -- cgit From 5ba11087b60eb7cbcaa1ea4ccbb0b1a6bcf3c1be Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Fri, 28 Apr 2023 03:59:53 +0200 Subject: vim-patch:9.0.0911: with 'smoothscroll' set mouse click position may be wrong Problem: With 'smoothscroll' set mouse click position may be wrong. Solution: Adjust computations for w_skipcol. (Yee Cheng Chin, closes vim/vim#11514) https://github.com/vim/vim/commit/e6392b102151ec69fad232bcf00591230cef8e1c Co-authored-by: Yee Cheng Chin --- src/nvim/mouse.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index ead8dc2195..b890727a98 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1410,9 +1410,22 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) } else { row -= win_get_fill(win, lnum); } - count = plines_win_nofill(win, lnum, true); + count = plines_win_nofill(win, lnum, false); } else { - count = plines_win(win, lnum, true); + count = plines_win(win, lnum, false); + } + + if (win->w_skipcol > 0 && lnum == win->w_topline) { + // Adjust for 'smoothscroll' clipping the top screen lines. + // A similar formula is used in curs_columns(). + int width1 = win->w_width - win_col_off(win); + int skip_lines = 0; + if (win->w_skipcol > width1) { + skip_lines = (win->w_skipcol - width1) / (width1 + win_col_off2(win)) + 1; + } else if (win->w_skipcol > 0) { + skip_lines = 1; + } + count -= skip_lines; } if (count > row) { @@ -1436,8 +1449,11 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) col = off; } col += row * (win->w_width_inner - off); - // add skip column (for long wrapping line) - col += win->w_skipcol; + + // Add skip column for the topline. + if (lnum == win->w_topline) { + col += win->w_skipcol; + } } if (!win->w_p_wrap) { -- cgit From 5b111a8f00f8dbe458a3d437c9f06c9419d24840 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Tue, 2 May 2023 12:00:42 +0200 Subject: fix(ui): adjust 'smoothscroll' for inner dimensions --- src/nvim/mouse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index b890727a98..79bd65a88f 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1418,7 +1418,7 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) if (win->w_skipcol > 0 && lnum == win->w_topline) { // Adjust for 'smoothscroll' clipping the top screen lines. // A similar formula is used in curs_columns(). - int width1 = win->w_width - win_col_off(win); + int width1 = win->w_width_inner - win_col_off(win); int skip_lines = 0; if (win->w_skipcol > width1) { skip_lines = (win->w_skipcol - width1) / (width1 + win_col_off2(win)) + 1; -- cgit From dc394b9641f92a5014147da58f5e14fd1681ec0f Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 3 May 2023 10:29:19 +0800 Subject: fix(mouse): fix popup menu position check with winbar (#23456) --- src/nvim/mouse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 79bd65a88f..8189fde83c 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -223,7 +223,7 @@ static int get_fpos_of_mouse(pos_T *mpos) } // winpos and height may change in win_enter()! - if (winrow + wp->w_winbar_height >= wp->w_height_inner) { // In (or below) status line + if (winrow >= wp->w_height_inner) { // In (or below) status line return IN_STATUS_LINE; } -- cgit From a3fba5cafcf124946ea65a68fc1b9dfbeb197525 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 5 Jun 2023 17:11:58 +0800 Subject: fix(mouse): handle folded lines with virt_lines attached to line above (#23912) --- src/nvim/mouse.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 8189fde83c..208956e65d 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1310,14 +1310,13 @@ retnomove: } first = false; - if (hasFolding(curwin->w_topline, NULL, &curwin->w_topline) - && curwin->w_topline == curbuf->b_ml.ml_line_count) { - break; - } - if (curwin->w_topfill > 0) { curwin->w_topfill--; } else { + if (hasFolding(curwin->w_topline, NULL, &curwin->w_topline) + && curwin->w_topline == curbuf->b_ml.ml_line_count) { + break; + } curwin->w_topline++; curwin->w_topfill = win_get_fill(curwin, curwin->w_topline); } @@ -1403,8 +1402,7 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) while (row > 0) { // Don't include filler lines in "count" - if (win_may_fill(win) - && !hasFoldingWin(win, lnum, NULL, NULL, true, NULL)) { + if (win_may_fill(win)) { if (lnum == win->w_topline) { row -= win->w_topfill; } else { -- cgit From fcf3519c65a2d6736de437f686e788684a6c8564 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 17 Apr 2023 22:18:58 +0200 Subject: refactor: remove long long is 32-bits even on 64-bit windows which makes the type suboptimal for a codebase meant to be cross-platform. --- src/nvim/mouse.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 208956e65d..9c6acf9f80 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -284,7 +284,7 @@ static int get_fpos_of_mouse(pos_T *mpos) /// @param fixindent PUT_FIXINDENT if fixing indent necessary /// /// @return true if start_arrow() should be called for edit mode. -bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) +bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent) { static bool got_click = false; // got a click some time back @@ -732,7 +732,7 @@ popupexit: } if (start_visual.lnum) { // right click in visual mode - long diff; + linenr_T diff; // When ALT is pressed make Visual mode blockwise. if (mod_mask & MOD_MASK_ALT) { VIsual_mode = Ctrl_V; @@ -1616,17 +1616,17 @@ static linenr_T find_longest_lnum(void) if (curwin->w_topline <= curwin->w_cursor.lnum && curwin->w_botline > curwin->w_cursor.lnum && curwin->w_botline <= curbuf->b_ml.ml_line_count + 1) { - long max = 0; + colnr_T max = 0; // Use maximum of all visible lines. Remember the lnum of the // longest line, closest to the cursor line. Used when scrolling // below. for (linenr_T lnum = curwin->w_topline; lnum < curwin->w_botline; lnum++) { colnr_T len = scroll_line_len(lnum); - if (len > (colnr_T)max) { + if (len > max) { max = len; ret = lnum; - } else if (len == (colnr_T)max + } else if (len == max && abs(lnum - curwin->w_cursor.lnum) < abs(ret - curwin->w_cursor.lnum)) { ret = lnum; -- cgit From bf52fb7193ca08ceca292cfca9156380a6661979 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 12 Jul 2023 08:50:34 +0800 Subject: fix(mouse): copy the line before syntax matching (#24320) --- src/nvim/mouse.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 9c6acf9f80..aca15eb0e2 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1692,7 +1692,8 @@ static int mouse_adjust_click(win_T *wp, int row, int col) // highlighting the second byte, not the ninth. linenr_T lnum = wp->w_cursor.lnum; - char *line = ml_get(lnum); + // Make a copy of the line, because syntax matching may free it. + char *line = xstrdup(ml_get(lnum)); char *ptr = line; char *ptr_end; char *ptr_row_offset = line; // Where we begin adjusting `ptr_end` @@ -1733,8 +1734,8 @@ static int mouse_adjust_click(win_T *wp, int row, int col) vcol = offset; -#define INCR() nudge++; ptr_end += utfc_ptr2len((char *)ptr_end) -#define DECR() nudge--; ptr_end -= utfc_ptr2len((char *)ptr_end) +#define INCR() nudge++; ptr_end += utfc_ptr2len(ptr_end) +#define DECR() nudge--; ptr_end -= utfc_ptr2len(ptr_end) while (ptr < ptr_end && *ptr != NUL) { int cwidth = win_chartabsize(curwin, ptr, vcol); @@ -1776,6 +1777,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) ptr += utfc_ptr2len(ptr); } + xfree(line); return col + nudge; } -- cgit From 5fb4c397a1da2737262ac7686666dc2596db50c2 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 24 Jul 2023 18:16:53 +0800 Subject: fix(mouse): drag vsep of window with 'statuscolumn' (#24462) Problem: Cannot drag a vertical separator to the right of a window whose 'statuscolumn' is wider than itself. Solution: Never treat a click on a vertical separator as a click on 'statuscolumn'. --- src/nvim/mouse.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index aca15eb0e2..d8341d2b10 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1107,21 +1107,11 @@ retnomove: } bool below_window = grid == DEFAULT_GRID_HANDLE && row + wp->w_winbar_height >= wp->w_height; - on_status_line = (below_window) - ? row + wp->w_winbar_height - wp->w_height + 1 == 1 - : false; - - on_winbar = (row == -1) - ? wp->w_winbar_height != 0 - : false; - - on_statuscol = !below_window && !on_status_line && !on_winbar && col < win_col_off(wp) - ? *wp->w_p_stc != NUL - : false; - - on_sep_line = grid == DEFAULT_GRID_HANDLE && col >= wp->w_width - ? col - wp->w_width + 1 == 1 - : false; + on_status_line = below_window && row + wp->w_winbar_height - wp->w_height + 1 == 1; + on_sep_line = grid == DEFAULT_GRID_HANDLE && col >= wp->w_width && col - wp->w_width + 1 == 1; + on_winbar = row == -1 && wp->w_winbar_height != 0; + on_statuscol = !below_window && !on_status_line && !on_sep_line && !on_winbar + && *wp->w_p_stc != NUL && col < win_col_off(wp); // The rightmost character of the status line might be a vertical // separator character if there is no connecting window to the right. -- cgit From 551998b7eed7dd411e4d14f65b108ae8a93c4081 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 18 Aug 2023 15:00:03 +0800 Subject: vim-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: vim/vim#12808 https://github.com/vim/vim/commit/e500ae8e29ad921378085f5d70ee5c0c537be1ba Remove the mouse_adjust_click() function. There is a difference in behavior with the old mouse_adjust_click() approach: when clicking on the character immediately after concealed text that is completely hidden, cursor is put on the clicked character rather than at the start of the concealed text. The new behavior is better, but it causes unnecessary scrolling in a functional test (which is an existing issue unrelated to these patches), so adjust the test. Now fully merged: vim-patch:9.0.0177: cursor position wrong with 'virtualedit' and mouse click --- src/nvim/mouse.c | 188 +++++++++++++++++-------------------------------------- 1 file changed, 57 insertions(+), 131 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index d8341d2b10..0f3405bf0d 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1329,15 +1329,15 @@ retnomove: } } + colnr_T col_from_screen = -1; + int mouse_fold_flags = 0; + mouse_check_grid(&col_from_screen, &mouse_fold_flags); + // compute the position in the buffer line from the posn on the screen if (mouse_comp_pos(curwin, &row, &col, &curwin->w_cursor.lnum)) { 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) { VIsual = old_cursor; @@ -1352,6 +1352,10 @@ retnomove: } } + if (col_from_screen >= 0) { + 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 @@ -1369,14 +1373,14 @@ retnomove: count |= CURSOR_MOVED; // Cursor has moved } - count |= mouse_check_fold(); + count |= mouse_fold_flags; return count; } -// Compute the position in the buffer line from the posn on the screen in -// window "win". -// Returns true if the position is below the last line. +/// Compute the position in the buffer line from the posn on the screen in +/// window "win". +/// Returns true if the position is below the last line. bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) { int col = *colp; @@ -1573,9 +1577,7 @@ static void set_mouse_topline(win_T *wp) orig_topfill = wp->w_topfill; } -/// /// Return length of line "lnum" for horizontal scrolling. -/// static colnr_T scroll_line_len(linenr_T lnum) { colnr_T col = 0; @@ -1663,116 +1665,9 @@ bool mouse_scroll_horiz(int dir) return set_leftcol(leftcol); } -/// Adjusts the clicked column position when 'conceallevel' > 0 -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; - } - - // `col` is the position within the current line that is highlighted by the - // cursor without consideration for concealed characters. The current line is - // scanned *up to* `col`, nudging it left or right when concealed characters - // are encountered. - // - // win_chartabsize() is used to keep track of the virtual column position - // relative to the line's bytes. For example: if col == 9 and the line - // starts with a tab that's 8 columns wide, we would want the cursor to be - // highlighting the second byte, not the ninth. - - linenr_T lnum = wp->w_cursor.lnum; - // Make a copy of the line, because syntax matching may free it. - char *line = xstrdup(ml_get(lnum)); - char *ptr = line; - char *ptr_end; - char *ptr_row_offset = line; // Where we begin adjusting `ptr_end` - - // Find the offset where scanning should begin. - int offset = wp->w_leftcol; - if (row > 0) { - offset += row * (wp->w_width_inner - win_col_off(wp) - win_col_off2(wp) - - wp->w_leftcol + wp->w_skipcol); - } - - int vcol; - - if (offset) { - // Skip everything up to an offset since nvim takes care of displaying the - // correct portion of the line when horizontally scrolling. - // When 'wrap' is enabled, only the row (of the wrapped line) needs to be - // checked for concealed characters. - vcol = 0; - while (vcol < offset && *ptr != NUL) { - vcol += win_chartabsize(curwin, ptr, vcol); - ptr += utfc_ptr2len(ptr); - } - - ptr_row_offset = ptr; - } - - // Align `ptr_end` with `col` - vcol = offset; - ptr_end = ptr_row_offset; - while (vcol < col && *ptr_end != NUL) { - vcol += win_chartabsize(curwin, ptr_end, vcol); - ptr_end += utfc_ptr2len(ptr_end); - } - - int prev_matchid; - int nudge = 0; - - vcol = offset; - -#define INCR() nudge++; ptr_end += utfc_ptr2len(ptr_end) -#define DECR() nudge--; ptr_end -= utfc_ptr2len(ptr_end) - - while (ptr < ptr_end && *ptr != NUL) { - int cwidth = win_chartabsize(curwin, ptr, vcol); - vcol += cwidth; - if (cwidth > 1 && *ptr == '\t' && nudge > 0) { - // A tab will "absorb" any previous adjustments. - cwidth = MIN(cwidth, nudge); - while (cwidth > 0) { - DECR(); - cwidth--; - } - } - - int matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line)); - if (matchid != 0) { - if (wp->w_p_cole == 3) { - INCR(); - } else { - if (!(row > 0 && ptr == ptr_row_offset) - && (wp->w_p_cole == 1 || (wp->w_p_cole == 2 - && (wp->w_p_lcs_chars.conceal != NUL - || syn_get_sub_char() != NUL)))) { - // At least one placeholder character will be displayed. - DECR(); - } - - prev_matchid = matchid; - - while (prev_matchid == matchid && *ptr != NUL) { - INCR(); - ptr += utfc_ptr2len(ptr); - matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line)); - } - - continue; - } - } - - ptr += utfc_ptr2len(ptr); - } - - xfree(line); - return col + nudge; -} - -// Check clicked cell is foldcolumn -int mouse_check_fold(void) +/// Check clicked cell on its grid +static void mouse_check_grid(colnr_T *vcolp, int *flagsp) + FUNC_ATTR_NONNULL_ALL { int click_grid = mouse_grid; int click_row = mouse_row; @@ -1780,7 +1675,8 @@ int mouse_check_fold(void) int mouse_char = ' '; int max_row = Rows; int max_col = Columns; - int multigrid = ui_has(kUIMultigrid); + bool multigrid = ui_has(kUIMultigrid); + colnr_T col_from_screen = -1; win_T *wp = mouse_find_win(&click_grid, &click_row, &click_col); if (wp && multigrid) { @@ -1792,14 +1688,46 @@ int mouse_check_fold(void) && mouse_col >= 0 && mouse_col < max_col) { ScreenGrid *gp = multigrid ? &wp->w_grid_alloc : &default_grid; int fdc = win_fdccol_count(wp); - int row = multigrid && mouse_grid == 0 ? click_row : mouse_row; - int col = multigrid && mouse_grid == 0 ? click_col : mouse_col; + int use_row = multigrid && mouse_grid == 0 ? click_row : mouse_row; + int use_col = multigrid && mouse_grid == 0 ? click_col : mouse_col; - // Remember the character under the mouse, might be one of foldclose or - // foldopen fillchars in the fold column. if (gp->chars != NULL) { - mouse_char = utf_ptr2char((char *)gp->chars[gp->line_offset[row] - + (unsigned)col]); + const size_t off = gp->line_offset[use_row] + (size_t)use_col; + + // Only use vcols[] after the window was redrawn. Mainly matters + // for tests, a user would not click before redrawing. + if (wp->w_redr_type == 0) { + col_from_screen = gp->vcols[off]; + } + + if (col_from_screen == MAXCOL) { + // When clicking after end of line, still need to set correct curswant + size_t off_l = gp->line_offset[use_row]; + if (gp->vcols[off_l] < MAXCOL) { + // Binary search to find last char in line + size_t off_r = off; + while (off_l < off_r) { + size_t off_m = (off_l + off_r + 1) / 2; + if (gp->vcols[off_m] < MAXCOL) { + off_l = off_m; + } else { + off_r = off_m - 1; + } + } + *vcolp = gp->vcols[off_r] + (int)(off - off_r); + } else { + // Shouldn't normally happen + *vcolp = MAXCOL; + } + } else if (col_from_screen >= 0) { + // Use the virtual column from vcols[], it is accurate also after + // concealed characters. + *vcolp = col_from_screen; + } + + // Remember the character under the mouse, might be one of foldclose or + // foldopen fillchars in the fold column. + mouse_char = utf_ptr2char((char *)gp->chars[off]); } // Check for position outside of the fold column. @@ -1810,10 +1738,8 @@ int mouse_check_fold(void) } if (wp && mouse_char == wp->w_p_fcs_chars.foldclosed) { - return MOUSE_FOLD_OPEN; + *flagsp |= MOUSE_FOLD_OPEN; } else if (mouse_char != ' ') { - return MOUSE_FOLD_CLOSE; + *flagsp |= MOUSE_FOLD_CLOSE; } - - return 0; } -- cgit From cc35352f65f823259675f84a915ee03d2423913e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 21 Aug 2023 15:23:32 +0800 Subject: vim-patch:8.1.2062: the mouse code is spread out (#24817) Problem: The mouse code is spread out. Solution: Move all the mouse code to mouse.c. (Yegappan Lakshmanan, closes vim/vim#4959) https://github.com/vim/vim/commit/b20b9e14ddd8db111e886ad0494e15b955159426 Also move getmousepos() there. N/A patches for version.c: vim-patch:8.1.2070: mouse code is spread out Problem: Mouse code is spread out. Solution: Move mouse terminal code parsing to mouse.c. (Yegappan Lakshmanan, closes vim/vim#4966) https://github.com/vim/vim/commit/b8ff5c271ee5dcef6f63436b77e228e062ff9a0e Co-authored-by: Bram Moolenaar --- src/nvim/mouse.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 0f3405bf0d..bd57101de5 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -13,6 +13,7 @@ #include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/drawscreen.h" +#include "nvim/edit.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/eval/typval_defs.h" @@ -34,6 +35,7 @@ #include "nvim/ops.h" #include "nvim/option.h" #include "nvim/plines.h" +#include "nvim/popupmenu.h" #include "nvim/pos.h" #include "nvim/search.h" #include "nvim/state.h" @@ -959,6 +961,82 @@ popupexit: return moved; } +void ins_mouse(int c) +{ + pos_T tpos; + win_T *old_curwin = curwin; + + undisplay_dollar(); + tpos = curwin->w_cursor; + if (do_mouse(NULL, c, BACKWARD, 1, 0)) { + win_T *new_curwin = curwin; + + if (curwin != old_curwin && win_valid(old_curwin)) { + // Mouse took us to another window. We need to go back to the + // previous one to stop insert there properly. + curwin = old_curwin; + curbuf = curwin->w_buffer; + if (bt_prompt(curbuf)) { + // Restart Insert mode when re-entering the prompt buffer. + curbuf->b_prompt_insert = 'A'; + } + } + start_arrow(curwin == old_curwin ? &tpos : NULL); + if (curwin != new_curwin && win_valid(new_curwin)) { + curwin = new_curwin; + curbuf = curwin->w_buffer; + } + set_can_cindent(true); + } + + // redraw status lines (in case another window became active) + redraw_statuslines(); +} + +void ins_mousescroll(int dir) +{ + win_T *const old_curwin = curwin; + pos_T tpos = curwin->w_cursor; + + if (mouse_row >= 0 && mouse_col >= 0) { + int row = mouse_row, col = mouse_col, grid = mouse_grid; + + // find the window at the pointer coordinates + win_T *wp = mouse_find_win(&grid, &row, &col); + if (wp == NULL) { + return; + } + curwin = wp; + curbuf = curwin->w_buffer; + } + if (curwin == old_curwin) { + undisplay_dollar(); + } + + // Don't scroll the window in which completion is being done. + if (!pum_visible() || curwin != old_curwin) { + if (dir == MSCR_DOWN || dir == MSCR_UP) { + if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { + scroll_redraw(dir, curwin->w_botline - curwin->w_topline); + } else if (p_mousescroll_vert > 0) { + scroll_redraw(dir, (linenr_T)p_mousescroll_vert); + } + } else { + mouse_scroll_horiz(dir); + } + } + + curwin->w_redr_status = true; + + curwin = old_curwin; + curbuf = curwin->w_buffer; + + if (!equalpos(curwin->w_cursor, tpos)) { + start_arrow(&tpos); + set_can_cindent(true); + } +} + /// Return true if "c" is a mouse key. bool is_mouse_key(int c) { @@ -1378,6 +1456,57 @@ retnomove: return count; } +/// Mouse scroll wheel: Default action is to scroll three lines, or one page +/// when Shift or Ctrl is used. +/// K_MOUSEUP (cap->arg == 1) or K_MOUSEDOWN (cap->arg == 0) or +/// K_MOUSELEFT (cap->arg == -1) or K_MOUSERIGHT (cap->arg == -2) +void nv_mousescroll(cmdarg_T *cap) +{ + win_T *old_curwin = curwin; + + if (mouse_row >= 0 && mouse_col >= 0) { + int grid, row, col; + + grid = mouse_grid; + row = mouse_row; + col = mouse_col; + + // find the window at the pointer coordinates + win_T *wp = mouse_find_win(&grid, &row, &col); + if (wp == NULL) { + return; + } + curwin = wp; + curbuf = curwin->w_buffer; + } + + if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) { + if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { + (void)onepage(cap->arg ? FORWARD : BACKWARD, 1); + } else if (p_mousescroll_vert > 0) { + cap->count1 = (int)p_mousescroll_vert; + cap->count0 = (int)p_mousescroll_vert; + nv_scroll_line(cap); + } + } else { + mouse_scroll_horiz(cap->arg); + } + if (curwin != old_curwin && curwin->w_p_cul) { + redraw_for_cursorline(curwin); + } + + curwin->w_redr_status = true; + + curwin = old_curwin; + curbuf = curwin->w_buffer; +} + +/// Mouse clicks and drags. +void nv_mouse(cmdarg_T *cap) +{ + (void)do_mouse(cap->oap, cap->cmdchar, BACKWARD, cap->count1, 0); +} + /// Compute the position in the buffer line from the posn on the screen in /// window "win". /// Returns true if the position is below the last line. @@ -1743,3 +1872,44 @@ static void mouse_check_grid(colnr_T *vcolp, int *flagsp) *flagsp |= MOUSE_FOLD_CLOSE; } } + +/// "getmousepos()" function +void f_getmousepos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +{ + int row = mouse_row; + int col = mouse_col; + int grid = mouse_grid; + varnumber_T winid = 0; + varnumber_T winrow = 0; + varnumber_T wincol = 0; + linenr_T lnum = 0; + varnumber_T column = 0; + + tv_dict_alloc_ret(rettv); + dict_T *d = rettv->vval.v_dict; + + tv_dict_add_nr(d, S_LEN("screenrow"), (varnumber_T)mouse_row + 1); + tv_dict_add_nr(d, S_LEN("screencol"), (varnumber_T)mouse_col + 1); + + win_T *wp = mouse_find_win(&grid, &row, &col); + if (wp != NULL) { + int height = wp->w_height + wp->w_hsep_height + wp->w_status_height; + // The height is adjusted by 1 when there is a bottom border. This is not + // necessary for a top border since `row` starts at -1 in that case. + if (row < height + wp->w_border_adj[2]) { + winid = wp->handle; + winrow = row + 1 + wp->w_winrow_off; // Adjust by 1 for top border + wincol = col + 1 + wp->w_wincol_off; // Adjust by 1 for left border + if (row >= 0 && row < wp->w_height && col >= 0 && col < wp->w_width) { + (void)mouse_comp_pos(wp, &row, &col, &lnum); + col = vcol2col(wp, lnum, col); + column = col + 1; + } + } + } + tv_dict_add_nr(d, S_LEN("winid"), winid); + tv_dict_add_nr(d, S_LEN("winrow"), winrow); + tv_dict_add_nr(d, S_LEN("wincol"), wincol); + tv_dict_add_nr(d, S_LEN("line"), (varnumber_T)lnum); + tv_dict_add_nr(d, S_LEN("column"), column); +} -- cgit From bd3c1c75796838ad0363849c9c04934141fc4ac5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 21 Aug 2023 20:44:26 +0800 Subject: vim-patch:9.0.0886: horizontal mouse scroll only works in the GUI Problem: Horizontal mouse scroll only works in the GUI. Solution: Make horizontal mouse scroll also work in a terminal. (Christopher Plewright, closes vim/vim#11448) https://github.com/vim/vim/commit/44c2209352d56d70b1fc0215e81f1822d55aa563 Co-authored-by: Christopher Plewright --- src/nvim/mouse.c | 201 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 108 insertions(+), 93 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index bd57101de5..f9177ac355 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -993,48 +993,35 @@ void ins_mouse(int c) redraw_statuslines(); } +/// Implementation for scrolling in direction "dir", which is one of the MSCR_ +/// values. void ins_mousescroll(int dir) { - win_T *const old_curwin = curwin; - pos_T tpos = curwin->w_cursor; - - if (mouse_row >= 0 && mouse_col >= 0) { - int row = mouse_row, col = mouse_col, grid = mouse_grid; + cmdarg_T cap; + CLEAR_FIELD(cap); - // find the window at the pointer coordinates - win_T *wp = mouse_find_win(&grid, &row, &col); - if (wp == NULL) { - return; - } - curwin = wp; - curbuf = curwin->w_buffer; - } - if (curwin == old_curwin) { - undisplay_dollar(); - } + oparg_T oa; + clear_oparg(&oa); + cap.oap = &oa; - // Don't scroll the window in which completion is being done. - if (!pum_visible() || curwin != old_curwin) { - if (dir == MSCR_DOWN || dir == MSCR_UP) { - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { - scroll_redraw(dir, curwin->w_botline - curwin->w_topline); - } else if (p_mousescroll_vert > 0) { - scroll_redraw(dir, (linenr_T)p_mousescroll_vert); - } - } else { - mouse_scroll_horiz(dir); - } - } - - curwin->w_redr_status = true; - - curwin = old_curwin; - curbuf = curwin->w_buffer; - - if (!equalpos(curwin->w_cursor, tpos)) { - start_arrow(&tpos); - set_can_cindent(true); + cap.arg = dir; + switch (dir) { + case MSCR_UP: + cap.cmdchar = K_MOUSEUP; + break; + case MSCR_DOWN: + cap.cmdchar = K_MOUSEDOWN; + break; + case MSCR_LEFT: + cap.cmdchar = K_MOUSELEFT; + break; + case MSCR_RIGHT: + cap.cmdchar = K_MOUSERIGHT; + break; + default: + siemsg("Invalid ins_mousescroll() argument: %d", dir); } + do_mousescroll(MODE_INSERT, &cap); } /// Return true if "c" is a mouse key. @@ -1456,20 +1443,44 @@ retnomove: return count; } -/// Mouse scroll wheel: Default action is to scroll three lines, or one page -/// when Shift or Ctrl is used. -/// K_MOUSEUP (cap->arg == 1) or K_MOUSEDOWN (cap->arg == 0) or -/// K_MOUSELEFT (cap->arg == -1) or K_MOUSERIGHT (cap->arg == -2) -void nv_mousescroll(cmdarg_T *cap) +/// Make a horizontal scroll to "leftcol". +/// @return true if the cursor moved, false otherwise. +static bool do_mousescroll_horiz(colnr_T leftcol) { - win_T *old_curwin = curwin; + if (curwin->w_p_wrap) { + return false; // no horizontal scrolling when wrapping + } + if (curwin->w_leftcol == leftcol) { + return false; // already there + } - if (mouse_row >= 0 && mouse_col >= 0) { - int grid, row, col; + // When the line of the cursor is too short, move the cursor to the + // longest visible line. + if (!virtual_active() + && leftcol > scroll_line_len(curwin->w_cursor.lnum)) { + curwin->w_cursor.lnum = find_longest_lnum(); + curwin->w_cursor.col = 0; + } - grid = mouse_grid; - row = mouse_row; - col = mouse_col; + return set_leftcol(leftcol); +} + +/// Mouse scroll wheel: Default action is to scroll p_mousescroll_vert lines, +/// or p_mousescroll_hor, or one page when Shift or Ctrl is used. +/// Direction is indicated by "cap->arg": +/// K_MOUSEUP - MSCR_UP +/// K_MOUSEDOWN - MSCR_DOWN +/// K_MOUSELEFT - MSCR_LEFT +/// K_MOUSERIGHT - MSCR_RIGHT +void do_mousescroll(int mode, cmdarg_T *cap) +{ + win_T *const old_curwin = curwin; + pos_T tpos = curwin->w_cursor; + + if (mouse_row >= 0 && mouse_col >= 0) { + int grid = mouse_grid; + int row = mouse_row; + int col = mouse_col; // find the window at the pointer coordinates win_T *wp = mouse_find_win(&grid, &row, &col); @@ -1480,18 +1491,45 @@ void nv_mousescroll(cmdarg_T *cap) curbuf = curwin->w_buffer; } - if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) { - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { - (void)onepage(cap->arg ? FORWARD : BACKWARD, 1); - } else if (p_mousescroll_vert > 0) { - cap->count1 = (int)p_mousescroll_vert; - cap->count0 = (int)p_mousescroll_vert; - nv_scroll_line(cap); + if (mode == MODE_INSERT && curwin == old_curwin) { + undisplay_dollar(); + } + + // For Insert mode, don't scroll the window in which completion is being done. + if (mode == MODE_NORMAL || !pum_visible() || curwin != old_curwin) { + if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) { + if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { + if (mode == MODE_INSERT) { + int step = curwin->w_botline - curwin->w_topline; + scroll_redraw(cap->arg, step); + } else { + (void)onepage(cap->arg ? FORWARD : BACKWARD, 1); + } + } else if (p_mousescroll_vert > 0) { + if (mode == MODE_INSERT) { + scroll_redraw(cap->arg, (linenr_T)p_mousescroll_vert); + } else { + cap->count1 = (int)p_mousescroll_vert; + cap->count0 = (int)p_mousescroll_vert; + nv_scroll_line(cap); + } + } + } else { + int step = (int)p_mousescroll_hor; + if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { + step = curwin->w_width_inner; + } + + colnr_T leftcol = curwin->w_leftcol + (cap->arg == MSCR_RIGHT ? -step : +step); + if (leftcol < 0) { + leftcol = 0; + } + + (void)do_mousescroll_horiz(leftcol); } - } else { - mouse_scroll_horiz(cap->arg); } - if (curwin != old_curwin && curwin->w_p_cul) { + + if (mode == MODE_NORMAL && curwin != old_curwin && curwin->w_p_cul) { redraw_for_cursorline(curwin); } @@ -1499,6 +1537,18 @@ void nv_mousescroll(cmdarg_T *cap) curwin = old_curwin; curbuf = curwin->w_buffer; + + if (mode == MODE_INSERT) { + if (!equalpos(curwin->w_cursor, tpos)) { + start_arrow(&tpos); + set_can_cindent(true); + } + } +} + +void nv_mousescroll(cmdarg_T *cap) +{ + do_mousescroll(MODE_NORMAL, cap); } /// Mouse clicks and drags. @@ -1724,9 +1774,7 @@ static colnr_T scroll_line_len(linenr_T lnum) return col; } -/// /// Find longest visible line number. -/// static linenr_T find_longest_lnum(void) { linenr_T ret = 0; @@ -1761,39 +1809,6 @@ static linenr_T find_longest_lnum(void) return ret; } -/// Do a horizontal scroll. -/// @return true if the cursor moved, false otherwise. -bool mouse_scroll_horiz(int dir) -{ - if (curwin->w_p_wrap) { - return false; - } - - int step = (int)p_mousescroll_hor; - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { - step = curwin->w_width_inner; - } - - int leftcol = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : +step); - if (leftcol < 0) { - leftcol = 0; - } - - if (curwin->w_leftcol == leftcol) { - return false; - } - - // When the line of the cursor is too short, move the cursor to the - // longest visible line. - if (!virtual_active() - && (colnr_T)leftcol > scroll_line_len(curwin->w_cursor.lnum)) { - curwin->w_cursor.lnum = find_longest_lnum(); - curwin->w_cursor.col = 0; - } - - return set_leftcol(leftcol); -} - /// Check clicked cell on its grid static void mouse_check_grid(colnr_T *vcolp, int *flagsp) FUNC_ATTR_NONNULL_ALL -- cgit From 1f9878a2e2205cede1b7e261de34272129362eb4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 21 Aug 2023 21:13:48 +0800 Subject: vim-patch:9.0.0902: some mouse scroll code is not in a good place Problem: Some mouse scroll code is not in a good place. Solution: Refactor the code. (Christopher Plewright, closes vim/vim#11561) https://github.com/vim/vim/commit/696d0a86250636602d42e29e57d8923f538e0549 Co-authored-by: Christopher Plewright --- src/nvim/mouse.c | 115 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 61 insertions(+), 54 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index f9177ac355..18a5adf7e7 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -993,18 +993,17 @@ void ins_mouse(int c) redraw_statuslines(); } -/// Implementation for scrolling in direction "dir", which is one of the MSCR_ -/// values. +/// Implementation for scrolling in Insert mode in direction "dir", which is one +/// of the MSCR_ values. void ins_mousescroll(int dir) { cmdarg_T cap; - CLEAR_FIELD(cap); - oparg_T oa; + CLEAR_FIELD(cap); clear_oparg(&oa); cap.oap = &oa; - cap.arg = dir; + switch (dir) { case MSCR_UP: cap.cmdchar = K_MOUSEUP; @@ -1021,7 +1020,37 @@ void ins_mousescroll(int dir) default: siemsg("Invalid ins_mousescroll() argument: %d", dir); } - do_mousescroll(MODE_INSERT, &cap); + + win_T *wp = curwin; + if (mouse_row >= 0 && mouse_col >= 0) { + // Find the window at the mouse pointer coordinates. + int grid = mouse_grid; + int row = mouse_row; + int col = mouse_col; + wp = mouse_find_win(&grid, &row, &col); + if (wp == NULL) { + return; + } + } + + if (wp == curwin) { + // Don't scroll the current window if the popup menu is visible. + if (pum_visible()) { + return; + } + + undisplay_dollar(); + } + + pos_T orig_cursor = curwin->w_cursor; + + // The scrolling works almost the same way as in Normal mode. + nv_mousescroll(&cap); + + if (!equalpos(curwin->w_cursor, orig_cursor)) { + start_arrow(&orig_cursor); + set_can_cindent(true); + } } /// Return true if "c" is a mouse key. @@ -1472,64 +1501,54 @@ static bool do_mousescroll_horiz(colnr_T leftcol) /// K_MOUSEDOWN - MSCR_DOWN /// K_MOUSELEFT - MSCR_LEFT /// K_MOUSERIGHT - MSCR_RIGHT -void do_mousescroll(int mode, cmdarg_T *cap) +void nv_mousescroll(cmdarg_T *cap) { win_T *const old_curwin = curwin; - pos_T tpos = curwin->w_cursor; if (mouse_row >= 0 && mouse_col >= 0) { + // Find the window at the mouse pointer coordinates. int grid = mouse_grid; int row = mouse_row; int col = mouse_col; - - // find the window at the pointer coordinates win_T *wp = mouse_find_win(&grid, &row, &col); if (wp == NULL) { return; } + // NOTE: Must restore "curwin" to "old_curwin" before returning! curwin = wp; curbuf = curwin->w_buffer; } - if (mode == MODE_INSERT && curwin == old_curwin) { - undisplay_dollar(); - } + bool shift_or_ctrl = mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL); - // For Insert mode, don't scroll the window in which completion is being done. - if (mode == MODE_NORMAL || !pum_visible() || curwin != old_curwin) { - if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) { - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { - if (mode == MODE_INSERT) { - int step = curwin->w_botline - curwin->w_topline; - scroll_redraw(cap->arg, step); - } else { - (void)onepage(cap->arg ? FORWARD : BACKWARD, 1); - } - } else if (p_mousescroll_vert > 0) { - if (mode == MODE_INSERT) { - scroll_redraw(cap->arg, (linenr_T)p_mousescroll_vert); - } else { - cap->count1 = (int)p_mousescroll_vert; - cap->count0 = (int)p_mousescroll_vert; - nv_scroll_line(cap); - } - } + if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) { + // Vertical scrolling + if (!(State & MODE_INSERT) && shift_or_ctrl) { + // whole page up or down + (void)onepage(cap->arg ? FORWARD : BACKWARD, 1); } else { - int step = (int)p_mousescroll_hor; - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { - step = curwin->w_width_inner; + if (shift_or_ctrl) { + // whole page up or down + cap->count1 = curwin->w_botline - curwin->w_topline; + } else { + cap->count1 = (int)p_mousescroll_vert; } - - colnr_T leftcol = curwin->w_leftcol + (cap->arg == MSCR_RIGHT ? -step : +step); - if (leftcol < 0) { - leftcol = 0; + if (cap->count1 > 0) { + cap->count0 = cap->count1; + nv_scroll_line(cap); } - - (void)do_mousescroll_horiz(leftcol); } + } else { + // Horizontal scrolling + int step = shift_or_ctrl ? curwin->w_width_inner : (int)p_mousescroll_hor; + colnr_T leftcol = curwin->w_leftcol + (cap->arg == MSCR_RIGHT ? -step : +step); + if (leftcol < 0) { + leftcol = 0; + } + (void)do_mousescroll_horiz(leftcol); } - if (mode == MODE_NORMAL && curwin != old_curwin && curwin->w_p_cul) { + if (curwin != old_curwin && curwin->w_p_cul) { redraw_for_cursorline(curwin); } @@ -1537,18 +1556,6 @@ void do_mousescroll(int mode, cmdarg_T *cap) curwin = old_curwin; curbuf = curwin->w_buffer; - - if (mode == MODE_INSERT) { - if (!equalpos(curwin->w_cursor, tpos)) { - start_arrow(&tpos); - set_can_cindent(true); - } - } -} - -void nv_mousescroll(cmdarg_T *cap) -{ - do_mousescroll(MODE_NORMAL, cap); } /// Mouse clicks and drags. -- cgit From 042678a7b4ee85dca85586b0c0e223dcaf6c2116 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 21 Aug 2023 21:30:33 +0800 Subject: vim-patch:9.0.0906: mouse scroll code is not optimal Problem: Mouse scroll code is not optimal. Solution: Properly organise Normal mode, Insert mode and common code. (Christopher Plewright, closes vim/vim#11572) https://github.com/vim/vim/commit/ff95ce0930e6db0037fe8d1fc875a6522b054582 Co-authored-by: Christopher Plewright --- src/nvim/mouse.c | 110 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 63 insertions(+), 47 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 18a5adf7e7..176aff849e 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -993,6 +993,48 @@ void ins_mouse(int c) redraw_statuslines(); } +/// Common mouse wheel scrolling, shared between Insert mode and NV modes. +/// Default action is to scroll mouse_vert_step lines (or mouse_hor_step columns +/// depending on the scroll direction) or one page when Shift or Ctrl is used. +/// Direction is indicated by "cap->arg": +/// K_MOUSEUP - MSCR_UP +/// K_MOUSEDOWN - MSCR_DOWN +/// K_MOUSELEFT - MSCR_LEFT +/// K_MOUSERIGHT - MSCR_RIGHT +/// "curwin" may have been changed to the window that should be scrolled and +/// differ from the window that actually has focus. +static void do_mousescroll(cmdarg_T *cap) +{ + bool shift_or_ctrl = mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL); + + if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) { + // Vertical scrolling + if (!(State & MODE_INSERT) && shift_or_ctrl) { + // whole page up or down + (void)onepage(cap->arg ? FORWARD : BACKWARD, 1); + } else { + if (shift_or_ctrl) { + // whole page up or down + cap->count1 = curwin->w_botline - curwin->w_topline; + } else { + cap->count1 = (int)p_mousescroll_vert; + } + if (cap->count1 > 0) { + cap->count0 = cap->count1; + nv_scroll_line(cap); + } + } + } else { + // Horizontal scrolling + int step = shift_or_ctrl ? curwin->w_width_inner : (int)p_mousescroll_hor; + colnr_T leftcol = curwin->w_leftcol + (cap->arg == MSCR_RIGHT ? -step : +step); + if (leftcol < 0) { + leftcol = 0; + } + (void)do_mousescroll_horiz(leftcol); + } +} + /// Implementation for scrolling in Insert mode in direction "dir", which is one /// of the MSCR_ values. void ins_mousescroll(int dir) @@ -1021,19 +1063,22 @@ void ins_mousescroll(int dir) siemsg("Invalid ins_mousescroll() argument: %d", dir); } - win_T *wp = curwin; + win_T *old_curwin = curwin; if (mouse_row >= 0 && mouse_col >= 0) { // Find the window at the mouse pointer coordinates. + // NOTE: Must restore "curwin" to "old_curwin" before returning! int grid = mouse_grid; int row = mouse_row; int col = mouse_col; - wp = mouse_find_win(&grid, &row, &col); - if (wp == NULL) { + curwin = mouse_find_win(&grid, &row, &col); + if (curwin == NULL) { + curwin = old_curwin; return; } + curbuf = curwin->w_buffer; } - if (wp == curwin) { + if (curwin == old_curwin) { // Don't scroll the current window if the popup menu is visible. if (pum_visible()) { return; @@ -1044,8 +1089,12 @@ void ins_mousescroll(int dir) pos_T orig_cursor = curwin->w_cursor; - // The scrolling works almost the same way as in Normal mode. - nv_mousescroll(&cap); + // Call the common mouse scroll function shared with other modes. + do_mousescroll(&cap); + + curwin->w_redr_status = true; + curwin = old_curwin; + curbuf = curwin->w_buffer; if (!equalpos(curwin->w_cursor, orig_cursor)) { start_arrow(&orig_cursor); @@ -1494,66 +1543,33 @@ static bool do_mousescroll_horiz(colnr_T leftcol) return set_leftcol(leftcol); } -/// Mouse scroll wheel: Default action is to scroll p_mousescroll_vert lines, -/// or p_mousescroll_hor, or one page when Shift or Ctrl is used. -/// Direction is indicated by "cap->arg": -/// K_MOUSEUP - MSCR_UP -/// K_MOUSEDOWN - MSCR_DOWN -/// K_MOUSELEFT - MSCR_LEFT -/// K_MOUSERIGHT - MSCR_RIGHT +/// Normal and Visual modes implementation for scrolling in direction +/// "cap->arg", which is one of the MSCR_ values. void nv_mousescroll(cmdarg_T *cap) { win_T *const old_curwin = curwin; if (mouse_row >= 0 && mouse_col >= 0) { // Find the window at the mouse pointer coordinates. + // NOTE: Must restore "curwin" to "old_curwin" before returning! int grid = mouse_grid; int row = mouse_row; int col = mouse_col; - win_T *wp = mouse_find_win(&grid, &row, &col); - if (wp == NULL) { + curwin = mouse_find_win(&grid, &row, &col); + if (curwin == NULL) { + curwin = old_curwin; return; } - // NOTE: Must restore "curwin" to "old_curwin" before returning! - curwin = wp; curbuf = curwin->w_buffer; } - bool shift_or_ctrl = mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL); - - if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) { - // Vertical scrolling - if (!(State & MODE_INSERT) && shift_or_ctrl) { - // whole page up or down - (void)onepage(cap->arg ? FORWARD : BACKWARD, 1); - } else { - if (shift_or_ctrl) { - // whole page up or down - cap->count1 = curwin->w_botline - curwin->w_topline; - } else { - cap->count1 = (int)p_mousescroll_vert; - } - if (cap->count1 > 0) { - cap->count0 = cap->count1; - nv_scroll_line(cap); - } - } - } else { - // Horizontal scrolling - int step = shift_or_ctrl ? curwin->w_width_inner : (int)p_mousescroll_hor; - colnr_T leftcol = curwin->w_leftcol + (cap->arg == MSCR_RIGHT ? -step : +step); - if (leftcol < 0) { - leftcol = 0; - } - (void)do_mousescroll_horiz(leftcol); - } + // Call the common mouse scroll function shared with other modes. + do_mousescroll(cap); if (curwin != old_curwin && curwin->w_p_cul) { redraw_for_cursorline(curwin); } - curwin->w_redr_status = true; - curwin = old_curwin; curbuf = curwin->w_buffer; } -- cgit From d401b33314a4178b23443c78119055c3d34a407e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 21 Aug 2023 23:19:12 +0800 Subject: fix(terminal): handle horizontal scrolling in another window (#24828) --- src/nvim/mouse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 176aff849e..0f77b5d568 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1003,13 +1003,13 @@ void ins_mouse(int c) /// K_MOUSERIGHT - MSCR_RIGHT /// "curwin" may have been changed to the window that should be scrolled and /// differ from the window that actually has focus. -static void do_mousescroll(cmdarg_T *cap) +void do_mousescroll(cmdarg_T *cap) { bool shift_or_ctrl = mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL); if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) { // Vertical scrolling - if (!(State & MODE_INSERT) && shift_or_ctrl) { + if ((State & MODE_NORMAL) && shift_or_ctrl) { // whole page up or down (void)onepage(cap->arg ? FORWARD : BACKWARD, 1); } else { -- cgit From cefd774fac76b91f5368833555818c80c992c3b1 Mon Sep 17 00:00:00 2001 From: bfredl Date: Thu, 24 Aug 2023 15:14:23 +0200 Subject: refactor(memline): distinguish mutating uses of ml_get_buf() ml_get_buf() takes a third parameters to indicate whether the caller wants to mutate the memline data in place. However the vast majority of the call sites is using this function just to specify a buffer but without any mutation. This makes it harder to grep for the places which actually perform mutation. Solution: Remove the bool param from ml_get_buf(). it now works like ml_get() except for a non-current buffer. Add a new ml_get_buf_mut() function for the mutating use-case, which can be grepped along with the other ml_replace() etc functions which can modify the memline. --- src/nvim/mouse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 0f77b5d568..76ac191a68 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1750,7 +1750,7 @@ colnr_T vcol2col(win_T *const wp, const linenr_T lnum, const colnr_T vcol) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { // try to advance to the specified column - char *line = ml_get_buf(wp->w_buffer, lnum, false); + char *line = ml_get_buf(wp->w_buffer, lnum); chartabsize_T cts; init_chartabsize_arg(&cts, wp, lnum, 0, line, line); while (cts.cts_vcol < vcol && *cts.cts_ptr != NUL) { -- cgit From 2b475cb5cc2196a32085fbbdfd7357cbb02a1cb0 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 11 Sep 2023 08:29:33 +0800 Subject: fix(mouse): click on 'statuscolumn' with 'rightleft' (#25090) --- src/nvim/mouse.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 76ac191a68..b8c80cadf5 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -220,7 +220,10 @@ static int get_fpos_of_mouse(pos_T *mpos) // compute the position in the buffer line from the posn on the screen bool below_buffer = mouse_comp_pos(wp, &row, &col, &mpos->lnum); - if (!below_buffer && *wp->w_p_stc != NUL && mouse_col < win_col_off(wp)) { + if (!below_buffer && *wp->w_p_stc != NUL + && (wp->w_p_rl + ? wincol >= wp->w_width_inner - win_col_off(wp) + : wincol < win_col_off(wp))) { return MOUSE_STATUSCOL; } @@ -675,6 +678,10 @@ popupexit: click_col = mouse_col; } + if (in_statuscol && wp->w_p_rl) { + click_col = wp->w_width_inner - click_col - 1; + } + if (click_defs != NULL) { switch (click_defs[click_col].type) { case kStlClickDisabled: @@ -1254,7 +1261,10 @@ retnomove: on_sep_line = grid == DEFAULT_GRID_HANDLE && col >= wp->w_width && col - wp->w_width + 1 == 1; on_winbar = row == -1 && wp->w_winbar_height != 0; on_statuscol = !below_window && !on_status_line && !on_sep_line && !on_winbar - && *wp->w_p_stc != NUL && col < win_col_off(wp); + && *wp->w_p_stc != NUL + && (wp->w_p_rl + ? col >= wp->w_width_inner - win_col_off(wp) + : col < win_col_off(wp)); // The rightmost character of the status line might be a vertical // separator character if there is no connecting window to the right. -- cgit From 8da986ea877b07a5eb117446f410f2a7fc8cd9cb Mon Sep 17 00:00:00 2001 From: bfredl Date: Wed, 13 Sep 2023 13:39:18 +0200 Subject: refactor(grid): change schar_T representation to be more compact Previously, a screen cell would occupy 28+4=32 bytes per cell as we always made space for up to MAX_MCO+1 codepoints in a cell. As an example, even a pretty modest 50*80 screen would consume 50*80*2*32 = 256000, i e a quarter megabyte With the factor of two due to the TUI side buffer, and even more when using msg_grid and/or ext_multigrid. This instead stores a 4-byte union of either: - a valid UTF-8 sequence up to 4 bytes - an escape char which is invalid UTF-8 (0xFF) plus a 24-bit index to a glyph cache This avoids allocating space for huge composed glyphs _upfront_, while still keeping rendering such glyphs reasonably fast (1 hash table lookup + one plain index lookup). If the same large glyphs are using repeatedly on the screen, this is still a net reduction of memory/cache consumption. The only case which really gets worse is if you blast the screen full with crazy emojis and zalgo text and even this case only leads to 4 extra bytes per char. When only <= 4-byte glyphs are used, plus the 4-byte attribute code, i e 8 bytes in total there is a factor of four reduction of memory use. Memory which will be quite hot in cache as the screen buffer is scanned over in win_line() buffer text drawing A slight complication is that the representation depends on host byte order. I've tested this manually by compling and running this in qemu-s390x and it works fine. We might add a qemu based solution to CI at some point. --- src/nvim/mouse.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index b8c80cadf5..e35385dd43 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1849,7 +1849,6 @@ static void mouse_check_grid(colnr_T *vcolp, int *flagsp) int click_grid = mouse_grid; int click_row = mouse_row; int click_col = mouse_col; - int mouse_char = ' '; int max_row = Rows; int max_col = Columns; bool multigrid = ui_has(kUIMultigrid); @@ -1864,7 +1863,6 @@ static void mouse_check_grid(colnr_T *vcolp, int *flagsp) if (wp && mouse_row >= 0 && mouse_row < max_row && mouse_col >= 0 && mouse_col < max_col) { ScreenGrid *gp = multigrid ? &wp->w_grid_alloc : &default_grid; - int fdc = win_fdccol_count(wp); int use_row = multigrid && mouse_grid == 0 ? click_row : mouse_row; int use_col = multigrid && mouse_grid == 0 ? click_col : mouse_col; @@ -1901,22 +1899,12 @@ static void mouse_check_grid(colnr_T *vcolp, int *flagsp) // concealed characters. *vcolp = col_from_screen; } - - // Remember the character under the mouse, might be one of foldclose or - // foldopen fillchars in the fold column. - mouse_char = utf_ptr2char((char *)gp->chars[off]); - } - - // Check for position outside of the fold column. - if (wp->w_p_rl ? click_col < wp->w_width_inner - fdc : - click_col >= fdc + (cmdwin_type == 0 ? 0 : 1)) { - mouse_char = ' '; } } - if (wp && mouse_char == wp->w_p_fcs_chars.foldclosed) { + if (col_from_screen == -2) { *flagsp |= MOUSE_FOLD_OPEN; - } else if (mouse_char != ' ') { + } else if (col_from_screen == -3) { *flagsp |= MOUSE_FOLD_CLOSE; } } -- cgit From adb73772d9197a7fa6e9ee7a2e8874118e60844d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 21 Sep 2023 08:00:03 +0800 Subject: vim-patch:9.0.1919: Wrong curswant when clicking on empty line or with vsplits Problem: Wrong curswant when clicking on empty line or with vsplits. Solution: Don't check for ScreenCols[] before the start of the window and handle empty line properly. closes: vim/vim#13132 https://github.com/vim/vim/commit/03cd697d635f1b0e7ffe21cf8244a8fb755f2ddb --- src/nvim/mouse.c | 83 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 42 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index e35385dd43..c4a31e0783 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1849,56 +1849,55 @@ static void mouse_check_grid(colnr_T *vcolp, int *flagsp) int click_grid = mouse_grid; int click_row = mouse_row; int click_col = mouse_col; - int max_row = Rows; - int max_col = Columns; - bool multigrid = ui_has(kUIMultigrid); - colnr_T col_from_screen = -1; + // XXX: this doesn't change click_grid if it is 1, even with multigrid win_T *wp = mouse_find_win(&click_grid, &click_row, &click_col); - if (wp && multigrid) { - max_row = wp->w_grid_alloc.rows; - max_col = wp->w_grid_alloc.cols; + // Only use vcols[] after the window was redrawn. Mainly matters + // for tests, a user would not click before redrawing. + if (wp == NULL || wp->w_redr_type != 0) { + return; } + ScreenGrid *gp = &wp->w_grid; + int start_row = 0; + int start_col = 0; + grid_adjust(&gp, &start_row, &start_col); + if (gp->handle != click_grid) { + return; + } + click_row += start_row; + click_col += start_col; - if (wp && mouse_row >= 0 && mouse_row < max_row - && mouse_col >= 0 && mouse_col < max_col) { - ScreenGrid *gp = multigrid ? &wp->w_grid_alloc : &default_grid; - int use_row = multigrid && mouse_grid == 0 ? click_row : mouse_row; - int use_col = multigrid && mouse_grid == 0 ? click_col : mouse_col; - - if (gp->chars != NULL) { - const size_t off = gp->line_offset[use_row] + (size_t)use_col; - - // Only use vcols[] after the window was redrawn. Mainly matters - // for tests, a user would not click before redrawing. - if (wp->w_redr_type == 0) { - col_from_screen = gp->vcols[off]; - } + colnr_T col_from_screen = -1; - if (col_from_screen == MAXCOL) { - // When clicking after end of line, still need to set correct curswant - size_t off_l = gp->line_offset[use_row]; - if (gp->vcols[off_l] < MAXCOL) { - // Binary search to find last char in line - size_t off_r = off; - while (off_l < off_r) { - size_t off_m = (off_l + off_r + 1) / 2; - if (gp->vcols[off_m] < MAXCOL) { - off_l = off_m; - } else { - off_r = off_m - 1; - } + if (gp->chars != NULL + && click_row >= 0 && click_row < gp->rows + && click_col >= 0 && click_col < gp->cols) { + const size_t off = gp->line_offset[click_row] + (size_t)click_col; + col_from_screen = gp->vcols[off]; + + if (col_from_screen == MAXCOL) { + // When clicking after end of line, still need to set correct curswant + size_t off_l = gp->line_offset[click_row] + (size_t)start_col; + if (gp->vcols[off_l] < MAXCOL) { + // Binary search to find last char in line + size_t off_r = off; + while (off_l < off_r) { + size_t off_m = (off_l + off_r + 1) / 2; + if (gp->vcols[off_m] < MAXCOL) { + off_l = off_m; + } else { + off_r = off_m - 1; } - *vcolp = gp->vcols[off_r] + (int)(off - off_r); - } else { - // Shouldn't normally happen - *vcolp = MAXCOL; } - } else if (col_from_screen >= 0) { - // Use the virtual column from vcols[], it is accurate also after - // concealed characters. - *vcolp = col_from_screen; + *vcolp = gp->vcols[off_r] + (int)(off - off_r); + } else { + // Clicking on an empty line + *vcolp = click_col - start_col; } + } else if (col_from_screen >= 0) { + // Use the virtual column from vcols[], it is accurate also after + // concealed characters. + *vcolp = col_from_screen; } } -- cgit From e25cf47ad3e10e0e1ae2b2376d898382af5b1e26 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 21 Sep 2023 10:20:30 +0800 Subject: fix(mouse): click on empty line with 'foldcolumn' --- src/nvim/mouse.c | 61 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 29 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index c4a31e0783..33d7bc2e51 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1861,44 +1861,47 @@ static void mouse_check_grid(colnr_T *vcolp, int *flagsp) int start_row = 0; int start_col = 0; grid_adjust(&gp, &start_row, &start_col); - if (gp->handle != click_grid) { + if (gp->handle != click_grid || gp->chars == NULL) { return; } click_row += start_row; click_col += start_col; + if (click_row < 0 || click_row >= gp->rows + || click_col < 0 || click_col >= gp->cols) { + return; + } - colnr_T col_from_screen = -1; + const size_t off = gp->line_offset[click_row] + (size_t)click_col; + colnr_T col_from_screen = gp->vcols[off]; - if (gp->chars != NULL - && click_row >= 0 && click_row < gp->rows - && click_col >= 0 && click_col < gp->cols) { - const size_t off = gp->line_offset[click_row] + (size_t)click_col; - col_from_screen = gp->vcols[off]; - - if (col_from_screen == MAXCOL) { - // When clicking after end of line, still need to set correct curswant - size_t off_l = gp->line_offset[click_row] + (size_t)start_col; - if (gp->vcols[off_l] < MAXCOL) { - // Binary search to find last char in line - size_t off_r = off; - while (off_l < off_r) { - size_t off_m = (off_l + off_r + 1) / 2; - if (gp->vcols[off_m] < MAXCOL) { - off_l = off_m; - } else { - off_r = off_m - 1; - } + if (col_from_screen == MAXCOL) { + // When clicking after end of line, still need to set correct curswant + size_t off_l = gp->line_offset[click_row] + (size_t)start_col; + if (gp->vcols[off_l] < MAXCOL) { + // Binary search to find last char in line + size_t off_r = off; + while (off_l < off_r) { + size_t off_m = (off_l + off_r + 1) / 2; + if (gp->vcols[off_m] < MAXCOL) { + off_l = off_m; + } else { + off_r = off_m - 1; } - *vcolp = gp->vcols[off_r] + (int)(off - off_r); - } else { - // Clicking on an empty line - *vcolp = click_col - start_col; } - } else if (col_from_screen >= 0) { - // Use the virtual column from vcols[], it is accurate also after - // concealed characters. - *vcolp = col_from_screen; + colnr_T eol_vcol = gp->vcols[off_r]; + assert(eol_vcol < MAXCOL); + // This may be -2 or -3 with 'foldcolumn' and empty line. + // In that case set it to -1 as it's just before start of line. + eol_vcol = MAX(eol_vcol, -1); + *vcolp = eol_vcol + (int)(off - off_r); + } else { + // Clicking on an empty line + *vcolp = click_col - start_col; } + } else if (col_from_screen >= 0) { + // Use the virtual column from vcols[], it is accurate also after + // concealed characters. + *vcolp = col_from_screen; } if (col_from_screen == -2) { -- cgit From 6555176f34f102a8878a0bac55fd80459c943aa2 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 22 Sep 2023 05:44:45 +0800 Subject: vim-patch:9.0.1923: curswant wrong on click with 've' and 'nowrap' set (#25293) Problem: curswant wrong on click with 've' and 'nowrap' set Solution: Add w_leftcol to mouse click column. closes: vim/vim#13142 https://github.com/vim/vim/commit/db54e989b5cff3cc6442dfc500e3962cc1c0b6d0 --- src/nvim/mouse.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 33d7bc2e51..9b09a3fdf3 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1890,13 +1890,15 @@ static void mouse_check_grid(colnr_T *vcolp, int *flagsp) } colnr_T eol_vcol = gp->vcols[off_r]; assert(eol_vcol < MAXCOL); - // This may be -2 or -3 with 'foldcolumn' and empty line. - // In that case set it to -1 as it's just before start of line. - eol_vcol = MAX(eol_vcol, -1); + if (eol_vcol < 0) { + // Empty line or whole line before w_leftcol, + // with columns before buffer text + eol_vcol = wp->w_leftcol - 1; + } *vcolp = eol_vcol + (int)(off - off_r); } else { - // Clicking on an empty line - *vcolp = click_col - start_col; + // Empty line or whole line before w_leftcol + *vcolp = click_col - start_col + wp->w_leftcol; } } else if (col_from_screen >= 0) { // Use the virtual column from vcols[], it is accurate also after -- cgit From cf8b2c0e74fd5e723b0c15c2ce84e6900fd322d3 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 30 Sep 2023 12:05:28 +0800 Subject: build(iwyu): add a few more _defs.h mappings (#25435) --- src/nvim/mouse.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 9b09a3fdf3..20605c52c5 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -16,7 +16,6 @@ #include "nvim/edit.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" -#include "nvim/eval/typval_defs.h" #include "nvim/ex_docmd.h" #include "nvim/fold.h" #include "nvim/getchar.h" @@ -41,7 +40,6 @@ #include "nvim/state.h" #include "nvim/statusline.h" #include "nvim/strings.h" -#include "nvim/syntax.h" #include "nvim/types.h" #include "nvim/ui.h" #include "nvim/ui_compositor.h" -- cgit From dc6d0d2daf69e2fdadda81feb97906dbc962a239 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 30 Sep 2023 14:41:34 +0800 Subject: refactor: reorganize option header files (#25437) - Move vimoption_T to option.h - option_defs.h is for option-related types - option_vars.h corresponds to Vim's option.h - option_defs.h and option_vars.h don't include each other --- src/nvim/mouse.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 20605c52c5..0433031393 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -33,6 +33,7 @@ #include "nvim/normal.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/option_vars.h" #include "nvim/plines.h" #include "nvim/popupmenu.h" #include "nvim/pos.h" -- cgit From bcda800933f6de09392c3c91e290077952989722 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 14 Oct 2023 19:18:25 +0800 Subject: vim-patch:9.0.2022: getmousepos() returns wrong index for TAB char (#25636) Problem: When clicking in the middle of a TAB, getmousepos() returns the column of the next char instead of the TAB. Solution: Break out of the loop when the vcol to find is inside current char. Fix invalid memory access when calling virtcol2col() on an empty line. closes: vim/vim#13321 https://github.com/vim/vim/commit/b583eda7031b1f6a3469a2537d0c10ca5fa5568e --- src/nvim/mouse.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 0433031393..75c399bcad 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1754,7 +1754,7 @@ static win_T *mouse_find_grid_win(int *gridp, int *rowp, int *colp) } /// Convert a virtual (screen) column to a character column. -/// The first column is one. +/// The first column is zero. colnr_T vcol2col(win_T *const wp, const linenr_T lnum, const colnr_T vcol) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { @@ -1763,7 +1763,11 @@ colnr_T vcol2col(win_T *const wp, const linenr_T lnum, const colnr_T vcol) chartabsize_T cts; init_chartabsize_arg(&cts, wp, lnum, 0, line, line); while (cts.cts_vcol < vcol && *cts.cts_ptr != NUL) { - cts.cts_vcol += win_lbr_chartabsize(&cts, NULL); + int size = win_lbr_chartabsize(&cts, NULL); + if (cts.cts_vcol + size > vcol) { + break; + } + cts.cts_vcol += size; MB_PTR_ADV(cts.cts_ptr); } clear_chartabsize_arg(&cts); -- cgit From d974a3dcbb3757ebeb78fa64054c795ab7acdf1a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 15 Oct 2023 17:19:01 +0800 Subject: vim-patch:9.0.2032: cannot get mouse click pos for tab or virt text (#25653) Problem: Cannot accurately get mouse clicking position when clicking on a TAB or with virtual text. Solution: Add a "coladd" field to getmousepos() result. closes: vim/vim#13335 https://github.com/vim/vim/commit/f5a94d5165bb9e390797da50a1fa7a87df3fbee4 --- src/nvim/mouse.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 75c399bcad..a76e4b7e53 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -243,9 +243,7 @@ static int get_fpos_of_mouse(pos_T *mpos) return IN_UNKNOWN; } - mpos->col = vcol2col(wp, mpos->lnum, col); - - mpos->coladd = 0; + mpos->col = vcol2col(wp, mpos->lnum, col, &mpos->coladd); return IN_BUFFER; } @@ -1755,8 +1753,8 @@ static win_T *mouse_find_grid_win(int *gridp, int *rowp, int *colp) /// Convert a virtual (screen) column to a character column. /// The first column is zero. -colnr_T vcol2col(win_T *const wp, const linenr_T lnum, const colnr_T vcol) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +colnr_T vcol2col(win_T *wp, linenr_T lnum, colnr_T vcol, colnr_T *coladdp) + FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT { // try to advance to the specified column char *line = ml_get_buf(wp->w_buffer, lnum); @@ -1772,6 +1770,9 @@ colnr_T vcol2col(win_T *const wp, const linenr_T lnum, const colnr_T vcol) } clear_chartabsize_arg(&cts); + if (coladdp != NULL) { + *coladdp = vcol - cts.cts_vcol; + } return (colnr_T)(cts.cts_ptr - line); } @@ -1927,6 +1928,7 @@ void f_getmousepos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) varnumber_T wincol = 0; linenr_T lnum = 0; varnumber_T column = 0; + colnr_T coladd = 0; tv_dict_alloc_ret(rettv); dict_T *d = rettv->vval.v_dict; @@ -1945,7 +1947,7 @@ void f_getmousepos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) wincol = col + 1 + wp->w_wincol_off; // Adjust by 1 for left border if (row >= 0 && row < wp->w_height && col >= 0 && col < wp->w_width) { (void)mouse_comp_pos(wp, &row, &col, &lnum); - col = vcol2col(wp, lnum, col); + col = vcol2col(wp, lnum, col, &coladd); column = col + 1; } } @@ -1955,4 +1957,5 @@ void f_getmousepos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) tv_dict_add_nr(d, S_LEN("wincol"), wincol); tv_dict_add_nr(d, S_LEN("line"), (varnumber_T)lnum); tv_dict_add_nr(d, S_LEN("column"), column); + tv_dict_add_nr(d, S_LEN("coladd"), coladd); } -- cgit From acc646ad8fc3ef11fcc63b69f3d8484e4a91accd Mon Sep 17 00:00:00 2001 From: dundargoc Date: Fri, 29 Sep 2023 14:58:48 +0200 Subject: refactor: the long goodbye long is 32 bits on windows, while it is 64 bits on other architectures. This makes the type suboptimal for a codebase meant to be cross-platform. Replace it with more appropriate integer types. --- src/nvim/mouse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index a76e4b7e53..a9914c439b 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -452,7 +452,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent) if ((State & REPLACE_FLAG) && !yank_register_mline(regname)) { insert_reg(regname, true); } else { - do_put(regname, NULL, BACKWARD, 1L, + do_put(regname, NULL, BACKWARD, 1, (fixindent ? PUT_FIXINDENT : 0) | PUT_CURSEND); // Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r @@ -710,9 +710,9 @@ popupexit: && which_button == MOUSE_LEFT) { // open or close a fold at this line if (jump_flags & MOUSE_FOLD_OPEN) { - openFold(curwin->w_cursor, 1L); + openFold(curwin->w_cursor, 1); } else { - closeFold(curwin->w_cursor, 1L); + closeFold(curwin->w_cursor, 1); } // don't move the cursor if still in the same window if (curwin == old_curwin) { @@ -733,7 +733,7 @@ popupexit: // When dragging the mouse above the window, scroll down. if (is_drag && mouse_row < 0 && !in_status_line) { - scroll_redraw(false, 1L); + scroll_redraw(false, 1); mouse_row = 0; } -- cgit From 353a4be7e84fdc101318215bdcc8a7e780d737fe Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sun, 12 Nov 2023 13:13:58 +0100 Subject: build: remove PVS We already have an extensive suite of static analysis tools we use, which causes a fair bit of redundancy as we get duplicate warnings. PVS is also prone to give false warnings which creates a lot of work to identify and disable. --- src/nvim/mouse.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index a9914c439b..141910f9df 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1,6 +1,3 @@ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - #include #include #include -- cgit From ac1113ded5f8f09dd99a9894d7a7e795626fb728 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 13 Nov 2023 23:40:37 +0100 Subject: refactor: follow style guide - reduce variable scope - prefer initialization over declaration and assignment --- src/nvim/mouse.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 141910f9df..8a48a8928e 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -100,15 +100,12 @@ static void find_start_of_word(pos_T *pos) /// When 'selection' is "exclusive", the position is just after the word. static void find_end_of_word(pos_T *pos) { - char *line; - int cclass; - - line = ml_get(pos->lnum); + char *line = ml_get(pos->lnum); if (*p_sel == 'e' && pos->col > 0) { pos->col--; pos->col -= utf_head_off(line, line + pos->col); } - cclass = get_mouse_class(line + pos->col); + int cclass = get_mouse_class(line + pos->col); while (line[pos->col] != NUL) { int col = pos->col + utfc_ptr2len(line + pos->col); if (get_mouse_class(line + col) != cclass) { @@ -964,11 +961,10 @@ popupexit: void ins_mouse(int c) { - pos_T tpos; win_T *old_curwin = curwin; undisplay_dollar(); - tpos = curwin->w_cursor; + pos_T tpos = curwin->w_cursor; if (do_mouse(NULL, c, BACKWARD, 1, 0)) { win_T *new_curwin = curwin; @@ -1183,8 +1179,6 @@ int jump_to_mouse(int flags, bool *inclusive, int which_button) static int prev_col = -1; static int did_drag = false; // drag was noticed - win_T *wp, *old_curwin; - pos_T old_cursor; int count; bool first; int row = mouse_row; @@ -1237,15 +1231,15 @@ retnomove: if (flags & MOUSE_SETPOS) { goto retnomove; // ugly goto... } - old_curwin = curwin; - old_cursor = curwin->w_cursor; + win_T *old_curwin = curwin; + pos_T old_cursor = curwin->w_cursor; if (row < 0 || col < 0) { // check if it makes sense return IN_UNKNOWN; } // find the window where the row is in - wp = mouse_find_win(&grid, &row, &col); + win_T *wp = mouse_find_win(&grid, &row, &col); if (wp == NULL) { return IN_UNKNOWN; } -- cgit From a8a93e517f9eb988ee86170d9a77382637dd24a3 Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Fri, 24 Nov 2023 02:15:50 +0100 Subject: fix(mouse): avoid dragging after click label popupmenu callback (#26187) --- src/nvim/mouse.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 8a48a8928e..368153cad6 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -241,6 +241,14 @@ static int get_fpos_of_mouse(pos_T *mpos) return IN_BUFFER; } +static bool mouse_got_click = false; ///< got a click some time back + +/// Reset the flag that a mouse click was seen. +void reset_mouse_got_click(void) +{ + mouse_got_click = false; +} + /// Do the appropriate action for the current mouse click in the current mode. /// Not used for Command-line mode. /// @@ -282,8 +290,6 @@ static int get_fpos_of_mouse(pos_T *mpos) /// @return true if start_arrow() should be called for edit mode. bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent) { - static bool got_click = false; // got a click some time back - int which_button; // MOUSE_LEFT, _MIDDLE or _RIGHT bool is_click; // If false it's a drag or release event bool is_drag; // If true it's a drag event @@ -341,13 +347,13 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent) // Ignore drag and release events if we didn't get a click. if (is_click) { - got_click = true; + mouse_got_click = true; } else { - if (!got_click) { // didn't get click, ignore + if (!mouse_got_click) { // didn't get click, ignore return false; } if (!is_drag) { // release, reset got_click - got_click = false; + mouse_got_click = false; if (in_tab_line) { in_tab_line = false; return false; @@ -364,7 +370,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent) stuffnumReadbuff(count); } stuffcharReadbuff(Ctrl_T); - got_click = false; // ignore drag&release now + mouse_got_click = false; // ignore drag&release now return false; } @@ -588,7 +594,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent) ui_flush(); // Update before showing popup menu } show_popupmenu(); - got_click = false; // ignore release events + mouse_got_click = false; // ignore release events return (jump_flags & CURSOR_MOVED) != 0; } if (which_button == MOUSE_LEFT @@ -628,7 +634,7 @@ popupexit: // If an operator is pending, ignore all drags and releases until the next mouse click. if (!is_drag && oap != NULL && oap->op_type != OP_NOP) { - got_click = false; + mouse_got_click = false; oap->motion_type = kMTCharWise; } @@ -838,7 +844,7 @@ popupexit: } else { // location list window do_cmdline_cmd(".ll"); } - got_click = false; // ignore drag&release now + mouse_got_click = false; // ignore drag&release now } else if ((mod_mask & MOD_MASK_CTRL) || (curbuf->b_help && (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)) { // Ctrl-Mouse click (or double click in a help window) jumps to the tag @@ -847,7 +853,7 @@ popupexit: stuffcharReadbuff(Ctrl_O); } stuffcharReadbuff(Ctrl_RSB); - got_click = false; // ignore drag&release now + mouse_got_click = false; // ignore drag&release now } else if ((mod_mask & MOD_MASK_SHIFT)) { // Shift-Mouse click searches for the next occurrence of the word under // the mouse pointer -- cgit From 6a2a37b1e102394d99b4891dc9807868f0fa3c97 Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Sat, 25 Nov 2023 00:10:19 +0100 Subject: fix(mouse): avoid dragging when clicking next to popupmenu (#26201) --- src/nvim/mouse.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 368153cad6..0b4cd5dd14 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -132,6 +132,8 @@ static void move_tab_to_mouse(void) } } +static bool got_click = false; // got a click some time back + /// Call click definition function for column "col" in the "click_defs" array for button /// "which_button". static void call_click_def_func(StlClickDefinition *click_defs, int col, int which_button) @@ -187,6 +189,8 @@ static void call_click_def_func(StlClickDefinition *click_defs, int col, int whi typval_T rettv; (void)call_vim_function(click_defs[col].func, ARRAY_SIZE(argv), argv, &rettv); tv_clear(&rettv); + // Make sure next click does not register as drag when callback absorbs the release event. + got_click = false; } /// Translate window coordinates to buffer position without any side effects. @@ -241,14 +245,6 @@ static int get_fpos_of_mouse(pos_T *mpos) return IN_BUFFER; } -static bool mouse_got_click = false; ///< got a click some time back - -/// Reset the flag that a mouse click was seen. -void reset_mouse_got_click(void) -{ - mouse_got_click = false; -} - /// Do the appropriate action for the current mouse click in the current mode. /// Not used for Command-line mode. /// @@ -347,13 +343,13 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent) // Ignore drag and release events if we didn't get a click. if (is_click) { - mouse_got_click = true; + got_click = true; } else { - if (!mouse_got_click) { // didn't get click, ignore + if (!got_click) { // didn't get click, ignore return false; } if (!is_drag) { // release, reset got_click - mouse_got_click = false; + got_click = false; if (in_tab_line) { in_tab_line = false; return false; @@ -370,7 +366,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent) stuffnumReadbuff(count); } stuffcharReadbuff(Ctrl_T); - mouse_got_click = false; // ignore drag&release now + got_click = false; // ignore drag&release now return false; } @@ -594,7 +590,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent) ui_flush(); // Update before showing popup menu } show_popupmenu(); - mouse_got_click = false; // ignore release events + got_click = false; // ignore release events return (jump_flags & CURSOR_MOVED) != 0; } if (which_button == MOUSE_LEFT @@ -634,7 +630,7 @@ popupexit: // If an operator is pending, ignore all drags and releases until the next mouse click. if (!is_drag && oap != NULL && oap->op_type != OP_NOP) { - mouse_got_click = false; + got_click = false; oap->motion_type = kMTCharWise; } @@ -844,7 +840,7 @@ popupexit: } else { // location list window do_cmdline_cmd(".ll"); } - mouse_got_click = false; // ignore drag&release now + got_click = false; // ignore drag&release now } else if ((mod_mask & MOD_MASK_CTRL) || (curbuf->b_help && (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)) { // Ctrl-Mouse click (or double click in a help window) jumps to the tag @@ -853,7 +849,7 @@ popupexit: stuffcharReadbuff(Ctrl_O); } stuffcharReadbuff(Ctrl_RSB); - mouse_got_click = false; // ignore drag&release now + got_click = false; // ignore drag&release now } else if ((mod_mask & MOD_MASK_SHIFT)) { // Shift-Mouse click searches for the next occurrence of the word under // the mouse pointer -- cgit From 8b428ca8b79ebb7b36c3e403ff3bcb6924a635a6 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 16:00:21 +0100 Subject: build(IWYU): fix includes for func_attr.h --- src/nvim/mouse.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 0b4cd5dd14..2c7438df48 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -15,6 +15,7 @@ #include "nvim/eval/typval.h" #include "nvim/ex_docmd.h" #include "nvim/fold.h" +#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/globals.h" #include "nvim/grid.h" -- cgit From f4aedbae4cb1f206f5b7c6142697b71dd473059b Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 18:39:38 +0100 Subject: build(IWYU): fix includes for undo_defs.h --- src/nvim/mouse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 2c7438df48..babd4e353e 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -34,7 +34,7 @@ #include "nvim/option_vars.h" #include "nvim/plines.h" #include "nvim/popupmenu.h" -#include "nvim/pos.h" +#include "nvim/pos_defs.h" #include "nvim/search.h" #include "nvim/state.h" #include "nvim/statusline.h" -- cgit From 6c14ae6bfaf51415b555e9a6b85d1d280976358d Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 20:27:32 +0100 Subject: refactor: rename types.h to types_defs.h --- src/nvim/mouse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index babd4e353e..b3cbe371ed 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -39,7 +39,7 @@ #include "nvim/state.h" #include "nvim/statusline.h" #include "nvim/strings.h" -#include "nvim/types.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/ui_compositor.h" #include "nvim/vim.h" -- cgit From 79b6ff28ad1204fbb4199b9092f5c578d88cb28e Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 28 Nov 2023 20:31:00 +0100 Subject: refactor: fix headers with IWYU --- src/nvim/mouse.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index b3cbe371ed..b07163d1f8 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -4,7 +4,7 @@ #include #include -#include "nvim/ascii.h" +#include "nvim/ascii_defs.h" #include "nvim/buffer.h" #include "nvim/buffer_defs.h" #include "nvim/charset.h" @@ -20,7 +20,7 @@ #include "nvim/globals.h" #include "nvim/grid.h" #include "nvim/keycodes.h" -#include "nvim/macros.h" +#include "nvim/macros_defs.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" @@ -42,7 +42,7 @@ #include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/ui_compositor.h" -#include "nvim/vim.h" +#include "nvim/vim_defs.h" #include "nvim/window.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -- cgit From 86cc791debba09c8ed1aa0d863be844108866a38 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 29 Nov 2023 23:10:21 +0800 Subject: refactor: move function macros out of vim_defs.h (#26300) --- src/nvim/mouse.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/mouse.c') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index b07163d1f8..8fe3864424 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -24,6 +24,7 @@ #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" +#include "nvim/memory.h" #include "nvim/menu.h" #include "nvim/message.h" #include "nvim/mouse.h" -- cgit