" Helper functions for generating mouse events " xterm2 and sgr always work, urxvt is optional. let g:Ttymouse_values = ['xterm2', 'sgr'] if has('mouse_urxvt') call add(g:Ttymouse_values, 'urxvt') endif " dec doesn't support all the functionality if has('mouse_dec') let g:Ttymouse_dec = ['dec'] else let g:Ttymouse_dec = [] endif " netterm only supports left click if has('mouse_netterm') let g:Ttymouse_netterm = ['netterm'] else let g:Ttymouse_netterm = [] endif " Vim Mouse Codes. " Used by the GUI and by MS-Windows Consoles. " Keep these in sync with vim.h let s:MOUSE_CODE = { \ 'BTN_LEFT' : 0x00, \ 'BTN_MIDDLE' : 0x01, \ 'BTN_RIGHT' : 0x02, \ 'BTN_RELEASE' : 0x03, \ 'BTN_X1' : 0x300, \ 'BTN_X2' : 0x400, \ 'SCRL_DOWN' : 0x100, \ 'SCRL_UP' : 0x200, \ 'SCRL_LEFT' : 0x500, \ 'SCRL_RIGHT' : 0x600, \ 'MOVE' : 0x700, \ 'MOD_SHIFT' : 0x04, \ 'MOD_ALT' : 0x08, \ 'MOD_CTRL' : 0x10, \ } " Helper function to emit a terminal escape code. func TerminalEscapeCode(code, row, col, m) if &ttymouse ==# 'xterm2' " need to use byte encoding here. let str = list2str([a:code + 0x20, a:col + 0x20, a:row + 0x20]) if has('iconv') let bytes = str->iconv('utf-8', 'latin1') else " Hopefully the numbers are not too big. let bytes = str endif return "\[M" .. bytes elseif &ttymouse ==# 'sgr' return printf("\[<%d;%d;%d%s", a:code, a:col, a:row, a:m) elseif &ttymouse ==# 'urxvt' return printf("\[%d;%d;%dM", a:code + 0x20, a:col, a:row) endif endfunc func DecEscapeCode(code, down, row, col) return printf("\[%d;%d;%d;%d&w", a:code, a:down, a:row, a:col) endfunc func NettermEscapeCode(row, col) return printf("\}%d,%d\r", a:row, a:col) endfunc " Send low level mouse event to MS-Windows consoles or GUI func MSWinMouseEvent(button, row, col, move, multiclick, modifiers) let args = { } let args.button = a:button " Scroll directions are inverted in the GUI, no idea why. if has('gui_running') if a:button == s:MOUSE_CODE.SCRL_UP let args.button = s:MOUSE_CODE.SCRL_DOWN elseif a:button == s:MOUSE_CODE.SCRL_DOWN let args.button = s:MOUSE_CODE.SCRL_UP elseif a:button == s:MOUSE_CODE.SCRL_LEFT let args.button = s:MOUSE_CODE.SCRL_RIGHT elseif a:button == s:MOUSE_CODE.SCRL_RIGHT let args.button = s:MOUSE_CODE.SCRL_LEFT endif endif let args.row = a:row let args.col = a:col let args.move = a:move let args.multiclick = a:multiclick let args.modifiers = a:modifiers call test_mswin_event("mouse", args) unlet args endfunc func MouseLeftClickCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(2, 4, a:row, a:col) elseif &ttymouse ==# 'netterm' return NettermEscapeCode(a:row, a:col) else return TerminalEscapeCode(0, a:row, a:col, 'M') endif endfunc func MouseLeftClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_LEFT, a:row, a:col, 0, 0, 0) else call feedkeys(MouseLeftClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseMiddleClickCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(4, 2, a:row, a:col) else return TerminalEscapeCode(1, a:row, a:col, 'M') endif endfunc func MouseMiddleClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_MIDDLE, a:row, a:col, 0, 0, 0) else call feedkeys(MouseMiddleClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseRightClickCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(6, 1, a:row, a:col) else return TerminalEscapeCode(2, a:row, a:col, 'M') endif endfunc func MouseRightClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_RIGHT, a:row, a:col, 0, 0, 0) else call feedkeys(MouseRightClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseCtrlLeftClickCode(row, col) let ctrl = 0x10 return TerminalEscapeCode(0 + ctrl, a:row, a:col, 'M') endfunc func MouseCtrlLeftClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_LEFT, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_CTRL) else call feedkeys(MouseCtrlLeftClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseCtrlRightClickCode(row, col) let ctrl = 0x10 return TerminalEscapeCode(2 + ctrl, a:row, a:col, 'M') endfunc func MouseCtrlRightClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_RIGHT, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_CTRL) else call feedkeys(MouseCtrlRightClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseAltLeftClickCode(row, col) let alt = 0x8 return TerminalEscapeCode(0 + alt, a:row, a:col, 'M') endfunc func MouseAltLeftClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_LEFT, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_ALT) else call feedkeys(MouseAltLeftClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseAltRightClickCode(row, col) let alt = 0x8 return TerminalEscapeCode(2 + alt, a:row, a:col, 'M') endfunc func MouseAltRightClick(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_RIGHT, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_ALT) else call feedkeys(MouseAltRightClickCode(a:row, a:col), 'Lx!') endif endfunc func MouseLeftReleaseCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(3, 0, a:row, a:col) elseif &ttymouse ==# 'netterm' return '' else return TerminalEscapeCode(3, a:row, a:col, 'm') endif endfunc func MouseLeftRelease(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_RELEASE, a:row, a:col, 0, 0, 0) else call feedkeys(MouseLeftReleaseCode(a:row, a:col), 'Lx!') endif endfunc func MouseMiddleReleaseCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(5, 0, a:row, a:col) else return TerminalEscapeCode(3, a:row, a:col, 'm') endif endfunc func MouseMiddleRelease(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_RELEASE, a:row, a:col, 0, 0, 0) else call feedkeys(MouseMiddleReleaseCode(a:row, a:col), 'Lx!') endif endfunc func MouseRightReleaseCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(7, 0, a:row, a:col) else return TerminalEscapeCode(3, a:row, a:col, 'm') endif endfunc func MouseRightRelease(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_RELEASE, a:row, a:col, 0, 0, 0) else call feedkeys(MouseRightReleaseCode(a:row, a:col), 'Lx!') endif endfunc func MouseLeftDragCode(row, col) if &ttymouse ==# 'dec' return DecEscapeCode(1, 4, a:row, a:col) else return TerminalEscapeCode(0x20, a:row, a:col, 'M') endif endfunc func MouseLeftDrag(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.BTN_LEFT, a:row, a:col, 1, 0, 0) else call feedkeys(MouseLeftDragCode(a:row, a:col), 'Lx!') endif endfunc func MouseWheelUpCode(row, col) return TerminalEscapeCode(0x40, a:row, a:col, 'M') endfunc func MouseWheelUp(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_UP, a:row, a:col, 0, 0, 0) else call feedkeys(MouseWheelUpCode(a:row, a:col), 'Lx!') endif endfunc func MouseWheelDownCode(row, col) return TerminalEscapeCode(0x41, a:row, a:col, 'M') endfunc func MouseWheelDown(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_DOWN, a:row, a:col, 0, 0, 0) else call feedkeys(MouseWheelDownCode(a:row, a:col), 'Lx!') endif endfunc func MouseWheelLeftCode(row, col) return TerminalEscapeCode(0x42, a:row, a:col, 'M') endfunc func MouseWheelLeft(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_LEFT, a:row, a:col, 0, 0, 0) else call feedkeys(MouseWheelLeftCode(a:row, a:col), 'Lx!') endif endfunc func MouseWheelRightCode(row, col) return TerminalEscapeCode(0x43, a:row, a:col, 'M') endfunc func MouseWheelRight(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_RIGHT, a:row, a:col, 0, 0, 0) else call feedkeys(MouseWheelRightCode(a:row, a:col), 'Lx!') endif endfunc func MouseShiftWheelUpCode(row, col) " todo feed shift mod. return TerminalEscapeCode(0x40, a:row, a:col, 'M') endfunc func MouseShiftWheelUp(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_UP, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_SHIFT) else call feedkeys(MouseShiftWheelUpCode(a:row, a:col), 'Lx!') endif endfunc func MouseShiftWheelDownCode(row, col) " todo feed shift mod. return TerminalEscapeCode(0x41, a:row, a:col, 'M') endfunc func MouseShiftWheelDown(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_DOWN, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_SHIFT) else call feedkeys(MouseShiftWheelDownCode(a:row, a:col), 'Lx!') endif endfunc func MouseShiftWheelLeftCode(row, col) " todo feed shift mod. return TerminalEscapeCode(0x42, a:row, a:col, 'M') endfunc func MouseShiftWheelLeft(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_LEFT, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_SHIFT) else call feedkeys(MouseShiftWheelLeftCode(a:row, a:col), 'Lx!') endif endfunc func MouseShiftWheelRightCode(row, col) " todo feed shift mod. return TerminalEscapeCode(0x43, a:row, a:col, 'M') endfunc func MouseShiftWheelRight(row, col) if has('win32') call MSWinMouseEvent(s:MOUSE_CODE.SCRL_RIGHT, a:row, a:col, 0, 0, \ s:MOUSE_CODE.MOD_SHIFT) else call feedkeys(MouseShiftWheelRightCode(a:row, a:col), 'Lx!') endif endfunc " vim: shiftwidth=2 sts=2 expandtab