mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
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 #11448)
This commit is contained in:
parent
b53a190e9f
commit
44c2209352
@ -4499,7 +4499,7 @@ ins_horscroll(void)
|
|||||||
|
|
||||||
undisplay_dollar();
|
undisplay_dollar();
|
||||||
tpos = curwin->w_cursor;
|
tpos = curwin->w_cursor;
|
||||||
if (gui_do_horiz_scroll(scrollbar_value, FALSE))
|
if (do_mousescroll_horiz(scrollbar_value))
|
||||||
{
|
{
|
||||||
start_arrow(&tpos);
|
start_arrow(&tpos);
|
||||||
can_cindent = TRUE;
|
can_cindent = TRUE;
|
||||||
|
@ -2221,7 +2221,7 @@ getcmdline_int(
|
|||||||
case K_HOR_SCROLLBAR:
|
case K_HOR_SCROLLBAR:
|
||||||
if (msg_scrolled == 0)
|
if (msg_scrolled == 0)
|
||||||
{
|
{
|
||||||
gui_do_horiz_scroll(scrollbar_value, FALSE);
|
do_mousescroll_horiz(scrollbar_value);
|
||||||
redrawcmd();
|
redrawcmd();
|
||||||
}
|
}
|
||||||
goto cmdline_not_changed;
|
goto cmdline_not_changed;
|
||||||
|
123
src/gui.c
123
src/gui.c
@ -4105,14 +4105,14 @@ gui_drag_scrollbar(scrollbar_T *sb, long value, int still_dragging)
|
|||||||
scrollbar_value = value;
|
scrollbar_value = value;
|
||||||
|
|
||||||
if (State & MODE_NORMAL)
|
if (State & MODE_NORMAL)
|
||||||
gui_do_horiz_scroll(scrollbar_value, FALSE);
|
do_mousescroll_horiz(scrollbar_value);
|
||||||
else if (State & MODE_INSERT)
|
else if (State & MODE_INSERT)
|
||||||
ins_horscroll();
|
ins_horscroll();
|
||||||
else if (State & MODE_CMDLINE)
|
else if (State & MODE_CMDLINE)
|
||||||
{
|
{
|
||||||
if (msg_scrolled == 0)
|
if (msg_scrolled == 0)
|
||||||
{
|
{
|
||||||
gui_do_horiz_scroll(scrollbar_value, FALSE);
|
do_mousescroll_horiz(scrollbar_value);
|
||||||
redrawcmdline();
|
redrawcmdline();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4504,88 +4504,13 @@ gui_do_scroll(void)
|
|||||||
return (wp == curwin && !EQUAL_POS(curwin->w_cursor, old_cursor));
|
return (wp == curwin && !EQUAL_POS(curwin->w_cursor, old_cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Horizontal scrollbar stuff:
|
* Horizontal scrollbar stuff:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Return length of line "lnum" for horizontal scrolling.
|
|
||||||
*/
|
|
||||||
static colnr_T
|
|
||||||
scroll_line_len(linenr_T lnum)
|
|
||||||
{
|
|
||||||
char_u *p;
|
|
||||||
colnr_T col;
|
|
||||||
int w;
|
|
||||||
|
|
||||||
p = ml_get(lnum);
|
|
||||||
col = 0;
|
|
||||||
if (*p != NUL)
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
w = chartabsize(p, col);
|
|
||||||
MB_PTR_ADV(p);
|
|
||||||
if (*p == NUL) // don't count the last character
|
|
||||||
break;
|
|
||||||
col += w;
|
|
||||||
}
|
|
||||||
return col;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember which line is currently the longest, so that we don't have to
|
|
||||||
// search for it when scrolling horizontally.
|
|
||||||
static linenr_T longest_lnum = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find longest visible line number. If this is not possible (or not desired,
|
|
||||||
* by setting 'h' in "guioptions") then the current line number is returned.
|
|
||||||
*/
|
|
||||||
static linenr_T
|
|
||||||
gui_find_longest_lnum(void)
|
|
||||||
{
|
|
||||||
linenr_T ret = 0;
|
|
||||||
|
|
||||||
// Calculate maximum for horizontal scrollbar. Check for reasonable
|
|
||||||
// line numbers, topline and botline can be invalid when displaying is
|
|
||||||
// postponed.
|
|
||||||
if (vim_strchr(p_go, GO_HORSCROLL) == NULL
|
|
||||||
&& curwin->w_topline <= curwin->w_cursor.lnum
|
|
||||||
&& curwin->w_botline > curwin->w_cursor.lnum
|
|
||||||
&& curwin->w_botline <= curbuf->b_ml.ml_line_count + 1)
|
|
||||||
{
|
|
||||||
linenr_T lnum;
|
|
||||||
colnr_T n;
|
|
||||||
long 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 (lnum = curwin->w_topline; lnum < curwin->w_botline; ++lnum)
|
|
||||||
{
|
|
||||||
n = scroll_line_len(lnum);
|
|
||||||
if (n > (colnr_T)max)
|
|
||||||
{
|
|
||||||
max = n;
|
|
||||||
ret = lnum;
|
|
||||||
}
|
|
||||||
else if (n == (colnr_T)max
|
|
||||||
&& abs((int)(lnum - curwin->w_cursor.lnum))
|
|
||||||
< abs((int)(ret - curwin->w_cursor.lnum)))
|
|
||||||
ret = lnum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// Use cursor line only.
|
|
||||||
ret = curwin->w_cursor.lnum;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gui_update_horiz_scrollbar(int force)
|
gui_update_horiz_scrollbar(int force)
|
||||||
{
|
{
|
||||||
long value, size, max; // need 32 bit ints here
|
long value, size, max;
|
||||||
|
|
||||||
if (!gui.which_scrollbars[SBAR_BOTTOM])
|
if (!gui.which_scrollbars[SBAR_BOTTOM])
|
||||||
return;
|
return;
|
||||||
@ -4619,9 +4544,7 @@ gui_update_horiz_scrollbar(int force)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
value = curwin->w_leftcol;
|
value = curwin->w_leftcol;
|
||||||
|
max = scroll_line_len(ui_find_longest_lnum());
|
||||||
longest_lnum = gui_find_longest_lnum();
|
|
||||||
max = scroll_line_len(longest_lnum);
|
|
||||||
|
|
||||||
if (virtual_active())
|
if (virtual_active())
|
||||||
{
|
{
|
||||||
@ -4669,44 +4592,6 @@ gui_update_horiz_scrollbar(int force)
|
|||||||
gui_mch_set_scrollbar_thumb(&gui.bottom_sbar, value, size, max);
|
gui_mch_set_scrollbar_thumb(&gui.bottom_sbar, value, size, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Do a horizontal scroll. Return TRUE if the cursor moved, FALSE otherwise.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
gui_do_horiz_scroll(long_u leftcol, int compute_longest_lnum)
|
|
||||||
{
|
|
||||||
// no wrapping, no scrolling
|
|
||||||
if (curwin->w_p_wrap)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (curwin->w_leftcol == (colnr_T)leftcol)
|
|
||||||
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 (vim_strchr(p_go, GO_HORSCROLL) == NULL
|
|
||||||
&& !virtual_active()
|
|
||||||
&& (colnr_T)leftcol > scroll_line_len(curwin->w_cursor.lnum))
|
|
||||||
{
|
|
||||||
if (compute_longest_lnum)
|
|
||||||
{
|
|
||||||
curwin->w_cursor.lnum = gui_find_longest_lnum();
|
|
||||||
curwin->w_cursor.col = 0;
|
|
||||||
}
|
|
||||||
// Do a sanity check on "longest_lnum", just in case.
|
|
||||||
else if (longest_lnum >= curwin->w_topline
|
|
||||||
&& longest_lnum < curwin->w_botline)
|
|
||||||
{
|
|
||||||
curwin->w_cursor.lnum = longest_lnum;
|
|
||||||
curwin->w_cursor.col = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return leftcol_changed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that none of the colors are the same as the background color
|
* Check that none of the colors are the same as the background color
|
||||||
*/
|
*/
|
||||||
|
276
src/mouse.c
276
src/mouse.c
@ -1101,89 +1101,39 @@ ins_mouse(int c)
|
|||||||
redraw_statuslines();
|
redraw_statuslines();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implementation for scrolling in direction "dir", which is one of the MSCR_
|
||||||
|
* values.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
ins_mousescroll(int dir)
|
ins_mousescroll(int dir)
|
||||||
{
|
{
|
||||||
pos_T tpos;
|
cmdarg_T cap;
|
||||||
win_T *old_curwin = curwin, *wp;
|
CLEAR_FIELD(cap);
|
||||||
int did_scroll = FALSE;
|
|
||||||
|
|
||||||
tpos = curwin->w_cursor;
|
oparg_T oa;
|
||||||
|
clear_oparg(&oa);
|
||||||
|
cap.oap = &oa;
|
||||||
|
|
||||||
if (mouse_row >= 0 && mouse_col >= 0)
|
cap.arg = dir;
|
||||||
|
switch (dir)
|
||||||
{
|
{
|
||||||
int row, col;
|
case MSCR_UP:
|
||||||
|
cap.cmdchar = K_MOUSEUP;
|
||||||
row = mouse_row;
|
break;
|
||||||
col = mouse_col;
|
case MSCR_DOWN:
|
||||||
|
cap.cmdchar = K_MOUSEDOWN;
|
||||||
// find the window at the pointer coordinates
|
break;
|
||||||
wp = mouse_find_win(&row, &col, FIND_POPUP);
|
case MSCR_LEFT:
|
||||||
if (wp == NULL)
|
cap.cmdchar = K_MOUSELEFT;
|
||||||
return;
|
break;
|
||||||
curwin = wp;
|
case MSCR_RIGHT:
|
||||||
curbuf = curwin->w_buffer;
|
cap.cmdchar = K_MOUSERIGHT;
|
||||||
}
|
break;
|
||||||
if (curwin == old_curwin)
|
default:
|
||||||
undisplay_dollar();
|
siemsg("Invalid ins_mousescroll() argument: %d", dir);
|
||||||
|
|
||||||
// Don't scroll the window in which completion is being done.
|
|
||||||
if (!pum_visible() || curwin != old_curwin)
|
|
||||||
{
|
|
||||||
long step;
|
|
||||||
|
|
||||||
if (dir == MSCR_DOWN || dir == MSCR_UP)
|
|
||||||
{
|
|
||||||
if (mouse_vert_step < 0
|
|
||||||
|| mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
|
|
||||||
step = (long)(curwin->w_botline - curwin->w_topline);
|
|
||||||
else
|
|
||||||
step = mouse_vert_step;
|
|
||||||
scroll_redraw(dir, step);
|
|
||||||
# ifdef FEAT_PROP_POPUP
|
|
||||||
if (WIN_IS_POPUP(curwin))
|
|
||||||
popup_set_firstline(curwin);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
#ifdef FEAT_GUI
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int val;
|
|
||||||
|
|
||||||
if (mouse_hor_step < 0
|
|
||||||
|| mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
|
|
||||||
step = curwin->w_width;
|
|
||||||
else
|
|
||||||
step = mouse_hor_step;
|
|
||||||
val = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : step);
|
|
||||||
if (val < 0)
|
|
||||||
val = 0;
|
|
||||||
gui_do_horiz_scroll(val, TRUE);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
did_scroll = TRUE;
|
|
||||||
may_trigger_winscrolled();
|
|
||||||
}
|
|
||||||
|
|
||||||
curwin->w_redr_status = TRUE;
|
|
||||||
|
|
||||||
curwin = old_curwin;
|
|
||||||
curbuf = curwin->w_buffer;
|
|
||||||
|
|
||||||
// The popup menu may overlay the window, need to redraw it.
|
|
||||||
// TODO: Would be more efficient to only redraw the windows that are
|
|
||||||
// overlapped by the popup menu.
|
|
||||||
if (pum_visible() && did_scroll)
|
|
||||||
{
|
|
||||||
redraw_all_later(UPD_NOT_VALID);
|
|
||||||
ins_compl_show_pum();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!EQUAL_POS(curwin->w_cursor, tpos))
|
|
||||||
{
|
|
||||||
start_arrow(&tpos);
|
|
||||||
set_can_cindent(TRUE);
|
|
||||||
}
|
}
|
||||||
|
do_mousescroll(MODE_INSERT, &cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2072,17 +2022,53 @@ retnomove:
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make a horizontal scroll to "leftcol".
|
||||||
|
* Return TRUE if the cursor moved, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
do_mousescroll_horiz(long_u leftcol)
|
||||||
|
{
|
||||||
|
if (curwin->w_p_wrap)
|
||||||
|
return FALSE; // no wrapping, no scrolling
|
||||||
|
|
||||||
|
if (curwin->w_leftcol == (colnr_T)leftcol)
|
||||||
|
return FALSE; // already there
|
||||||
|
|
||||||
|
curwin->w_leftcol = (colnr_T)leftcol;
|
||||||
|
|
||||||
|
// When the line of the cursor is too short, move the cursor to the
|
||||||
|
// longest visible line.
|
||||||
|
if (
|
||||||
|
#ifdef FEAT_GUI
|
||||||
|
(!gui.in_use || vim_strchr(p_go, GO_HORSCROLL) == NULL) &&
|
||||||
|
#endif
|
||||||
|
!virtual_active()
|
||||||
|
&& (long)leftcol > scroll_line_len(curwin->w_cursor.lnum))
|
||||||
|
{
|
||||||
|
curwin->w_cursor.lnum = ui_find_longest_lnum();
|
||||||
|
curwin->w_cursor.col = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return leftcol_changed();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mouse scroll wheel: Default action is to scroll mouse_vert_step lines (or
|
* Mouse scroll wheel: Default action is to scroll mouse_vert_step lines (or
|
||||||
* mouse_hor_step, depending on the scroll direction), or one page when Shift or
|
* mouse_hor_step, depending on the scroll direction), or one page when Shift
|
||||||
* Ctrl is used.
|
* or Ctrl is used.
|
||||||
* K_MOUSEUP (cap->arg == 1) or K_MOUSEDOWN (cap->arg == 0) or
|
* Direction is indicated by "cap->arg":
|
||||||
* K_MOUSELEFT (cap->arg == -1) or K_MOUSERIGHT (cap->arg == -2)
|
* K_MOUSEUP - MSCR_UP
|
||||||
|
* K_MOUSEDOWN - MSCR_DOWN
|
||||||
|
* K_MOUSELEFT - MSCR_LEFT
|
||||||
|
* K_MOUSERIGHT - MSCR_RIGHT
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
nv_mousescroll(cmdarg_T *cap)
|
do_mousescroll(int mode, cmdarg_T *cap)
|
||||||
{
|
{
|
||||||
win_T *old_curwin = curwin, *wp;
|
win_T *old_curwin = curwin, *wp;
|
||||||
|
int did_ins_scroll = FALSE;
|
||||||
|
pos_T tpos = curwin->w_cursor;
|
||||||
|
|
||||||
if (mouse_row >= 0 && mouse_col >= 0)
|
if (mouse_row >= 0 && mouse_col >= 0)
|
||||||
{
|
{
|
||||||
@ -2102,61 +2088,80 @@ nv_mousescroll(cmdarg_T *cap)
|
|||||||
curwin = wp;
|
curwin = wp;
|
||||||
curbuf = curwin->w_buffer;
|
curbuf = curwin->w_buffer;
|
||||||
}
|
}
|
||||||
if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN)
|
if (mode == MODE_INSERT && curwin == old_curwin)
|
||||||
{
|
undisplay_dollar();
|
||||||
|
|
||||||
# ifdef FEAT_TERMINAL
|
# ifdef FEAT_TERMINAL
|
||||||
if (term_use_loop())
|
if (term_use_loop())
|
||||||
// This window is a terminal window, send the mouse event there.
|
// This window is a terminal window, send the mouse event there.
|
||||||
// Set "typed" to FALSE to avoid an endless loop.
|
// Set "typed" to FALSE to avoid an endless loop.
|
||||||
send_keys_to_term(curbuf->b_term, cap->cmdchar, mod_mask, FALSE);
|
send_keys_to_term(curbuf->b_term, cap->cmdchar, mod_mask, FALSE);
|
||||||
else
|
else
|
||||||
# endif
|
# endif
|
||||||
if (mouse_vert_step < 0 || 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)
|
||||||
{
|
{
|
||||||
(void)onepage(cap->arg ? FORWARD : BACKWARD, 1L);
|
if (mouse_vert_step < 0
|
||||||
}
|
|| mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
|
||||||
else
|
|
||||||
{
|
|
||||||
// Don't scroll more than half the window height.
|
|
||||||
if (curwin->w_height < mouse_vert_step * 2)
|
|
||||||
{
|
{
|
||||||
cap->count1 = curwin->w_height / 2;
|
if (mode == MODE_INSERT)
|
||||||
if (cap->count1 == 0)
|
{
|
||||||
cap->count1 = 1;
|
long step = (long)(curwin->w_botline - curwin->w_topline);
|
||||||
|
scroll_redraw(cap->arg, step);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
did_ins_scroll = onepage(cap->arg ? FORWARD : BACKWARD, 1L);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cap->count1 = mouse_vert_step;
|
{
|
||||||
cap->count0 = cap->count1;
|
if (mode == MODE_INSERT)
|
||||||
nv_scroll_line(cap);
|
{
|
||||||
}
|
scroll_redraw(cap->arg, mouse_vert_step);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Don't scroll more than half the window height.
|
||||||
|
if (curwin->w_height < mouse_vert_step * 2)
|
||||||
|
{
|
||||||
|
cap->count1 = curwin->w_height / 2;
|
||||||
|
if (cap->count1 == 0)
|
||||||
|
cap->count1 = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cap->count1 = mouse_vert_step;
|
||||||
|
}
|
||||||
|
cap->count0 = cap->count1;
|
||||||
|
nv_scroll_line(cap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef FEAT_PROP_POPUP
|
#ifdef FEAT_PROP_POPUP
|
||||||
if (WIN_IS_POPUP(curwin))
|
if (WIN_IS_POPUP(curwin))
|
||||||
popup_set_firstline(curwin);
|
popup_set_firstline(curwin);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
# ifdef FEAT_GUI
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
// Horizontal scroll - only allowed when 'wrap' is disabled
|
|
||||||
if (!curwin->w_p_wrap)
|
|
||||||
{
|
{
|
||||||
int val, step;
|
long step = (mouse_hor_step < 0
|
||||||
|
|| (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)))
|
||||||
|
? curwin->w_width : mouse_hor_step;
|
||||||
|
long leftcol = curwin->w_leftcol
|
||||||
|
+ (cap->arg == MSCR_RIGHT ? -step : step);
|
||||||
|
if (leftcol < 0)
|
||||||
|
leftcol = 0;
|
||||||
|
|
||||||
if (mouse_hor_step < 0
|
did_ins_scroll = do_mousescroll_horiz((long_u)leftcol);
|
||||||
|| mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
|
|
||||||
step = curwin->w_width;
|
|
||||||
else
|
|
||||||
step = mouse_hor_step;
|
|
||||||
val = curwin->w_leftcol + (cap->arg == MSCR_RIGHT ? -step : +step);
|
|
||||||
if (val < 0)
|
|
||||||
val = 0;
|
|
||||||
|
|
||||||
gui_do_horiz_scroll(val, TRUE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# endif
|
|
||||||
# ifdef FEAT_SYN_HL
|
# ifdef FEAT_SYN_HL
|
||||||
if (curwin != old_curwin && curwin->w_p_cul)
|
if (mode == MODE_NORMAL && curwin != old_curwin && curwin->w_p_cul)
|
||||||
redraw_for_cursorline(curwin);
|
redraw_for_cursorline(curwin);
|
||||||
# endif
|
# endif
|
||||||
may_trigger_winscrolled();
|
may_trigger_winscrolled();
|
||||||
@ -2165,6 +2170,29 @@ nv_mousescroll(cmdarg_T *cap)
|
|||||||
|
|
||||||
curwin = old_curwin;
|
curwin = old_curwin;
|
||||||
curbuf = curwin->w_buffer;
|
curbuf = curwin->w_buffer;
|
||||||
|
|
||||||
|
if (mode == MODE_INSERT)
|
||||||
|
{
|
||||||
|
// The popup menu may overlay the window, need to redraw it.
|
||||||
|
// TODO: Would be more efficient to only redraw the windows that are
|
||||||
|
// overlapped by the popup menu.
|
||||||
|
if (pum_visible() && did_ins_scroll)
|
||||||
|
{
|
||||||
|
redraw_all_later(UPD_NOT_VALID);
|
||||||
|
ins_compl_show_pum();
|
||||||
|
}
|
||||||
|
if (!EQUAL_POS(curwin->w_cursor, tpos))
|
||||||
|
{
|
||||||
|
start_arrow(&tpos);
|
||||||
|
set_can_cindent(TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv_mousescroll(cmdarg_T *cap)
|
||||||
|
{
|
||||||
|
do_mousescroll(MODE_NORMAL, cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3047,7 +3047,7 @@ nv_hor_scrollbar(cmdarg_T *cap)
|
|||||||
clearopbeep(cap->oap);
|
clearopbeep(cap->oap);
|
||||||
|
|
||||||
// Even if an operator was pending, we still want to scroll
|
// Even if an operator was pending, we still want to scroll
|
||||||
gui_do_horiz_scroll(scrollbar_value, FALSE);
|
do_mousescroll_horiz(scrollbar_value);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -45,7 +45,6 @@ void gui_drag_scrollbar(scrollbar_T *sb, long value, int still_dragging);
|
|||||||
void gui_may_update_scrollbars(void);
|
void gui_may_update_scrollbars(void);
|
||||||
void gui_update_scrollbars(int force);
|
void gui_update_scrollbars(int force);
|
||||||
int gui_do_scroll(void);
|
int gui_do_scroll(void);
|
||||||
int gui_do_horiz_scroll(long_u leftcol, int compute_longest_lnum);
|
|
||||||
void gui_check_colors(void);
|
void gui_check_colors(void);
|
||||||
guicolor_T gui_get_color(char_u *name);
|
guicolor_T gui_get_color(char_u *name);
|
||||||
int gui_get_lightness(guicolor_T pixel);
|
int gui_get_lightness(guicolor_T pixel);
|
||||||
|
@ -14,6 +14,8 @@ int mouse_has(int c);
|
|||||||
int mouse_model_popup(void);
|
int mouse_model_popup(void);
|
||||||
void reset_dragwin(void);
|
void reset_dragwin(void);
|
||||||
int jump_to_mouse(int flags, int *inclusive, int which_button);
|
int jump_to_mouse(int flags, int *inclusive, int which_button);
|
||||||
|
int do_mousescroll_horiz(long_u leftcol);
|
||||||
|
void do_mousescroll(int mode, cmdarg_T *cap);
|
||||||
void nv_mousescroll(cmdarg_T *cap);
|
void nv_mousescroll(cmdarg_T *cap);
|
||||||
void nv_mouse(cmdarg_T *cap);
|
void nv_mouse(cmdarg_T *cap);
|
||||||
void reset_held_button(void);
|
void reset_held_button(void);
|
||||||
|
@ -30,6 +30,8 @@ void ui_cursor_shape_forced(int forced);
|
|||||||
void ui_cursor_shape(void);
|
void ui_cursor_shape(void);
|
||||||
int check_col(int col);
|
int check_col(int col);
|
||||||
int check_row(int row);
|
int check_row(int row);
|
||||||
|
long scroll_line_len(linenr_T lnum);
|
||||||
|
linenr_T ui_find_longest_lnum(void);
|
||||||
void ui_focus_change(int in_focus);
|
void ui_focus_change(int in_focus);
|
||||||
void im_save_status(long *psave);
|
void im_save_status(long *psave);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
69
src/ui.c
69
src/ui.c
@ -1125,6 +1125,75 @@ check_row(int row)
|
|||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return length of line "lnum" in screen cells for horizontal scrolling.
|
||||||
|
*/
|
||||||
|
long
|
||||||
|
scroll_line_len(linenr_T lnum)
|
||||||
|
{
|
||||||
|
char_u *p = ml_get(lnum);
|
||||||
|
colnr_T col = 0;
|
||||||
|
|
||||||
|
if (*p != NUL)
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
int w = chartabsize(p, col);
|
||||||
|
MB_PTR_ADV(p);
|
||||||
|
if (*p == NUL) // don't count the last character
|
||||||
|
break;
|
||||||
|
col += w;
|
||||||
|
}
|
||||||
|
return col;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the longest visible line number. This is used for horizontal
|
||||||
|
* scrolling. If this is not possible (or not desired, by setting 'h' in
|
||||||
|
* "guioptions") then the current line number is returned.
|
||||||
|
*/
|
||||||
|
linenr_T
|
||||||
|
ui_find_longest_lnum(void)
|
||||||
|
{
|
||||||
|
linenr_T ret = 0;
|
||||||
|
|
||||||
|
// Calculate maximum for horizontal scrollbar. Check for reasonable
|
||||||
|
// line numbers, topline and botline can be invalid when displaying is
|
||||||
|
// postponed.
|
||||||
|
if (
|
||||||
|
# ifdef FEAT_GUI
|
||||||
|
(!gui.in_use || vim_strchr(p_go, GO_HORSCROLL) == NULL) &&
|
||||||
|
# endif
|
||||||
|
curwin->w_topline <= curwin->w_cursor.lnum
|
||||||
|
&& curwin->w_botline > curwin->w_cursor.lnum
|
||||||
|
&& curwin->w_botline <= curbuf->b_ml.ml_line_count + 1)
|
||||||
|
{
|
||||||
|
linenr_T lnum;
|
||||||
|
long n;
|
||||||
|
long 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 (lnum = curwin->w_topline; lnum < curwin->w_botline; ++lnum)
|
||||||
|
{
|
||||||
|
n = scroll_line_len(lnum);
|
||||||
|
if (n > max)
|
||||||
|
{
|
||||||
|
max = n;
|
||||||
|
ret = lnum;
|
||||||
|
}
|
||||||
|
else if (n == max && abs((int)(lnum - curwin->w_cursor.lnum))
|
||||||
|
< abs((int)(ret - curwin->w_cursor.lnum)))
|
||||||
|
ret = lnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// Use cursor line only.
|
||||||
|
ret = curwin->w_cursor.lnum;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called when focus changed. Used for the GUI or for systems where this can
|
* Called when focus changed. Used for the GUI or for systems where this can
|
||||||
* be done in the console (Win32).
|
* be done in the console (Win32).
|
||||||
|
@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
886,
|
||||||
/**/
|
/**/
|
||||||
885,
|
885,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user