Merge pull request #24826 from zeertzjq/vim-9.0.0886

vim-patch:9.0.{0886,0902,.0906}: mouse scrolling refactors
This commit is contained in:
zeertzjq
2023-08-21 22:06:03 +08:00
committed by GitHub

View File

@@ -993,46 +993,111 @@ 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)
{
win_T *const old_curwin = curwin;
pos_T tpos = curwin->w_cursor;
cmdarg_T 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;
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);
}
win_T *old_curwin = curwin;
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) {
// 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;
curwin = mouse_find_win(&grid, &row, &col);
if (curwin == NULL) {
curwin = old_curwin;
return;
}
curwin = wp;
curbuf = curwin->w_buffer;
}
if (curwin == old_curwin) {
// Don't scroll the current window if the popup menu is visible.
if (pum_visible()) {
return;
}
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);
}
}
pos_T orig_cursor = curwin->w_cursor;
// 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, tpos)) {
start_arrow(&tpos);
if (!equalpos(curwin->w_cursor, orig_cursor)) {
start_arrow(&orig_cursor);
set_can_cindent(true);
}
}
@@ -1456,47 +1521,55 @@ 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)
/// Make a horizontal scroll to "leftcol".
/// @return true if the cursor moved, false otherwise.
static bool do_mousescroll_horiz(colnr_T leftcol)
{
if (curwin->w_p_wrap) {
return false; // no horizontal scrolling when wrapping
}
if (curwin->w_leftcol == leftcol) {
return false; // already there
}
// 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;
}
return set_leftcol(leftcol);
}
/// 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 *old_curwin = curwin;
win_T *const 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) {
// 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;
curwin = mouse_find_win(&grid, &row, &col);
if (curwin == NULL) {
curwin = old_curwin;
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);
}
// 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;
}
@@ -1724,9 +1797,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 +1832,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