Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion runtime/doc/term.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,8 @@ Mouse clicks can be mapped. The codes for mouse clicks are:

The X1 and X2 buttons refer to the extra buttons found on some mice. The
'Microsoft Explorer' mouse has these buttons available to the right thumb.
Currently X1 and X2 only work on Win32 and X11 environments.
Currently X1 and X2 only work on Win32 and X11 environments, and in terminals
with xterm-like mouse support.

Examples: >
:noremap <MiddleMouse> <LeftMouse><MiddleMouse>
Expand Down
12 changes: 11 additions & 1 deletion src/mouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -2316,6 +2316,10 @@ check_termcode_mouse(
* 0x23 = any button release
* 0x60 = button 4 down (scroll wheel down)
* 0x61 = button 5 down (scroll wheel up)
* 0x62 = button 6 down (scroll wheel left)
* 0x63 = button 7 down (scroll wheel right)
* 0xa0 = button 8 down (backward button)
* 0xa1 = button 9 down (forward button)
* add 0x04 for SHIFT
* add 0x08 for ALT
* add 0x10 for CTRL
Expand Down Expand Up @@ -2470,7 +2474,7 @@ check_termcode_mouse(
* Linux console with GPM and the MS-DOS or Win32 console
* (multi-clicks use >= 0x60).
*/
if (mouse_code >= MOUSEWHEEL_LOW
if (mouse_code >= MOUSEWHEEL_LOW && mouse_code < MOUSESIDEBUTTONS_LOW
# ifdef FEAT_GUI
&& !gui.in_use
# endif
Expand Down Expand Up @@ -2993,7 +2997,13 @@ check_termcode_mouse(
held_button = MOUSE_RELEASE;
}
else
{
#if defined(UNIX)
if (use_xterm_mouse() && orig_mouse_code >= MOUSESIDEBUTTONS_LOW)
current_button = (current_button) ? MOUSE_X2 : MOUSE_X1;
Copy link

Copilot AI Nov 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider using (orig_mouse_code & 0x01) instead of (current_button) for clarity. While the current logic is correct (relying on the LSB being preserved through the mask at line 2871), directly checking the LSB of orig_mouse_code would make the intent more explicit: button 8 (0xa0) has LSB=0 → X1, button 9 (0xa1) has LSB=1 → X2.

Suggested change
current_button = (current_button) ? MOUSE_X2 : MOUSE_X1;
current_button = (orig_mouse_code & 0x01) ? MOUSE_X2 : MOUSE_X1;

Copilot uses AI. Check for mistakes.
#endif
key_name[1] = get_pseudo_mouse_code(current_button, is_click, is_drag);
}


// Make sure the mouse position is valid. Some terminals may return weird
Expand Down
58 changes: 58 additions & 0 deletions src/testdir/test_termcodes.vim
Original file line number Diff line number Diff line change
Expand Up @@ -1641,6 +1641,64 @@ func Test_mouse_termcodes()
%bw!
endfunc

" Test buttons 8 and 9 for xterm-like terminal mouse support
func Test_term_mouse_side_buttons()
new
let save_mouse = &mouse
let save_term = &term
let save_ttymouse = &ttymouse
call test_override('no_query_mouse', 1)
set mouse=a term=xterm
call WaitForResponses()

for ttymouse_val in g:Ttymouse_values
let msg = 'ttymouse=' .. ttymouse_val
exe 'set ttymouse=' .. ttymouse_val

let mouse_codes = [
\ ["<X1Mouse>", TerminalEscapeCode(128, 1, 1, 'M')],
\ ["<X1Drag>", TerminalEscapeCode(128+32, 1, 1, 'M')],
\ ["<X2Mouse>", TerminalEscapeCode(129, 1, 1, 'M')],
\ ["<X2Drag>", TerminalEscapeCode(129+32, 1, 1, 'M')],
\ ["<S-X1Mouse>", TerminalEscapeCode(128+4, 1, 1, 'M')],
\ ["<S-X2Mouse>", TerminalEscapeCode(129+4, 1, 1, 'M')],
\ ["<M-X1Mouse>", TerminalEscapeCode(128+8, 1, 1, 'M')],
\ ["<M-X2Mouse>", TerminalEscapeCode(129+8, 1, 1, 'M')],
\ ["<C-X1Mouse>", TerminalEscapeCode(128+16, 1, 1, 'M')],
\ ["<C-X2Mouse>", TerminalEscapeCode(129+16, 1, 1, 'M')],
\ ]

for [outstr, code] in mouse_codes
exe "normal ggC\<C-K>" . code
" normal ggD
" call feedkeys("i\<C-K>" . code, 'Lx!')
Copy link

Copilot AI Nov 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented-out code. These lines appear to be debugging or alternative testing approaches that were left in. If they're not needed, they should be removed to keep the test clean.

Suggested change
" call feedkeys("i\<C-K>" . code, 'Lx!')

Copilot uses AI. Check for mistakes.
call assert_equal(outstr, getline(1), msg)
endfor
endfor

" ttymouse_val 'sgr'
let msg = 'ttymouse=sgr'
exe 'set ttymouse=sgr'

let mouse_codes = [
\ ["<X1Mouse>", TerminalEscapeCode(128, 1, 1, 'M')],
\ ["<X1Release>", TerminalEscapeCode(128, 1, 1, 'm')],
\ ["<X2Mouse>", TerminalEscapeCode(129, 1, 1, 'M')],
\ ["<X2Release>", TerminalEscapeCode(129, 1, 1, 'm')],
\ ]

for [outstr, code] in mouse_codes
exe "normal ggC\<C-K>" . code
call assert_equal(outstr, getline(1), msg)
endfor

let &mouse = save_mouse
let &term = save_term
let &ttymouse = save_ttymouse
call test_override('no_query_mouse', 0)
bwipe!
endfunc

" This only checks if the sequence is recognized.
" This must be after other tests, because it has side effects to xterm
" properties.
Expand Down
3 changes: 3 additions & 0 deletions src/vim.h
Original file line number Diff line number Diff line change
Expand Up @@ -2095,6 +2095,9 @@ typedef int sock_T;
// Lowest button code for using the mouse wheel (xterm only)
#define MOUSEWHEEL_LOW 0x60

// Lowest button code for extra mouse buttons 8-11
Copy link

Copilot AI Nov 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment mentions "extra mouse buttons 8-11" but the implementation only adds support for buttons 8 and 9 (corresponding to X1 and X2). Consider updating the comment to "extra mouse buttons 8-9" to accurately reflect what's implemented, or clarify that 10-11 are reserved for future use.

Suggested change
// Lowest button code for extra mouse buttons 8-11
// Lowest button code for extra mouse buttons 8-9

Copilot uses AI. Check for mistakes.
#define MOUSESIDEBUTTONS_LOW 0xa0

#define MOUSE_CLICK_MASK 0x03

#define NUM_MOUSE_CLICKS(code) \
Expand Down
Loading