1" Tests for decoding escape sequences sent by the terminal. 2 3" This only works for Unix in a terminal 4if has('gui_running') || !has('unix') 5 finish 6endif 7 8" Helper function to emit a terminal escape code. 9func TerminalEscapeCode(code_xterm, code_sgr, row, col, m) 10 if &ttymouse ==# 'xterm2' 11 " need to use byte encoding here. 12 let str = list2str([a:code_xterm, a:col + 0x20, a:row + 0x20]) 13 if has('iconv') 14 let bytes = iconv(str, 'utf-8', 'latin1') 15 else 16 " Hopefully the numbers are not too big. 17 let bytes = str 18 endif 19 call feedkeys("\<Esc>[M" .. bytes, 'Lx!') 20 elseif &ttymouse ==# 'sgr' 21 call feedkeys(printf("\<Esc>[<%d;%d;%d%s", a:code_sgr, a:col, a:row, a:m), 'Lx!') 22 endif 23endfunc 24 25func MouseLeftClick(row, col) 26 call TerminalEscapeCode(0x20, 0, a:row, a:col, 'M') 27endfunc 28 29func MouseLeftRelease(row, col) 30 call TerminalEscapeCode(0x23, 3, a:row, a:col, 'm') 31endfunc 32 33func MouseLeftDrag(row, col) 34 call TerminalEscapeCode(0x43, 0x20, a:row, a:col, 'M') 35endfunc 36 37func MouseWheelUp(row, col) 38 call TerminalEscapeCode(0x40, 0x40, a:row, a:col, 'M') 39endfunc 40 41func MouseWheelDown(row, col) 42 call TerminalEscapeCode(0x41, 0x41, a:row, a:col, 'M') 43endfunc 44 45func Test_xterm_mouse_click() 46 new 47 let save_mouse = &mouse 48 let save_term = &term 49 let save_ttymouse = &ttymouse 50 set mouse=a term=xterm 51 call setline(1, ['line 1', 'line 2', 'line 3 is a bit longer']) 52 53 for ttymouse_val in ['xterm2', 'sgr'] 54 let msg = 'ttymouse=' .. ttymouse_val 55 exe 'set ttymouse=' . ttymouse_val 56 go 57 call assert_equal([0, 1, 1, 0], getpos('.'), msg) 58 let row = 2 59 let col = 6 60 call MouseLeftClick(row, col) 61 call MouseLeftRelease(row, col) 62 call assert_equal([0, 2, 6, 0], getpos('.'), msg) 63 endfor 64 65 let &mouse = save_mouse 66 let &term = save_term 67 let &ttymouse = save_ttymouse 68 bwipe! 69endfunc 70 71func Test_xterm_mouse_wheel() 72 new 73 let save_mouse = &mouse 74 let save_term = &term 75 let save_ttymouse = &ttymouse 76 set mouse=a term=xterm 77 call setline(1, range(1, 100)) 78 79 for ttymouse_val in ['xterm2', 'sgr'] 80 let msg = 'ttymouse=' .. ttymouse_val 81 exe 'set ttymouse=' . ttymouse_val 82 go 83 call assert_equal(1, line('w0'), msg) 84 call assert_equal([0, 1, 1, 0], getpos('.'), msg) 85 86 call MouseWheelDown(1, 1) 87 call assert_equal(4, line('w0'), msg) 88 call assert_equal([0, 4, 1, 0], getpos('.'), msg) 89 90 call MouseWheelDown(1, 1) 91 call assert_equal(7, line('w0'), msg) 92 call assert_equal([0, 7, 1, 0], getpos('.'), msg) 93 94 call MouseWheelUp(1, 1) 95 call assert_equal(4, line('w0'), msg) 96 call assert_equal([0, 7, 1, 0], getpos('.'), msg) 97 98 call MouseWheelUp(1, 1) 99 call assert_equal(1, line('w0'), msg) 100 call assert_equal([0, 7, 1, 0], getpos('.'), msg) 101 endfor 102 103 let &mouse = save_mouse 104 let &term = save_term 105 let &ttymouse = save_ttymouse 106 bwipe! 107endfunc 108 109func Test_xterm_mouse_drag_window_separator() 110 let save_mouse = &mouse 111 let save_term = &term 112 let save_ttymouse = &ttymouse 113 set mouse=a term=xterm 114 115 for ttymouse_val in ['xterm2', 'sgr'] 116 let msg = 'ttymouse=' .. ttymouse_val 117 exe 'set ttymouse=' . ttymouse_val 118 119 " Split horizontally and test dragging the horizontal window separator. 120 split 121 let rowseparator = winheight(0) + 1 122 let row = rowseparator 123 let col = 1 124 125 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 126 if ttymouse_val !=# 'xterm2' || row <= 223 127 call MouseLeftClick(row, col) 128 let row -= 1 129 call MouseLeftDrag(row, col) 130 call assert_equal(rowseparator - 1, winheight(0) + 1, msg) 131 let row += 1 132 call MouseLeftDrag(row, col) 133 call assert_equal(rowseparator, winheight(0) + 1, msg) 134 call MouseLeftRelease(row, col) 135 call assert_equal(rowseparator, winheight(0) + 1, msg) 136 endif 137 bwipe! 138 139 " Split vertically and test dragging the vertical window separator. 140 vsplit 141 let colseparator = winwidth(0) + 1 142 let row = 1 143 let col = colseparator 144 145 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 146 if ttymouse_val !=# 'xterm2' || col <= 223 147 call MouseLeftClick(row, col) 148 let col -= 1 149 call MouseLeftDrag(row, col) 150 call assert_equal(colseparator - 1, winwidth(0) + 1, msg) 151 let col += 1 152 call MouseLeftDrag(row, col) 153 call assert_equal(colseparator, winwidth(0) + 1, msg) 154 call MouseLeftRelease(row, col) 155 call assert_equal(colseparator, winwidth(0) + 1, msg) 156 endif 157 bwipe! 158 endfor 159 160 let &mouse = save_mouse 161 let &term = save_term 162 let &ttymouse = save_ttymouse 163endfunc 164 165func Test_xterm_mouse_drag_statusline() 166 let save_mouse = &mouse 167 let save_term = &term 168 let save_ttymouse = &ttymouse 169 let save_laststatus = &laststatus 170 set mouse=a term=xterm laststatus=2 171 172 for ttymouse_val in ['xterm2', 'sgr'] 173 let msg = 'ttymouse=' .. ttymouse_val 174 exe 'set ttymouse=' . ttymouse_val 175 176 call assert_equal(1, &cmdheight, msg) 177 let rowstatusline = winheight(0) + 1 178 let row = rowstatusline 179 let col = 1 180 181 if ttymouse_val ==# 'xterm2' && row > 223 182 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 183 continue 184 endif 185 186 call MouseLeftClick(row, col) 187 let row -= 1 188 call MouseLeftDrag(row, col) 189 call assert_equal(2, &cmdheight, msg) 190 call assert_equal(rowstatusline - 1, winheight(0) + 1, msg) 191 let row += 1 192 call MouseLeftDrag(row, col) 193 call assert_equal(1, &cmdheight, msg) 194 call assert_equal(rowstatusline, winheight(0) + 1, msg) 195 call MouseLeftRelease(row, col) 196 call assert_equal(1, &cmdheight, msg) 197 call assert_equal(rowstatusline, winheight(0) + 1, msg) 198 endfor 199 200 let &mouse = save_mouse 201 let &term = save_term 202 let &ttymouse = save_ttymouse 203 let &laststatus = save_laststatus 204endfunc 205 206func Test_xterm_mouse_click_tab() 207 let save_mouse = &mouse 208 let save_term = &term 209 let save_ttymouse = &ttymouse 210 set mouse=a term=xterm 211 let row = 1 212 213 for ttymouse_val in ['xterm2', 'sgr'] 214 let msg = 'ttymouse=' .. ttymouse_val 215 exe 'set ttymouse=' . ttymouse_val 216 e Xfoo 217 tabnew Xbar 218 219 let a = split(execute(':tabs'), "\n") 220 call assert_equal(['Tab page 1', 221 \ ' Xfoo', 222 \ 'Tab page 2', 223 \ '> Xbar'], a, msg) 224 225 " Test clicking on tab names in the tabline at the top. 226 let col = 2 227 redraw 228 call MouseLeftClick(row, col) 229 call MouseLeftRelease(row, col) 230 let a = split(execute(':tabs'), "\n") 231 call assert_equal(['Tab page 1', 232 \ '> Xfoo', 233 \ 'Tab page 2', 234 \ ' Xbar'], a, msg) 235 236 let col = 9 237 call MouseLeftClick(row, col) 238 call MouseLeftRelease(row, col) 239 let a = split(execute(':tabs'), "\n") 240 call assert_equal(['Tab page 1', 241 \ ' Xfoo', 242 \ 'Tab page 2', 243 \ '> Xbar'], a, msg) 244 245 %bwipe! 246 endfor 247 248 let &mouse = save_mouse 249 let &term = save_term 250 let &ttymouse = save_ttymouse 251endfunc 252 253func Test_xterm_mouse_click_X_to_close_tab() 254 let save_mouse = &mouse 255 let save_term = &term 256 let save_ttymouse = &ttymouse 257 set mouse=a term=xterm 258 let row = 1 259 let col = &columns 260 261 for ttymouse_val in ['xterm2', 'sgr'] 262 if ttymouse_val ==# 'xterm2' && col > 223 263 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 264 continue 265 endif 266 let msg = 'ttymouse=' .. ttymouse_val 267 exe 'set ttymouse=' . ttymouse_val 268 e Xtab1 269 tabnew Xtab2 270 tabnew Xtab3 271 tabn 2 272 273 let a = split(execute(':tabs'), "\n") 274 call assert_equal(['Tab page 1', 275 \ ' Xtab1', 276 \ 'Tab page 2', 277 \ '> Xtab2', 278 \ 'Tab page 3', 279 \ ' Xtab3'], a, msg) 280 281 " Click on "X" in tabline to close current tab i.e. Xtab2. 282 redraw 283 call MouseLeftClick(row, col) 284 call MouseLeftRelease(row, col) 285 let a = split(execute(':tabs'), "\n") 286 call assert_equal(['Tab page 1', 287 \ ' Xtab1', 288 \ 'Tab page 2', 289 \ '> Xtab3'], a, msg) 290 291 %bwipe! 292 endfor 293 294 let &mouse = save_mouse 295 let &term = save_term 296 let &ttymouse = save_ttymouse 297endfunc 298 299func Test_xterm_mouse_drag_to_move_tab() 300 let save_mouse = &mouse 301 let save_term = &term 302 let save_ttymouse = &ttymouse 303 " Set 'mousetime' to 1 to avoid recognizing a double-click in the loop 304 set mouse=a term=xterm mousetime=1 305 let row = 1 306 307 for ttymouse_val in ['xterm2', 'sgr'] 308 let msg = 'ttymouse=' .. ttymouse_val 309 exe 'set ttymouse=' . ttymouse_val 310 e Xtab1 311 tabnew Xtab2 312 313 let a = split(execute(':tabs'), "\n") 314 call assert_equal(['Tab page 1', 315 \ ' Xtab1', 316 \ 'Tab page 2', 317 \ '> Xtab2'], a, msg) 318 redraw 319 320 " Click in tab2 and drag it to tab1. 321 " Check getcharmod() to verify that click is not 322 " interpreted as a spurious double-click. 323 call MouseLeftClick(row, 10) 324 call assert_equal(0, getcharmod(), msg) 325 for col in [9, 8, 7, 6] 326 call MouseLeftDrag(row, col) 327 endfor 328 call MouseLeftRelease(row, col) 329 let a = split(execute(':tabs'), "\n") 330 call assert_equal(['Tab page 1', 331 \ '> Xtab2', 332 \ 'Tab page 2', 333 \ ' Xtab1'], a, msg) 334 335 " brief sleep to avoid causing a double-click 336 sleep 20m 337 %bwipe! 338 endfor 339 340 let &mouse = save_mouse 341 let &term = save_term 342 let &ttymouse = save_ttymouse 343 set mousetime& 344endfunc 345 346func Test_xterm_mouse_double_click_to_create_tab() 347 let save_mouse = &mouse 348 let save_term = &term 349 let save_ttymouse = &ttymouse 350 " Set 'mousetime' to a small value, so that double-click works but we don't 351 " have to wait long to avoid a triple-click. 352 set mouse=a term=xterm mousetime=100 353 let row = 1 354 let col = 10 355 356 for ttymouse_val in ['xterm2', 'sgr'] 357 let msg = 'ttymouse=' .. ttymouse_val 358 exe 'set ttymouse=' . ttymouse_val 359 e Xtab1 360 tabnew Xtab2 361 362 let a = split(execute(':tabs'), "\n") 363 call assert_equal(['Tab page 1', 364 \ ' Xtab1', 365 \ 'Tab page 2', 366 \ '> Xtab2'], a, msg) 367 368 redraw 369 call MouseLeftClick(row, col) 370 " Check getcharmod() to verify that first click is not 371 " interpreted as a spurious double-click. 372 call assert_equal(0, getcharmod(), msg) 373 call MouseLeftRelease(row, col) 374 call MouseLeftClick(row, col) 375 call assert_equal(32, getcharmod(), msg) " double-click 376 call MouseLeftRelease(row, col) 377 let a = split(execute(':tabs'), "\n") 378 call assert_equal(['Tab page 1', 379 \ ' Xtab1', 380 \ 'Tab page 2', 381 \ '> [No Name]', 382 \ 'Tab page 3', 383 \ ' Xtab2'], a, msg) 384 385 if ttymouse_val !=# 'sgr' 386 " We need to sleep, or else MouseLeftClick() in next loop 387 " iteration will be interpreted as a spurious triple-click. 388 sleep 100m 389 endif 390 %bwipe! 391 endfor 392 393 let &mouse = save_mouse 394 let &term = save_term 395 let &ttymouse = save_ttymouse 396 set mousetime& 397endfunc 398 399func Test_xterm_mouse_click_in_fold_columns() 400 new 401 let save_mouse = &mouse 402 let save_term = &term 403 let save_ttymouse = &ttymouse 404 let save_foldcolumn = &foldcolumn 405 set mouse=a term=xterm foldcolumn=3 ttymouse=xterm2 406 407 " Create 2 nested folds. 408 call setline(1, range(1, 7)) 409 2,6fold 410 norm! zR 411 4,5fold 412 call assert_equal([-1, -1, -1, 4, 4, -1, -1], 413 \ map(range(1, 7), 'foldclosed(v:val)')) 414 415 " Click in "+" of inner fold in foldcolumn should open it. 416 redraw 417 let row = 4 418 let col = 2 419 call MouseLeftClick(row, col) 420 call MouseLeftRelease(row, col) 421 call assert_equal([-1, -1, -1, -1, -1, -1, -1], 422 \ map(range(1, 7), 'foldclosed(v:val)')) 423 424 " Click in "-" of outer fold in foldcolumn should close it. 425 redraw 426 let row = 2 427 let col = 1 428 call MouseLeftClick(row, col) 429 call MouseLeftRelease(row, col) 430 call assert_equal([-1, 2, 2, 2, 2, 2, -1], 431 \ map(range(1, 7), 'foldclosed(v:val)')) 432 norm! zR 433 434 " Click in "|" of inner fold in foldcolumn should close it. 435 redraw 436 let row = 5 437 let col = 2 438 call MouseLeftClick(row, col) 439 call MouseLeftRelease(row, col) 440 call assert_equal([-1, -1, -1, 4, 4, -1, -1], 441 \ map(range(1, 7), 'foldclosed(v:val)')) 442 443 let &foldcolumn = save_foldcolumn 444 let &ttymouse = save_ttymouse 445 let &term = save_term 446 let &mouse = save_mouse 447 bwipe! 448endfunc 449