mouse: Implement horizontal scroll. #3450
- Code from Vim source. - Removed the check for 'guioptions' - mouse_spec.lua: test <ScrollWheelLeft> and <ScrollWheelRight> - Move horizontal scroll logic to mouse.c - Remove 'gui_' from the function names - Renamed variables to be more specific (as opposed to generic p, w). - Marked some functions as `static`
This commit is contained in:
parent
dfe85dd80a
commit
5a5ef1c222
|
@ -7741,6 +7741,8 @@ static void ins_mousescroll(int dir)
|
|||
(long)(curwin->w_botline - curwin->w_topline));
|
||||
else
|
||||
scroll_redraw(dir, 3L);
|
||||
} else {
|
||||
mouse_scroll_horiz(dir);
|
||||
}
|
||||
did_scroll = TRUE;
|
||||
}
|
||||
|
|
|
@ -36,12 +36,6 @@ typedef int (*IndentGetter)(void);
|
|||
#define INSCHAR_NO_FEX 8 /* don't use 'formatexpr' */
|
||||
#define INSCHAR_COM_LIST 16 /* format comments with list/2nd line indent */
|
||||
|
||||
/* direction for nv_mousescroll() and ins_mousescroll() */
|
||||
#define MSCR_DOWN 0 /* DOWN must be FALSE */
|
||||
#define MSCR_UP 1
|
||||
#define MSCR_LEFT -1
|
||||
#define MSCR_RIGHT -2
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "edit.h.generated.h"
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "nvim/misc1.h"
|
||||
#include "nvim/cursor.h"
|
||||
#include "nvim/buffer_defs.h"
|
||||
#include "nvim/memline.h"
|
||||
#include "nvim/charset.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "mouse.c.generated.h"
|
||||
|
@ -503,3 +505,95 @@ 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;
|
||||
char_u *line = ml_get(lnum);
|
||||
if (*line != NUL) {
|
||||
for (;;) {
|
||||
int numchar = chartabsize(line, col);
|
||||
mb_ptr_adv(line);
|
||||
if (*line == NUL) { // don't count the last character
|
||||
break;
|
||||
}
|
||||
col += numchar;
|
||||
}
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
///
|
||||
/// Find longest visible line number.
|
||||
///
|
||||
static linenr_T 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 (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;
|
||||
|
||||
// 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) {
|
||||
max = len;
|
||||
ret = lnum;
|
||||
} else if (len == (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;
|
||||
}
|
||||
|
||||
///
|
||||
/// 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 = 6;
|
||||
if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) {
|
||||
step = curwin->w_width;
|
||||
}
|
||||
|
||||
int leftcol = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : +step);
|
||||
if (leftcol < 0) {
|
||||
leftcol = 0;
|
||||
}
|
||||
|
||||
if (curwin->w_leftcol == 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 (!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 leftcol_changed();
|
||||
}
|
||||
|
|
|
@ -34,6 +34,12 @@
|
|||
#define MOUSE_X1 0x300 // Mouse-button X1 (6th)
|
||||
#define MOUSE_X2 0x400 // Mouse-button X2
|
||||
|
||||
// Direction for nv_mousescroll() and ins_mousescroll()
|
||||
#define MSCR_DOWN 0 // DOWN must be FALSE
|
||||
#define MSCR_UP 1
|
||||
#define MSCR_LEFT -1
|
||||
#define MSCR_RIGHT -2
|
||||
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "mouse.h.generated.h"
|
||||
|
|
|
@ -3927,6 +3927,8 @@ static void nv_mousescroll(cmdarg_T *cap)
|
|||
cap->count0 = 3;
|
||||
nv_scroll_line(cap);
|
||||
}
|
||||
} else {
|
||||
mouse_scroll_horiz(cap->arg);
|
||||
}
|
||||
|
||||
curwin->w_redr_status = true;
|
||||
|
|
|
@ -426,4 +426,35 @@ describe('Mouse input', function()
|
|||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('horizontal scrolling', function()
|
||||
feed("<esc>:set nowrap<cr>")
|
||||
|
||||
feed("a <esc>20Ab<esc>")
|
||||
screen:expect([[
|
||||
|
|
||||
|
|
||||
bbbbbbbbbbbbbbb^b |
|
||||
~ |
|
||||
|
|
||||
]])
|
||||
|
||||
feed("<ScrollWheelLeft><0,0>")
|
||||
screen:expect([[
|
||||
|
|
||||
|
|
||||
n bbbbbbbbbbbbbbbbbbb^b |
|
||||
~ |
|
||||
|
|
||||
]])
|
||||
|
||||
feed("^<ScrollWheelRight><0,0>")
|
||||
screen:expect([[
|
||||
g |
|
||||
|
|
||||
^t and selection bbbbbbbbb|
|
||||
~ |
|
||||
|
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
|
Loading…
Reference in New Issue