mirror of
https://github.com/neovim/neovim.git
synced 2025-09-16 08:18:17 +00:00
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:
@@ -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();
|
||||
}
|
||||
|
Reference in New Issue
Block a user