@@ -389,7 +389,7 @@ func Test_set_guifont()
389389 endif
390390
391391 " This only works if 'renderoptions' exists and does not work for Windows XP
392- " and older.
392+ " and older.
393393 if exists (' +renderoptions' ) && windowsversion () !~ ' ^[345]\.'
394394 " doing this four times used to cause a crash
395395 set renderoptions = type :directx
@@ -875,4 +875,226 @@ func Test_gui_recursive_mapping()
875875 nunmap <C-W> a
876876endfunc
877877
878+ " Test GUI mouse events
879+ func Test_gui_mouse_event ()
880+ set mousemodel = extend
881+ call test_override (' no_query_mouse' , 1 )
882+ new
883+ call setline (1 , [' one two three' , ' four five six' ])
884+
885+ " place the cursor using left click
886+ call cursor (1 , 1 )
887+ call test_gui_mouse_event (0 , 2 , 4 , 0 , 0 )
888+ call test_gui_mouse_event (3 , 2 , 4 , 0 , 0 )
889+ call feedkeys (" \<Esc> " , ' Lx!' )
890+ call assert_equal ([0 , 2 , 4 , 0 ], getpos (' .' ))
891+
892+ " select and yank a word
893+ let @" = ' '
894+ call test_gui_mouse_event (0 , 1 , 9 , 0 , 0 )
895+ call test_gui_mouse_event (0 , 1 , 9 , 1 , 0 )
896+ call test_gui_mouse_event (3 , 1 , 9 , 0 , 0 )
897+ call feedkeys (" y" , ' Lx!' )
898+ call assert_equal (' three' , @" )
899+
900+ " create visual selection using right click
901+ let @" = ' '
902+ call test_gui_mouse_event (0 , 2 , 6 , 0 , 0 )
903+ call test_gui_mouse_event (3 , 2 , 6 , 0 , 0 )
904+ call test_gui_mouse_event (2 , 2 , 13 , 0 , 0 )
905+ call test_gui_mouse_event (3 , 2 , 13 , 0 , 0 )
906+ call feedkeys (" y" , ' Lx!' )
907+ call assert_equal (' five six' , @" )
908+
909+ " paste using middle mouse button
910+ let @* = ' abc '
911+ call feedkeys (' ""' , ' Lx!' )
912+ call test_gui_mouse_event (1 , 1 , 9 , 0 , 0 )
913+ call test_gui_mouse_event (3 , 1 , 9 , 0 , 0 )
914+ call feedkeys (" \<Esc> " , ' Lx!' )
915+ call assert_equal ([' one two abc three' , ' four five six' ], getline (1 , ' $' ))
916+
917+ " extend visual selection using right click in visual mode
918+ let @" = ' '
919+ call cursor (1 , 1 )
920+ call feedkeys (' v' , ' Lx!' )
921+ call test_gui_mouse_event (2 , 1 , 17 , 0 , 0 )
922+ call test_gui_mouse_event (3 , 1 , 17 , 0 , 0 )
923+ call feedkeys (" y" , ' Lx!' )
924+ call assert_equal (' one two abc three' , @" )
925+
926+ " extend visual selection using mouse drag
927+ let @" = ' '
928+ call cursor (1 , 1 )
929+ call test_gui_mouse_event (0 , 2 , 1 , 0 , 0 )
930+ call test_gui_mouse_event (0x43 , 2 , 9 , 0 , 0 )
931+ call test_gui_mouse_event (0x3 , 2 , 9 , 0 , 0 )
932+ call feedkeys (" y" , ' Lx!' )
933+ call assert_equal (' four five' , @" )
934+
935+ " select text by moving the mouse
936+ let @" = ' '
937+ call cursor (1 , 1 )
938+ redraw !
939+ call test_gui_mouse_event (0 , 1 , 4 , 0 , 0 )
940+ call test_gui_mouse_event (0x700 , 1 , 9 , 0 , 0 )
941+ call test_gui_mouse_event (0x700 , 1 , 13 , 0 , 0 )
942+ call test_gui_mouse_event (0x3 , 1 , 13 , 0 , 0 )
943+ call feedkeys (" y" , ' Lx!' )
944+ call assert_equal (' two abc t' , @" )
945+
946+ " Using mouse in insert mode
947+ call cursor (1 , 1 )
948+ call feedkeys (' i' , ' t' )
949+ call test_gui_mouse_event (0 , 2 , 11 , 0 , 0 )
950+ call test_gui_mouse_event (3 , 2 , 11 , 0 , 0 )
951+ call feedkeys (" po\<Esc> " , ' Lx!' )
952+ call assert_equal ([' one two abc three' , ' four five posix' ], getline (1 , ' $' ))
953+
954+ % d _
955+ call setline (1 , range (1 , 100 ))
956+ " scroll up
957+ call test_gui_mouse_event (0x200 , 2 , 1 , 0 , 0 )
958+ call test_gui_mouse_event (0x200 , 2 , 1 , 0 , 0 )
959+ call test_gui_mouse_event (0x200 , 2 , 1 , 0 , 0 )
960+ call feedkeys (" H" , ' Lx!' )
961+ call assert_equal (10 , line (' .' ))
962+
963+ " scroll down
964+ call test_gui_mouse_event (0x100 , 2 , 1 , 0 , 0 )
965+ call test_gui_mouse_event (0x100 , 2 , 1 , 0 , 0 )
966+ call feedkeys (" H" , ' Lx!' )
967+ call assert_equal (4 , line (' .' ))
968+
969+ % d _
970+ set nowrap
971+ call setline (1 , range (10 )- >join (' ' )- >repeat (10 ))
972+ " scroll left
973+ call test_gui_mouse_event (0x500 , 1 , 5 , 0 , 0 )
974+ call test_gui_mouse_event (0x500 , 1 , 10 , 0 , 0 )
975+ call test_gui_mouse_event (0x500 , 1 , 15 , 0 , 0 )
976+ call feedkeys (' g0' , ' Lx!' )
977+ call assert_equal (19 , col (' .' ))
978+
979+ " scroll right
980+ call test_gui_mouse_event (0x600 , 1 , 15 , 0 , 0 )
981+ call test_gui_mouse_event (0x600 , 1 , 10 , 0 , 0 )
982+ call feedkeys (' g0' , ' Lx!' )
983+ call assert_equal (7 , col (' .' ))
984+ set wrap &
985+
986+ % d _
987+ call setline (1 , repeat ([repeat (' a' , 60 )], 10 ))
988+
989+ " record various mouse events
990+ let mouseEventNames = [
991+ \ ' LeftMouse' , ' LeftRelease' , ' 2-LeftMouse' , ' 3-LeftMouse' ,
992+ \ ' S-LeftMouse' , ' A-LeftMouse' , ' C-LeftMouse' , ' MiddleMouse' ,
993+ \ ' MiddleRelease' , ' 2-MiddleMouse' , ' 3-MiddleMouse' ,
994+ \ ' S-MiddleMouse' , ' A-MiddleMouse' , ' C-MiddleMouse' ,
995+ \ ' RightMouse' , ' RightRelease' , ' 2-RightMouse' ,
996+ \ ' 3-RightMouse' , ' S-RightMouse' , ' A-RightMouse' , ' C-RightMouse' ,
997+ \ ' X1Mouse' , ' S-X1Mouse' , ' A-X1Mouse' , ' C-X1Mouse' , ' X2Mouse' ,
998+ \ ' S-X2Mouse' , ' A-X2Mouse' , ' C-X2Mouse'
999+ \ ]
1000+ let mouseEventCodes = map (copy (mouseEventNames), " '<' .. v:val .. '>'" )
1001+ let g: events = []
1002+ for e in mouseEventCodes
1003+ exe ' nnoremap ' .. e .. ' <Cmd>call add(g:events, "' ..
1004+ \ substitute (e , ' [<>]' , ' ' , ' g' ) .. ' ")<CR>'
1005+ endfor
1006+
1007+ " Test various mouse buttons (0 - Left, 1 - Middle, 2 - Right, 0x300 - X1,
1008+ " 0x300- X2)
1009+ for button in [0 , 1 , 2 , 0x300 , 0x400 ]
1010+ " Single click
1011+ call test_gui_mouse_event (button, 2 , 5 , 0 , 0 )
1012+ call test_gui_mouse_event (3 , 2 , 5 , 0 , 0 )
1013+
1014+ " Double/Triple click is supported by only the Left/Middle/Right mouse
1015+ " buttons
1016+ if button <= 2
1017+ " Double Click
1018+ call test_gui_mouse_event (button, 2 , 5 , 0 , 0 )
1019+ call test_gui_mouse_event (button, 2 , 5 , 1 , 0 )
1020+ call test_gui_mouse_event (3 , 2 , 5 , 0 , 0 )
1021+
1022+ " Triple Click
1023+ call test_gui_mouse_event (button, 2 , 5 , 0 , 0 )
1024+ call test_gui_mouse_event (button, 2 , 5 , 1 , 0 )
1025+ call test_gui_mouse_event (button, 2 , 5 , 1 , 0 )
1026+ call test_gui_mouse_event (3 , 2 , 5 , 0 , 0 )
1027+ endif
1028+
1029+ " Shift click
1030+ call test_gui_mouse_event (button, 3 , 7 , 0 , 4 )
1031+ call test_gui_mouse_event (3 , 3 , 7 , 0 , 4 )
1032+
1033+ " Alt click
1034+ call test_gui_mouse_event (button, 3 , 7 , 0 , 8 )
1035+ call test_gui_mouse_event (3 , 3 , 7 , 0 , 8 )
1036+
1037+ " Ctrl click
1038+ call test_gui_mouse_event (button, 3 , 7 , 0 , 16 )
1039+ call test_gui_mouse_event (3 , 3 , 7 , 0 , 16 )
1040+
1041+ call feedkeys (" \<Esc> " , ' Lx!' )
1042+ endfor
1043+
1044+ call assert_equal ([' LeftMouse' , ' LeftRelease' , ' LeftMouse' , ' 2-LeftMouse' ,
1045+ \ ' LeftMouse' , ' 2-LeftMouse' , ' 3-LeftMouse' , ' S-LeftMouse' ,
1046+ \ ' A-LeftMouse' , ' C-LeftMouse' , ' MiddleMouse' , ' MiddleRelease' ,
1047+ \ ' MiddleMouse' , ' 2-MiddleMouse' , ' MiddleMouse' , ' 2-MiddleMouse' ,
1048+ \ ' 3-MiddleMouse' , ' S-MiddleMouse' , ' A-MiddleMouse' , ' C-MiddleMouse' ,
1049+ \ ' RightMouse' , ' RightRelease' , ' RightMouse' , ' 2-RightMouse' ,
1050+ \ ' RightMouse' , ' 2-RightMouse' , ' 3-RightMouse' , ' S-RightMouse' ,
1051+ \ ' A-RightMouse' , ' C-RightMouse' , ' X1Mouse' , ' S-X1Mouse' , ' A-X1Mouse' ,
1052+ \ ' C-X1Mouse' , ' X2Mouse' , ' S-X2Mouse' , ' A-X2Mouse' , ' C-X2Mouse' ],
1053+ \ g: events )
1054+
1055+ for e in mouseEventCodes
1056+ exe ' nunmap ' .. e
1057+ endfor
1058+
1059+ " modeless selection
1060+ set mouse =
1061+ let save_guioptions = &guioptions
1062+ set guioptions += A
1063+ % d _
1064+ call setline (1 , [' one two three' , ' four five sixteen' ])
1065+ call cursor (1 , 1 )
1066+ redraw !
1067+ " Double click should select the word and copy it to clipboard
1068+ let @* = ' '
1069+ call test_gui_mouse_event (0 , 2 , 11 , 0 , 0 )
1070+ call test_gui_mouse_event (0 , 2 , 11 , 1 , 0 )
1071+ call test_gui_mouse_event (3 , 2 , 11 , 0 , 0 )
1072+ call feedkeys (" \<Esc> " , ' Lx!' )
1073+ call assert_equal ([0 , 1 , 1 , 0 ], getpos (' .' ))
1074+ call assert_equal (' sixteen' , @* )
1075+ " Right click should extend the selection from cursor
1076+ call cursor (1 , 6 )
1077+ redraw !
1078+ let @* = ' '
1079+ call test_gui_mouse_event (2 , 1 , 11 , 0 , 0 )
1080+ call test_gui_mouse_event (3 , 1 , 11 , 0 , 0 )
1081+ call feedkeys (" \<Esc> " , ' Lx!' )
1082+ call assert_equal ([0 , 1 , 6 , 0 ], getpos (' .' ))
1083+ call assert_equal (' wo thr' , @* )
1084+ " Middle click should paste the clipboard contents
1085+ call cursor (2 , 1 )
1086+ redraw !
1087+ call test_gui_mouse_event (1 , 1 , 11 , 0 , 0 )
1088+ call test_gui_mouse_event (3 , 1 , 11 , 0 , 0 )
1089+ call feedkeys (" \<Esc> " , ' Lx!' )
1090+ call assert_equal ([0 , 2 , 7 , 0 ], getpos (' .' ))
1091+ call assert_equal (' wo thrfour five sixteen' , getline (2 ))
1092+ set mouse &
1093+ let &guioptions = save_guioptions
1094+
1095+ bw !
1096+ call test_override (' no_query_mouse' , 0 )
1097+ set mousemodel &
1098+ endfunc
1099+
8781100" vim: shiftwidth = 2 sts = 2 expandtab
0 commit comments