aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/mouse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/mouse.c')
-rw-r--r--src/nvim/mouse.c215
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;