diff options
Diffstat (limited to 'src/nvim/mouse.c')
-rw-r--r-- | src/nvim/mouse.c | 215 |
1 files changed, 115 insertions, 100 deletions
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 4c0339e5f4..cf463fd40a 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -3,25 +3,26 @@ #include <stdbool.h> -#include "nvim/mouse.h" -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/window.h" +#include "nvim/buffer_defs.h" +#include "nvim/charset.h" +#include "nvim/cursor.h" +#include "nvim/diff.h" +#include "nvim/fold.h" +#include "nvim/memline.h" +#include "nvim/misc1.h" +#include "nvim/mouse.h" +#include "nvim/move.h" +#include "nvim/os_unix.h" +#include "nvim/plines.h" +#include "nvim/screen.h" #include "nvim/state.h" #include "nvim/strings.h" -#include "nvim/screen.h" #include "nvim/syntax.h" #include "nvim/ui.h" #include "nvim/ui_compositor.h" -#include "nvim/os_unix.h" -#include "nvim/fold.h" -#include "nvim/diff.h" -#include "nvim/move.h" -#include "nvim/misc1.h" -#include "nvim/cursor.h" -#include "nvim/buffer_defs.h" -#include "nvim/memline.h" -#include "nvim/charset.h" +#include "nvim/vim.h" +#include "nvim/window.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "mouse.c.generated.h" @@ -30,33 +31,34 @@ static linenr_T orig_topline = 0; static int orig_topfill = 0; -// Move the cursor to the specified row and column on the screen. -// Change current window if necessary. Returns an integer with the -// CURSOR_MOVED bit set if the cursor has moved or unset otherwise. -// -// The MOUSE_FOLD_CLOSE bit is set when clicked on the '-' in a fold column. -// The MOUSE_FOLD_OPEN bit is set when clicked on the '+' in a fold column. -// -// If flags has MOUSE_FOCUS, then the current window will not be changed, and -// if the mouse is outside the window then the text will scroll, or if the -// mouse was previously on a status line, then the status line may be dragged. -// -// If flags has MOUSE_MAY_VIS, then VIsual mode will be started before the -// cursor is moved unless the cursor was on a status line. -// This function returns one of IN_UNKNOWN, IN_BUFFER, IN_STATUS_LINE or -// IN_SEP_LINE depending on where the cursor was clicked. -// -// If flags has MOUSE_MAY_STOP_VIS, then Visual mode will be stopped, unless -// the mouse is on the status line of the same window. -// -// If flags has MOUSE_DID_MOVE, nothing is done if the mouse didn't move since -// the last call. -// -// If flags has MOUSE_SETPOS, nothing is done, only the current position is -// remembered. -int jump_to_mouse(int flags, - bool *inclusive, // used for inclusive operator, can be NULL - int which_button) // MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE +/// Move the cursor to the specified row and column on the screen. +/// Change current window if necessary. Returns an integer with the +/// CURSOR_MOVED bit set if the cursor has moved or unset otherwise. +/// +/// The MOUSE_FOLD_CLOSE bit is set when clicked on the '-' in a fold column. +/// The MOUSE_FOLD_OPEN bit is set when clicked on the '+' in a fold column. +/// +/// If flags has MOUSE_FOCUS, then the current window will not be changed, and +/// if the mouse is outside the window then the text will scroll, or if the +/// mouse was previously on a status line, then the status line may be dragged. +/// +/// If flags has MOUSE_MAY_VIS, then VIsual mode will be started before the +/// cursor is moved unless the cursor was on a status line. +/// This function returns one of IN_UNKNOWN, IN_BUFFER, IN_STATUS_LINE or +/// IN_SEP_LINE depending on where the cursor was clicked. +/// +/// If flags has MOUSE_MAY_STOP_VIS, then Visual mode will be stopped, unless +/// the mouse is on the status line of the same window. +/// +/// If flags has MOUSE_DID_MOVE, nothing is done if the mouse didn't move since +/// the last call. +/// +/// If flags has MOUSE_SETPOS, nothing is done, only the current position is +/// remembered. +/// +/// @param inclusive used for inclusive operator, can be NULL +/// @param which_button MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE +int jump_to_mouse(int flags, bool *inclusive, int which_button) { static int on_status_line = 0; // #lines below bottom of window static int on_sep_line = 0; // on separator right of window @@ -65,7 +67,7 @@ int jump_to_mouse(int flags, static win_T *dragwin = NULL; // window being dragged static int did_drag = false; // drag was noticed - win_T *wp, *old_curwin; + win_T *wp, *old_curwin; pos_T old_cursor; int count; bool first; @@ -80,8 +82,9 @@ int jump_to_mouse(int flags, if (flags & MOUSE_RELEASED) { // On button release we may change window focus if positioned on a // status line and no dragging happened. - if (dragwin != NULL && !did_drag) + if (dragwin != NULL && !did_drag) { flags &= ~(MOUSE_FOCUS | MOUSE_DID_MOVE); + } dragwin = NULL; did_drag = false; } @@ -108,15 +111,16 @@ retnomove: prev_row = mouse_row; prev_col = mouse_col; - if (flags & MOUSE_SETPOS) + if (flags & MOUSE_SETPOS) { goto retnomove; // ugly goto... - + } old_curwin = curwin; old_cursor = curwin->w_cursor; if (!(flags & MOUSE_FOCUS)) { - if (row < 0 || col < 0) // check if it makes sense + 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); @@ -150,10 +154,11 @@ retnomove: // The rightmost character of the status line might be a vertical // separator character if there is no connecting window to the right. if (on_status_line && on_sep_line) { - if (stl_connected(wp)) + if (stl_connected(wp)) { on_sep_line = 0; - else + } else { on_status_line = 0; + } } // Before jumping to another buffer, or moving the cursor for a left @@ -180,28 +185,32 @@ retnomove: // Only change window focus when not clicking on or dragging the // status line. Do change focus when releasing the mouse button // (MOUSE_FOCUS was set above if we dragged first). - if (dragwin == NULL || (flags & MOUSE_RELEASED)) + if (dragwin == NULL || (flags & MOUSE_RELEASED)) { win_enter(wp, true); // can make wp invalid! + } // set topline, to be able to check for double click ourselves - if (curwin != old_curwin) + if (curwin != old_curwin) { set_mouse_topline(curwin); + } if (on_status_line) { // In (or below) status line // Don't use start_arrow() if we're in the same window - if (curwin == old_curwin) + if (curwin == old_curwin) { return IN_STATUS_LINE; - else + } else { return IN_STATUS_LINE | CURSOR_MOVED; + } } if (on_sep_line) { // In (or below) status line // Don't use start_arrow() if we're in the same window - if (curwin == old_curwin) + if (curwin == old_curwin) { return IN_SEP_LINE; - else + } else { return IN_SEP_LINE | CURSOR_MOVED; + } } curwin->w_cursor.lnum = curwin->w_topline; - } else if (on_status_line && which_button == MOUSE_LEFT) { + } else if (on_status_line && which_button == MOUSE_LEFT) { if (dragwin != NULL) { // Drag the status line count = row - dragwin->w_winrow - dragwin->w_height + 1 @@ -210,7 +219,7 @@ retnomove: did_drag |= count; } return IN_STATUS_LINE; // Cursor didn't move - } else if (on_sep_line && which_button == MOUSE_LEFT) { + } else if (on_sep_line && which_button == MOUSE_LEFT) { if (dragwin != NULL) { // Drag the separator column count = col - dragwin->w_wincol - dragwin->w_width + 1 @@ -227,25 +236,23 @@ retnomove: redraw_curbuf_later(INVERTED); // delete the inversion } - - row -= curwin->w_winrow; - col -= curwin->w_wincol; - // When clicking beyond the end of the window, scroll the screen. // Scroll by however many rows outside the window we are. if (row < 0) { count = 0; for (first = true; curwin->w_topline > 1; ) { - if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) - ++count; - else - count += plines(curwin->w_topline - 1); - if (!first && count > -row) + if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) { + count++; + } else { + count += plines_win(curwin, curwin->w_topline - 1, true); + } + if (!first && count > -row) { break; + } first = false; (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); - if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) { - ++curwin->w_topfill; + if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) { + curwin->w_topfill++; } else { --curwin->w_topline; curwin->w_topfill = 0; @@ -256,13 +263,13 @@ retnomove: ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); redraw_later(curwin, VALID); row = 0; - } else if (row >= curwin->w_height_inner) { + } else if (row >= curwin->w_height_inner) { count = 0; for (first = true; curwin->w_topline < curbuf->b_ml.ml_line_count; ) { if (curwin->w_topfill > 0) { ++count; } else { - count += plines(curwin->w_topline); + count += plines_win(curwin, curwin->w_topline, true); } if (!first && count > row - curwin->w_height_inner + 1) { @@ -276,11 +283,10 @@ retnomove: } if (curwin->w_topfill > 0) { - --curwin->w_topfill; + curwin->w_topfill--; } else { - ++curwin->w_topline; - curwin->w_topfill = - diff_check_fill(curwin, curwin->w_topline); + curwin->w_topline++; + curwin->w_topfill = win_get_fill(curwin, curwin->w_topline); } } check_topfill(curwin, false); @@ -288,7 +294,7 @@ retnomove: curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); row = curwin->w_height_inner - 1; - } else if (row == 0) { + } else if (row == 0) { // When dragging the mouse, while the text has been scrolled up as // far as it goes, moving the mouse in the top line should scroll // the text down (done later when recomputing w_topline). @@ -366,12 +372,12 @@ 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->w_p_diff + if (win_may_fill(win) && !hasFoldingWin(win, lnum, NULL, NULL, true, NULL)) { if (lnum == win->w_topline) { row -= win->w_topfill; } else { - row -= diff_check_fill(win, lnum); + row -= win_get_fill(win, lnum); } count = plines_win_nofill(win, lnum, true); } else { @@ -395,8 +401,9 @@ 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); - if (col < off) + if (col < off) { col = off; + } col += row * (win->w_width_inner - off); // add skip column (for long wrapping line) col += win->w_skipcol; @@ -432,23 +439,26 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp) } - frame_T *fp; + frame_T *fp; fp = topframe; *rowp -= firstwin->w_winrow; for (;; ) { - if (fp->fr_layout == FR_LEAF) + if (fp->fr_layout == FR_LEAF) { break; + } if (fp->fr_layout == FR_ROW) { for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next) { - if (*colp < fp->fr_width) + if (*colp < fp->fr_width) { break; + } *colp -= fp->fr_width; } } else { // fr_layout == FR_COL for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next) { - if (*rowp < fp->fr_height) + if (*rowp < fp->fr_height) { break; + } *rowp -= fp->fr_height; } } @@ -522,7 +532,7 @@ static colnr_T scroll_line_len(linenr_T lnum) char_u *line = ml_get(lnum); if (*line != NUL) { for (;;) { - int numchar = chartabsize(line, col); + int numchar = win_chartabsize(curwin, line, col); MB_PTR_ADV(line); if (*line == NUL) { // don't count the last character break; @@ -570,27 +580,26 @@ static linenr_T find_longest_lnum(void) return ret; } -/// -/// Do a horizontal scroll. Return TRUE if the cursor moved, FALSE otherwise. -/// +/// 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; + return false; } int step = 6; if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { - step = curwin->w_width_inner; + step = curwin->w_width_inner; } int leftcol = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : +step); if (leftcol < 0) { - leftcol = 0; + leftcol = 0; } if (curwin->w_leftcol == leftcol) { - return false; + return false; } curwin->w_leftcol = (colnr_T)leftcol; @@ -599,8 +608,8 @@ bool mouse_scroll_horiz(int dir) // 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; + curwin->w_cursor.lnum = find_longest_lnum(); + curwin->w_cursor.col = 0; } return leftcol_changed(); @@ -619,10 +628,10 @@ static int mouse_adjust_click(win_T *wp, int row, int col) // scanned *up to* `col`, nudging it left or right when concealed characters // are encountered. // - // 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. + // 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; char_u *line = ml_get(lnum); @@ -646,7 +655,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) // checked for concealed characters. vcol = 0; while (vcol < offset && *ptr != NUL) { - vcol += chartabsize(ptr, vcol); + vcol += win_chartabsize(curwin, ptr, vcol); ptr += utfc_ptr2len(ptr); } @@ -657,7 +666,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) vcol = offset; ptr_end = ptr_row_offset; while (vcol < col && *ptr_end != NUL) { - vcol += chartabsize(ptr_end, vcol); + vcol += win_chartabsize(curwin, ptr_end, vcol); ptr_end += utfc_ptr2len(ptr_end); } @@ -672,7 +681,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) #define decr() nudge--; ptr_end -= utfc_ptr2len(ptr_end) while (ptr < ptr_end && *ptr != NUL) { - cwidth = chartabsize(ptr, vcol); + cwidth = win_chartabsize(curwin, ptr, vcol); vcol += cwidth; if (cwidth > 1 && *ptr == '\t' && nudge > 0) { // A tab will "absorb" any previous adjustments. @@ -721,14 +730,20 @@ int mouse_check_fold(void) int click_row = mouse_row; int click_col = mouse_col; int mouse_char = ' '; + int max_row = Rows; + int max_col = Columns; + int multigrid = ui_has(kUIMultigrid); win_T *wp; 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.Columns; + } - if (wp && mouse_row >= 0 && mouse_row < Rows - && mouse_col >= 0 && mouse_col <= Columns) { - int multigrid = ui_has(kUIMultigrid); + 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 row = multigrid && mouse_grid == 0 ? click_row : mouse_row; |