Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 1 | " Test MS-Windows input event handling. |
| 2 | " Most of this works the same in Windows GUI as well as Windows console. |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 3 | |
| 4 | source check.vim |
| 5 | CheckMSWindows |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 6 | |
| 7 | source mouse.vim |
| 8 | |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 9 | " Helper function for sending a grouped sequence of low level key presses |
| 10 | " The modifer key(s) can be included as VK Key Codes in the sequence |
| 11 | " Keydown events will be sent, to to the end of the group, then keyup events |
| 12 | " will be sent in reverse order to release the keys. |
| 13 | func SendKeyGroup(keygroup) |
| 14 | for k in a:keygroup |
| 15 | call test_mswin_event("key", {'event': "keydown", 'keycode': k}) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 16 | endfor |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 17 | for k in reverse(copy(a:keygroup)) |
| 18 | call test_mswin_event("key", {'event': "keyup", 'keycode': k}) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 19 | endfor |
| 20 | endfunc |
| 21 | |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 22 | " Send individual key press and release events. |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 23 | " the modifers for the key press can be specified in the modifiers arg. |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 24 | func SendKeyWithModifiers(key, modifiers) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 25 | let args = { } |
| 26 | let args.keycode = a:key |
| 27 | let args.modifiers = a:modifiers |
| 28 | let args.event = "keydown" |
| 29 | call test_mswin_event("key", args) |
| 30 | let args.event = "keyup" |
| 31 | call test_mswin_event("key", args) |
| 32 | unlet args |
| 33 | endfunc |
| 34 | |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 35 | " Send an individual key press, without modifiers. |
| 36 | func SendKey(key) |
| 37 | call SendKeyWithModifiers(a:key, 0) |
| 38 | endfunc |
| 39 | |
| 40 | " Send a string of individual key-press events, without modifiers. |
| 41 | func SendKeyStr(keystring) |
| 42 | for k in a:keystring |
| 43 | call SendKey(k) |
| 44 | endfor |
| 45 | endfunc |
| 46 | |
| 47 | " This tells Vim to execute the buffered keys as user commands, |
| 48 | " ie. same as feekdeys with mode X would do. |
| 49 | func ExecuteBufferedKeys() |
| 50 | if has('gui_running') |
| 51 | call feedkeys("\<Esc>", 'Lx!') |
| 52 | else |
| 53 | call test_mswin_event("key", {'execute': v:true}) |
| 54 | endif |
| 55 | endfunc |
| 56 | |
| 57 | |
| 58 | let s:VK = { |
| 59 | \ 'ENTER' : 0x0D, |
| 60 | \ 'SPACE' : 0x20, |
| 61 | \ 'SHIFT' : 0x10, |
| 62 | \ 'LSHIFT' : 0xA0, |
| 63 | \ 'RSHIFT' : 0xA1, |
| 64 | \ 'CONTROL' : 0x11, |
| 65 | \ 'LCONTROL' : 0xA2, |
| 66 | \ 'RCONTROL' : 0xA3, |
| 67 | \ 'MENU' : 0x12, |
| 68 | \ 'ALT' : 0x12, |
| 69 | \ 'LMENU' : 0xA4, |
| 70 | \ 'LALT' : 0xA4, |
| 71 | \ 'RMENU' : 0xA5, |
| 72 | \ 'RALT' : 0xA5, |
| 73 | \ 'OEM_1' : 0xBA, |
| 74 | \ 'OEM_2' : 0xBF, |
| 75 | \ 'OEM_3' : 0xC0, |
| 76 | \ 'OEM_4' : 0xDB, |
| 77 | \ 'OEM_5' : 0xDC, |
| 78 | \ 'OEM_6' : 0xDD, |
| 79 | \ 'OEM_7' : 0xDE, |
| 80 | \ 'OEM_PLUS' : 0xBB, |
| 81 | \ 'OEM_COMMA' : 0xBC, |
| 82 | \ 'OEM_MINUS' : 0xBD, |
| 83 | \ 'OEM_PERIOD' : 0xBE, |
| 84 | \ 'PRIOR' : 0x21, |
| 85 | \ 'NEXT' : 0x22, |
| 86 | \ 'END' : 0x23, |
| 87 | \ 'HOME' : 0x24, |
| 88 | \ 'LEFT' : 0x25, |
| 89 | \ 'UP' : 0x26, |
| 90 | \ 'RIGHT' : 0x27, |
| 91 | \ 'DOWN' : 0x28, |
| 92 | \ 'KEY_0' : 0x30, |
| 93 | \ 'KEY_1' : 0x31, |
| 94 | \ 'KEY_2' : 0x32, |
| 95 | \ 'KEY_3' : 0x33, |
| 96 | \ 'KEY_4' : 0x34, |
| 97 | \ 'KEY_5' : 0x35, |
| 98 | \ 'KEY_6' : 0x36, |
| 99 | \ 'KEY_7' : 0x37, |
| 100 | \ 'KEY_8' : 0x38, |
| 101 | \ 'KEY_9' : 0x39, |
| 102 | \ 'KEY_A' : 0x41, |
| 103 | \ 'KEY_B' : 0x42, |
| 104 | \ 'KEY_C' : 0x43, |
| 105 | \ 'KEY_D' : 0x44, |
| 106 | \ 'KEY_E' : 0x45, |
| 107 | \ 'KEY_F' : 0x46, |
| 108 | \ 'KEY_G' : 0x47, |
| 109 | \ 'KEY_H' : 0x48, |
| 110 | \ 'KEY_I' : 0x49, |
| 111 | \ 'KEY_J' : 0x4A, |
| 112 | \ 'KEY_K' : 0x4B, |
| 113 | \ 'KEY_L' : 0x4C, |
| 114 | \ 'KEY_M' : 0x4D, |
| 115 | \ 'KEY_N' : 0x4E, |
| 116 | \ 'KEY_O' : 0x4F, |
| 117 | \ 'KEY_P' : 0x50, |
| 118 | \ 'KEY_Q' : 0x51, |
| 119 | \ 'KEY_R' : 0x52, |
| 120 | \ 'KEY_S' : 0x53, |
| 121 | \ 'KEY_T' : 0x54, |
| 122 | \ 'KEY_U' : 0x55, |
| 123 | \ 'KEY_V' : 0x56, |
| 124 | \ 'KEY_W' : 0x57, |
| 125 | \ 'KEY_X' : 0x58, |
| 126 | \ 'KEY_Y' : 0x59, |
| 127 | \ 'KEY_Z' : 0x5A, |
| 128 | \ 'NUMPAD0' : 0x60, |
| 129 | \ 'NUMPAD1' : 0x61, |
| 130 | \ 'NUMPAD2' : 0x62, |
| 131 | \ 'NUMPAD3' : 0x63, |
| 132 | \ 'NUMPAD4' : 0x64, |
| 133 | \ 'NUMPAD5' : 0x65, |
| 134 | \ 'NUMPAD6' : 0x66, |
| 135 | \ 'NUMPAD7' : 0x67, |
| 136 | \ 'NUMPAD8' : 0x68, |
| 137 | \ 'NUMPAD9' : 0x69, |
| 138 | \ 'MULTIPLY' : 0x6A, |
| 139 | \ 'ADD' : 0x6B, |
| 140 | \ 'SUBTRACT' : 0x6D, |
| 141 | \ 'F1' : 0x70, |
| 142 | \ 'F2' : 0x71, |
| 143 | \ 'F3' : 0x72, |
| 144 | \ 'F4' : 0x73, |
| 145 | \ 'F5' : 0x74, |
| 146 | \ 'F6' : 0x75, |
| 147 | \ 'F7' : 0x76, |
| 148 | \ 'F8' : 0x77, |
| 149 | \ 'F9' : 0x78, |
| 150 | \ 'F10' : 0x79, |
| 151 | \ 'F11' : 0x7A, |
| 152 | \ 'F12' : 0x7B, |
| 153 | \ 'DELETE' : 0x2E, |
| 154 | \ 'BACK' : 0x08, |
| 155 | \ 'ESCAPE' : 0x1B |
| 156 | \ } |
| 157 | |
| 158 | let s:vim_MOD_MASK_SHIFT = 0x02 |
| 159 | let s:vim_MOD_MASK_CTRL = 0x04 |
| 160 | let s:vim_MOD_MASK_ALT = 0x08 |
| 161 | |
| 162 | let s:vim_key_modifiers = [ |
| 163 | \ ["", 0, []], |
| 164 | \ ["S-", 2, [s:VK.SHIFT]], |
| 165 | \ ["C-", 4, [s:VK.CONTROL]], |
| 166 | \ ["C-S-", 6, [s:VK.CONTROL, s:VK.SHIFT]], |
| 167 | \ ["A-", 8, [s:VK.MENU]], |
| 168 | \ ["A-S-", 10, [s:VK.MENU, s:VK.SHIFT]], |
| 169 | \ ["A-C-", 12, [s:VK.MENU, s:VK.CONTROL]], |
| 170 | \ ["A-C-S-", 14, [s:VK.MENU, s:VK.CONTROL, s:VK.SHIFT]], |
| 171 | \] |
| 172 | |
| 173 | " Assuming Standard US PC Keyboard layout |
| 174 | let s:test_ascii_key_chars = [ |
| 175 | \ [[s:VK.SPACE], ' '], |
| 176 | \ [[s:VK.OEM_1], ';'], |
| 177 | \ [[s:VK.OEM_2], '/'], |
| 178 | \ [[s:VK.OEM_3], '`'], |
| 179 | \ [[s:VK.OEM_4], '['], |
| 180 | \ [[s:VK.OEM_5], '\'], |
| 181 | \ [[s:VK.OEM_6], ']'], |
| 182 | \ [[s:VK.OEM_7], ''''], |
| 183 | \ [[s:VK.OEM_PLUS], '='], |
| 184 | \ [[s:VK.OEM_COMMA], ','], |
| 185 | \ [[s:VK.OEM_MINUS], '-'], |
| 186 | \ [[s:VK.OEM_PERIOD], '.'], |
| 187 | \ [[s:VK.SHIFT, s:VK.OEM_1], ':'], |
| 188 | \ [[s:VK.SHIFT, s:VK.OEM_2], '?'], |
| 189 | \ [[s:VK.SHIFT, s:VK.OEM_3], '~'], |
| 190 | \ [[s:VK.SHIFT, s:VK.OEM_4], '{'], |
| 191 | \ [[s:VK.SHIFT, s:VK.OEM_5], '|'], |
| 192 | \ [[s:VK.SHIFT, s:VK.OEM_6], '}'], |
| 193 | \ [[s:VK.SHIFT, s:VK.OEM_7], '"'], |
| 194 | \ [[s:VK.SHIFT, s:VK.OEM_PLUS], '+'], |
| 195 | \ [[s:VK.SHIFT, s:VK.OEM_COMMA], '<'], |
| 196 | \ [[s:VK.SHIFT, s:VK.OEM_MINUS], '_'], |
| 197 | \ [[s:VK.SHIFT, s:VK.OEM_PERIOD], '>'], |
| 198 | \ [[s:VK.KEY_1], '1'], |
| 199 | \ [[s:VK.KEY_2], '2'], |
| 200 | \ [[s:VK.KEY_3], '3'], |
| 201 | \ [[s:VK.KEY_4], '4'], |
| 202 | \ [[s:VK.KEY_5], '5'], |
| 203 | \ [[s:VK.KEY_6], '6'], |
| 204 | \ [[s:VK.KEY_7], '7'], |
| 205 | \ [[s:VK.KEY_8], '8'], |
| 206 | \ [[s:VK.KEY_9], '9'], |
| 207 | \ [[s:VK.KEY_0], '0'], |
| 208 | \ [[s:VK.SHIFT, s:VK.KEY_1], '!'], |
| 209 | \ [[s:VK.SHIFT, s:VK.KEY_2], '@'], |
| 210 | \ [[s:VK.SHIFT, s:VK.KEY_3], '#'], |
| 211 | \ [[s:VK.SHIFT, s:VK.KEY_4], '$'], |
| 212 | \ [[s:VK.SHIFT, s:VK.KEY_5], '%'], |
| 213 | \ [[s:VK.SHIFT, s:VK.KEY_6], '^'], |
| 214 | \ [[s:VK.SHIFT, s:VK.KEY_7], '&'], |
| 215 | \ [[s:VK.SHIFT, s:VK.KEY_8], '*'], |
| 216 | \ [[s:VK.SHIFT, s:VK.KEY_9], '('], |
| 217 | \ [[s:VK.SHIFT, s:VK.KEY_0], ')'], |
| 218 | \ [[s:VK.KEY_A], 'a'], |
| 219 | \ [[s:VK.KEY_B], 'b'], |
| 220 | \ [[s:VK.KEY_C], 'c'], |
| 221 | \ [[s:VK.KEY_D], 'd'], |
| 222 | \ [[s:VK.KEY_E], 'e'], |
| 223 | \ [[s:VK.KEY_F], 'f'], |
| 224 | \ [[s:VK.KEY_G], 'g'], |
| 225 | \ [[s:VK.KEY_H], 'h'], |
| 226 | \ [[s:VK.KEY_I], 'i'], |
| 227 | \ [[s:VK.KEY_J], 'j'], |
| 228 | \ [[s:VK.KEY_K], 'k'], |
| 229 | \ [[s:VK.KEY_L], 'l'], |
| 230 | \ [[s:VK.KEY_M], 'm'], |
| 231 | \ [[s:VK.KEY_N], 'n'], |
| 232 | \ [[s:VK.KEY_O], 'o'], |
| 233 | \ [[s:VK.KEY_P], 'p'], |
| 234 | \ [[s:VK.KEY_Q], 'q'], |
| 235 | \ [[s:VK.KEY_R], 'r'], |
| 236 | \ [[s:VK.KEY_S], 's'], |
| 237 | \ [[s:VK.KEY_T], 't'], |
| 238 | \ [[s:VK.KEY_U], 'u'], |
| 239 | \ [[s:VK.KEY_V], 'v'], |
| 240 | \ [[s:VK.KEY_W], 'w'], |
| 241 | \ [[s:VK.KEY_X], 'x'], |
| 242 | \ [[s:VK.KEY_Y], 'y'], |
| 243 | \ [[s:VK.KEY_Z], 'z'], |
| 244 | \ [[s:VK.SHIFT, s:VK.KEY_A], 'A'], |
| 245 | \ [[s:VK.SHIFT, s:VK.KEY_B], 'B'], |
| 246 | \ [[s:VK.SHIFT, s:VK.KEY_C], 'C'], |
| 247 | \ [[s:VK.SHIFT, s:VK.KEY_D], 'D'], |
| 248 | \ [[s:VK.SHIFT, s:VK.KEY_E], 'E'], |
| 249 | \ [[s:VK.SHIFT, s:VK.KEY_F], 'F'], |
| 250 | \ [[s:VK.SHIFT, s:VK.KEY_G], 'G'], |
| 251 | \ [[s:VK.SHIFT, s:VK.KEY_H], 'H'], |
| 252 | \ [[s:VK.SHIFT, s:VK.KEY_I], 'I'], |
| 253 | \ [[s:VK.SHIFT, s:VK.KEY_J], 'J'], |
| 254 | \ [[s:VK.SHIFT, s:VK.KEY_K], 'K'], |
| 255 | \ [[s:VK.SHIFT, s:VK.KEY_L], 'L'], |
| 256 | \ [[s:VK.SHIFT, s:VK.KEY_M], 'M'], |
| 257 | \ [[s:VK.SHIFT, s:VK.KEY_N], 'N'], |
| 258 | \ [[s:VK.SHIFT, s:VK.KEY_O], 'O'], |
| 259 | \ [[s:VK.SHIFT, s:VK.KEY_P], 'P'], |
| 260 | \ [[s:VK.SHIFT, s:VK.KEY_Q], 'Q'], |
| 261 | \ [[s:VK.SHIFT, s:VK.KEY_R], 'R'], |
| 262 | \ [[s:VK.SHIFT, s:VK.KEY_S], 'S'], |
| 263 | \ [[s:VK.SHIFT, s:VK.KEY_T], 'T'], |
| 264 | \ [[s:VK.SHIFT, s:VK.KEY_U], 'U'], |
| 265 | \ [[s:VK.SHIFT, s:VK.KEY_V], 'V'], |
| 266 | \ [[s:VK.SHIFT, s:VK.KEY_W], 'W'], |
| 267 | \ [[s:VK.SHIFT, s:VK.KEY_X], 'X'], |
| 268 | \ [[s:VK.SHIFT, s:VK.KEY_Y], 'Y'], |
| 269 | \ [[s:VK.SHIFT, s:VK.KEY_Z], 'Z'], |
| 270 | \ [[s:VK.CONTROL, s:VK.KEY_A], 0x01], |
| 271 | \ [[s:VK.CONTROL, s:VK.KEY_B], 0x02], |
| 272 | \ [[s:VK.CONTROL, s:VK.KEY_C], 0x03], |
| 273 | \ [[s:VK.CONTROL, s:VK.KEY_D], 0x04], |
| 274 | \ [[s:VK.CONTROL, s:VK.KEY_E], 0x05], |
| 275 | \ [[s:VK.CONTROL, s:VK.KEY_F], 0x06], |
| 276 | \ [[s:VK.CONTROL, s:VK.KEY_G], 0x07], |
| 277 | \ [[s:VK.CONTROL, s:VK.KEY_H], 0x08], |
| 278 | \ [[s:VK.CONTROL, s:VK.KEY_I], 0x09], |
| 279 | \ [[s:VK.CONTROL, s:VK.KEY_J], 0x0A], |
| 280 | \ [[s:VK.CONTROL, s:VK.KEY_K], 0x0B], |
| 281 | \ [[s:VK.CONTROL, s:VK.KEY_L], 0x0C], |
| 282 | \ [[s:VK.CONTROL, s:VK.KEY_M], 0x0D], |
| 283 | \ [[s:VK.CONTROL, s:VK.KEY_N], 0x0E], |
| 284 | \ [[s:VK.CONTROL, s:VK.KEY_O], 0x0F], |
| 285 | \ [[s:VK.CONTROL, s:VK.KEY_P], 0x10], |
| 286 | \ [[s:VK.CONTROL, s:VK.KEY_Q], 0x11], |
| 287 | \ [[s:VK.CONTROL, s:VK.KEY_R], 0x12], |
| 288 | \ [[s:VK.CONTROL, s:VK.KEY_S], 0x13], |
| 289 | \ [[s:VK.CONTROL, s:VK.KEY_T], 0x14], |
| 290 | \ [[s:VK.CONTROL, s:VK.KEY_U], 0x15], |
| 291 | \ [[s:VK.CONTROL, s:VK.KEY_V], 0x16], |
| 292 | \ [[s:VK.CONTROL, s:VK.KEY_W], 0x17], |
| 293 | \ [[s:VK.CONTROL, s:VK.KEY_X], 0x18], |
| 294 | \ [[s:VK.CONTROL, s:VK.KEY_Y], 0x19], |
| 295 | \ [[s:VK.CONTROL, s:VK.KEY_Z], 0x1A], |
| 296 | \ [[s:VK.CONTROL, s:VK.OEM_4], 0x1B], |
| 297 | \ [[s:VK.CONTROL, s:VK.OEM_5], 0x1C], |
| 298 | \ [[s:VK.CONTROL, s:VK.OEM_6], 0x1D], |
| 299 | \ ] |
| 300 | " The following non-printable ascii chars fail in the GUI, but work in the |
| 301 | " console. 0x1e [^^] Record separator (RS), and 0x1f [^_] Unit separator (US) |
| 302 | " \ [[s:VK.CONTROL, s:VK.SHIFT, s:VK.KEY_6], 0x1E], |
| 303 | " \ [[s:VK.CONTROL, s:VK.SHIFT, s:VK.OEM_MINUS], 0x1F], |
| 304 | |
| 305 | let s:test_extra_key_chars = [ |
| 306 | \ [[s:VK.ALT, s:VK.KEY_1], '±'], |
| 307 | \ [[s:VK.ALT, s:VK.KEY_2], '²'], |
| 308 | \ [[s:VK.ALT, s:VK.KEY_3], '³'], |
| 309 | \ [[s:VK.ALT, s:VK.KEY_4], '´'], |
| 310 | \ [[s:VK.ALT, s:VK.KEY_5], 'µ'], |
| 311 | \ [[s:VK.ALT, s:VK.KEY_6], '¶'], |
| 312 | \ [[s:VK.ALT, s:VK.KEY_7], '·'], |
| 313 | \ [[s:VK.ALT, s:VK.KEY_8], '¸'], |
| 314 | \ [[s:VK.ALT, s:VK.KEY_9], '¹'], |
| 315 | \ [[s:VK.ALT, s:VK.KEY_0], '°'], |
| 316 | \ [[s:VK.ALT, s:VK.KEY_A], 'á'], |
| 317 | \ [[s:VK.ALT, s:VK.KEY_B], 'â'], |
| 318 | \ [[s:VK.ALT, s:VK.KEY_C], 'ã'], |
| 319 | \ [[s:VK.ALT, s:VK.KEY_D], 'ä'], |
| 320 | \ [[s:VK.ALT, s:VK.KEY_E], 'Ã¥'], |
| 321 | \ [[s:VK.ALT, s:VK.KEY_F], 'æ'], |
| 322 | \ [[s:VK.ALT, s:VK.KEY_G], 'ç'], |
| 323 | \ [[s:VK.ALT, s:VK.KEY_H], 'è'], |
| 324 | \ [[s:VK.ALT, s:VK.KEY_I], 'é'], |
| 325 | \ [[s:VK.ALT, s:VK.KEY_J], 'ê'], |
| 326 | \ [[s:VK.ALT, s:VK.KEY_K], 'ë'], |
| 327 | \ [[s:VK.ALT, s:VK.KEY_L], 'ì'], |
| 328 | \ [[s:VK.ALT, s:VK.KEY_M], 'Ã'], |
| 329 | \ [[s:VK.ALT, s:VK.KEY_N], 'î'], |
| 330 | \ [[s:VK.ALT, s:VK.KEY_O], 'ï'], |
| 331 | \ [[s:VK.ALT, s:VK.KEY_P], 'ð'], |
| 332 | \ [[s:VK.ALT, s:VK.KEY_Q], 'ñ'], |
| 333 | \ [[s:VK.ALT, s:VK.KEY_R], 'ò'], |
| 334 | \ [[s:VK.ALT, s:VK.KEY_S], 'ó'], |
| 335 | \ [[s:VK.ALT, s:VK.KEY_T], 'ô'], |
| 336 | \ [[s:VK.ALT, s:VK.KEY_U], 'õ'], |
| 337 | \ [[s:VK.ALT, s:VK.KEY_V], 'ö'], |
| 338 | \ [[s:VK.ALT, s:VK.KEY_W], '÷'], |
| 339 | \ [[s:VK.ALT, s:VK.KEY_X], 'ø'], |
| 340 | \ [[s:VK.ALT, s:VK.KEY_Y], 'ù'], |
| 341 | \ [[s:VK.ALT, s:VK.KEY_Z], 'ú'], |
| 342 | \ ] |
| 343 | |
| 344 | func s:LoopTestKeyArray(arr) |
| 345 | " flush out any garbage left in the buffer |
| 346 | while getchar(0) |
| 347 | endwhile |
| 348 | |
| 349 | for [kcodes, kstr] in a:arr |
| 350 | " Send as a sequence of key presses. |
| 351 | call SendKeyGroup(kcodes) |
| 352 | let ch = getcharstr(0) |
| 353 | " need to deal a bit differently with the non-printable ascii chars < 0x20 |
| 354 | if kstr < 0x20 && index([s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL], kcodes[0]) >= 0 |
| 355 | call assert_equal(nr2char(kstr), $"{ch}") |
| 356 | else |
| 357 | call assert_equal(kstr, $"{ch}") |
| 358 | endif |
| 359 | let mod_mask = getcharmod() |
| 360 | " the mod_mask is zero when no modifiers are used |
| 361 | " and when the virtual termcap maps the character |
| 362 | call assert_equal(0, mod_mask, $"key = {kstr}") |
| 363 | |
| 364 | " Send as a single key press with a modifers mask. |
| 365 | let modifiers = 0 |
| 366 | let key = kcodes[0] |
| 367 | for key in kcodes |
| 368 | if index([s:VK.SHIFT, s:VK.LSHIFT, s:VK.RSHIFT], key) >= 0 |
| 369 | let modifiers = modifiers + s:vim_MOD_MASK_SHIFT |
| 370 | endif |
| 371 | if index([s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL], key) >= 0 |
| 372 | let modifiers = modifiers + s:vim_MOD_MASK_CTRL |
| 373 | endif |
| 374 | if index([s:VK.ALT, s:VK.LALT, s:VK.RALT], key) >= 0 |
| 375 | let modifiers = modifiers + s:vim_MOD_MASK_ALT |
| 376 | endif |
| 377 | endfor |
| 378 | call SendKeyWithModifiers(key, modifiers) |
| 379 | let ch = getcharstr(0) |
| 380 | " need to deal a bit differently with the non-printable ascii chars < 0x20 |
| 381 | if kstr < 0x20 && index([s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL], kcodes[0]) >= 0 |
| 382 | call assert_equal(nr2char(kstr), $"{ch}") |
| 383 | else |
| 384 | call assert_equal(kstr, $"{ch}") |
| 385 | endif |
| 386 | let mod_mask = getcharmod() |
| 387 | " the mod_mask is zero when no modifiers are used |
| 388 | " and when the virtual termcap maps the character |
| 389 | call assert_equal(0, mod_mask, $"key = {kstr}") |
| 390 | endfor |
| 391 | |
| 392 | " flush out any garbage left in the buffer |
| 393 | while getchar(0) |
| 394 | endwhile |
| 395 | |
| 396 | endfunc |
| 397 | |
| 398 | " Test MS-Windows key events |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 399 | func Test_mswin_key_event() |
| 400 | CheckMSWindows |
| 401 | new |
| 402 | |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 403 | call s:LoopTestKeyArray(s:test_ascii_key_chars) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 404 | |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 405 | if !has('gui_running') |
| 406 | call s:LoopTestKeyArray(s:test_extra_key_chars) |
| 407 | endif |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 408 | |
| 409 | " Test keyboard codes for digits |
| 410 | " (0x30 - 0x39) : VK_0 - VK_9 are the same as ASCII '0' - '9' |
| 411 | for kc in range(48, 57) |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 412 | call SendKey(kc) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 413 | let ch = getcharstr(0) |
| 414 | call assert_equal(nr2char(kc), ch) |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 415 | call SendKeyWithModifiers(kc, 0) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 416 | let ch = getcharstr(0) |
| 417 | call assert_equal(nr2char(kc), ch) |
| 418 | endfor |
| 419 | |
| 420 | " Test keyboard codes for Alt-0 to Alt-9 |
| 421 | " Expect +128 from the digit char codes |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 422 | for modkey in [s:VK.ALT, s:VK.LALT, s:VK.RALT] |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 423 | for kc in range(48, 57) |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 424 | call SendKeyGroup([modkey, kc]) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 425 | let ch = getchar(0) |
| 426 | call assert_equal(kc+128, ch) |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 427 | call SendKeyWithModifiers(kc, s:vim_MOD_MASK_ALT) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 428 | let ch = getchar(0) |
| 429 | call assert_equal(kc+128, ch) |
| 430 | endfor |
| 431 | endfor |
| 432 | |
| 433 | " Test for lowercase 'a' to 'z', VK codes 65(0x41) - 90(0x5A) |
| 434 | " Note: VK_A-VK_Z virtual key codes coincide with uppercase ASCII codes A-Z. |
| 435 | " eg VK_A is 65, and the ASCII character code for uppercase 'A' is also 65. |
| 436 | " Caution: these are interpreted as lowercase when Shift is NOT pressed. |
| 437 | " eg, sending VK_A (65) 'A' Key code without shift modifier, will produce ASCII |
| 438 | " char 'a' (91) as the output. The ASCII codes for the lowercase letters are |
| 439 | " numbered 32 higher than their uppercase versions. |
| 440 | for kc in range(65, 90) |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 441 | call SendKey(kc) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 442 | let ch = getcharstr(0) |
| 443 | call assert_equal(nr2char(kc + 32), ch) |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 444 | call SendKeyWithModifiers(kc, 0) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 445 | let ch = getcharstr(0) |
| 446 | call assert_equal(nr2char(kc + 32), ch) |
| 447 | endfor |
| 448 | |
| 449 | " Test for Uppercase 'A' - 'Z' keys |
| 450 | " ie. with VK_SHIFT, expect the keycode = character code. |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 451 | for modkey in [s:VK.SHIFT, s:VK.LSHIFT, s:VK.RSHIFT] |
| 452 | for kc in range(65, 90) |
| 453 | call SendKeyGroup([modkey, kc]) |
| 454 | let ch = getcharstr(0) |
| 455 | call assert_equal(nr2char(kc), ch) |
| 456 | call SendKeyWithModifiers(kc, s:vim_MOD_MASK_SHIFT) |
| 457 | let ch = getcharstr(0) |
| 458 | call assert_equal(nr2char(kc), ch) |
| 459 | endfor |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 460 | endfor |
| 461 | |
| 462 | " Test for <Ctrl-A> to <Ctrl-Z> keys |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 463 | " Expect the unicode characters 0x01 to 0x1A |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 464 | for modkey in [s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL] |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 465 | for kc in range(65, 90) |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 466 | call SendKeyGroup([modkey, kc]) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 467 | let ch = getcharstr(0) |
| 468 | call assert_equal(nr2char(kc - 64), ch) |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 469 | call SendKeyWithModifiers(kc, s:vim_MOD_MASK_CTRL) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 470 | let ch = getcharstr(0) |
| 471 | call assert_equal(nr2char(kc - 64), ch) |
| 472 | endfor |
| 473 | endfor |
| 474 | |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 475 | " Windows intercepts some of these keys in the GUI. |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 476 | if !has("gui_running") |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 477 | " Test for <Alt-A> to <Alt-Z> keys |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 478 | " Expect the unicode characters 0xE1 to 0xFA |
| 479 | " ie. 160 higher than the lowercase equivalent |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 480 | for modkey in [s:VK.ALT, s:VK.LALT, s:VK.RALT] |
| 481 | for kc in range(65, 90) |
| 482 | call SendKeyGroup([modkey, kc]) |
| 483 | let ch = getchar(0) |
| 484 | call assert_equal(kc+160, ch) |
| 485 | call SendKeyWithModifiers(kc, s:vim_MOD_MASK_ALT) |
| 486 | let ch = getchar(0) |
| 487 | call assert_equal(kc+160, ch) |
| 488 | endfor |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 489 | endfor |
| 490 | endif |
| 491 | |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 492 | " Windows intercepts some of these keys in the GUI |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 493 | if !has("gui_running") |
| 494 | " Test for Function Keys 'F1' to 'F12' |
| 495 | for n in range(1, 12) |
| 496 | let kstr = $"F{n}" |
| 497 | let keycode = eval('"\<' .. kstr .. '>"') |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 498 | call SendKey(111+n) |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 499 | let ch = getcharstr(0) |
| 500 | call assert_equal(keycode, $"{ch}", $"key = <{kstr}>") |
| 501 | endfor |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 502 | " NOTE: mod + Fn Keys not working in CI Testing!? |
| 503 | " Test for Function Keys 'F1' to 'F12' |
| 504 | " VK codes 112(0x70) - 123(0x7B) |
| 505 | " With ALL permutatios of modifiers; Shift, Ctrl & Alt |
| 506 | for [mod_str, vim_mod_mask, mod_keycodes] in s:vim_key_modifiers |
| 507 | for n in range(1, 12) |
| 508 | let kstr = $"{mod_str}F{n}" |
| 509 | let keycode = eval('"\<' .. kstr .. '>"') |
| 510 | " call SendKeyGroup(mod_keycodes + [111+n]) |
| 511 | call SendKeyWithModifiers(111+n, vim_mod_mask) |
| 512 | let ch = getcharstr(0) |
| 513 | let mod_mask = getcharmod() |
| 514 | """""" call assert_equal(keycode, $"{ch}", $"key = {kstr}") |
| 515 | " workaround for the virtual termcap maps changing the character instead |
| 516 | " of sending Shift |
| 517 | for mod_key in mod_keycodes |
| 518 | if index([s:VK.SHIFT, s:VK.LSHIFT, s:VK.RSHIFT], mod_key) >= 0 |
| 519 | let mod_mask = mod_mask + s:vim_MOD_MASK_SHIFT |
| 520 | endif |
| 521 | endfor |
| 522 | """"""call assert_equal(vim_mod_mask, mod_mask, $"mod = {vim_mod_mask} for key = {kstr}") |
| 523 | endfor |
| 524 | endfor |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 525 | endif |
| 526 | |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 527 | " Test for the various Ctrl and Shift key combinations. |
| 528 | " Refer to the following page for the virtual key codes: |
| 529 | " https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes |
| 530 | let keytests = [ |
| 531 | \ [[s:VK.SHIFT, s:VK.PRIOR], "S-Pageup", 2], |
| 532 | \ [[s:VK.LSHIFT, s:VK.PRIOR], "S-Pageup", 2], |
| 533 | \ [[s:VK.RSHIFT, s:VK.PRIOR], "S-Pageup", 2], |
| 534 | \ [[s:VK.CONTROL, s:VK.PRIOR], "C-Pageup", 4], |
| 535 | \ [[s:VK.LCONTROL, s:VK.PRIOR], "C-Pageup", 4], |
| 536 | \ [[s:VK.RCONTROL, s:VK.PRIOR], "C-Pageup", 4], |
| 537 | \ [[s:VK.CONTROL, s:VK.SHIFT, s:VK.PRIOR], "C-S-Pageup", 6], |
| 538 | \ [[s:VK.SHIFT, s:VK.NEXT], "S-PageDown", 2], |
| 539 | \ [[s:VK.LSHIFT, s:VK.NEXT], "S-PageDown", 2], |
| 540 | \ [[s:VK.RSHIFT, s:VK.NEXT], "S-PageDown", 2], |
| 541 | \ [[s:VK.CONTROL, s:VK.NEXT], "C-PageDown", 4], |
| 542 | \ [[s:VK.LCONTROL, s:VK.NEXT], "C-PageDown", 4], |
| 543 | \ [[s:VK.RCONTROL, s:VK.NEXT], "C-PageDown", 4], |
| 544 | \ [[s:VK.CONTROL, s:VK.SHIFT, s:VK.NEXT], "C-S-PageDown", 6], |
| 545 | \ [[s:VK.SHIFT, s:VK.END], "S-End", 0], |
| 546 | \ [[s:VK.CONTROL, s:VK.END], "C-End", 0], |
| 547 | \ [[s:VK.CONTROL, s:VK.SHIFT, s:VK.END], "C-S-End", 4], |
| 548 | \ [[s:VK.SHIFT, s:VK.HOME], "S-Home", 0], |
| 549 | \ [[s:VK.CONTROL, s:VK.HOME], "C-Home", 0], |
| 550 | \ [[s:VK.CONTROL, s:VK.SHIFT, s:VK.HOME], "C-S-Home", 4], |
| 551 | \ [[s:VK.SHIFT, s:VK.LEFT], "S-Left", 0], |
| 552 | \ [[s:VK.CONTROL, s:VK.LEFT], "C-Left", 0], |
| 553 | \ [[s:VK.CONTROL, s:VK.SHIFT, s:VK.LEFT], "C-S-Left", 4], |
| 554 | \ [[s:VK.SHIFT, s:VK.UP], "S-Up", 0], |
| 555 | \ [[s:VK.CONTROL, s:VK.UP], "C-Up", 4], |
| 556 | \ [[s:VK.CONTROL, s:VK.SHIFT, s:VK.UP], "C-S-Up", 4], |
| 557 | \ [[s:VK.SHIFT, s:VK.RIGHT], "S-Right", 0], |
| 558 | \ [[s:VK.CONTROL, s:VK.RIGHT], "C-Right", 0], |
| 559 | \ [[s:VK.CONTROL, s:VK.SHIFT, s:VK.RIGHT], "C-S-Right", 4], |
| 560 | \ [[s:VK.SHIFT, s:VK.DOWN], "S-Down", 0], |
| 561 | \ [[s:VK.CONTROL, s:VK.DOWN], "C-Down", 4], |
| 562 | \ [[s:VK.CONTROL, s:VK.SHIFT, s:VK.DOWN], "C-S-Down", 4], |
| 563 | \ [[s:VK.CONTROL, s:VK.KEY_0], "C-0", 4], |
| 564 | \ [[s:VK.CONTROL, s:VK.KEY_1], "C-1", 4], |
| 565 | \ [[s:VK.CONTROL, s:VK.KEY_2], "C-@", 0], |
| 566 | \ [[s:VK.CONTROL, s:VK.KEY_3], "C-3", 4], |
| 567 | \ [[s:VK.CONTROL, s:VK.KEY_4], "C-4", 4], |
| 568 | \ [[s:VK.CONTROL, s:VK.KEY_5], "C-5", 4], |
| 569 | \ [[s:VK.CONTROL, s:VK.KEY_6], "C-^", 0], |
| 570 | \ [[s:VK.CONTROL, s:VK.KEY_7], "C-7", 4], |
| 571 | \ [[s:VK.CONTROL, s:VK.KEY_8], "C-8", 4], |
| 572 | \ [[s:VK.CONTROL, s:VK.KEY_9], "C-9", 4], |
| 573 | \ [[s:VK.CONTROL, s:VK.NUMPAD0], "C-0", 4], |
| 574 | \ [[s:VK.CONTROL, s:VK.NUMPAD1], "C-1", 4], |
| 575 | \ [[s:VK.CONTROL, s:VK.NUMPAD2], "C-2", 4], |
| 576 | \ [[s:VK.CONTROL, s:VK.NUMPAD3], "C-3", 4], |
| 577 | \ [[s:VK.CONTROL, s:VK.NUMPAD4], "C-4", 4], |
| 578 | \ [[s:VK.CONTROL, s:VK.NUMPAD5], "C-5", 4], |
| 579 | \ [[s:VK.CONTROL, s:VK.NUMPAD6], "C-6", 4], |
| 580 | \ [[s:VK.CONTROL, s:VK.NUMPAD7], "C-7", 4], |
| 581 | \ [[s:VK.CONTROL, s:VK.NUMPAD8], "C-8", 4], |
| 582 | \ [[s:VK.CONTROL, s:VK.NUMPAD9], "C-9", 4], |
| 583 | \ [[s:VK.CONTROL, s:VK.MULTIPLY], "C-*", 4], |
| 584 | \ [[s:VK.CONTROL, s:VK.ADD], "C-+", 4], |
| 585 | \ [[s:VK.CONTROL, s:VK.SUBTRACT], "C--", 4], |
| 586 | \ [[s:VK.CONTROL, s:VK.OEM_MINUS], "C-_", 0] |
| 587 | \ ] |
| 588 | |
| 589 | " Not working in CI Testing yet!? |
| 590 | for [kcodes, kstr, kmod] in keytests |
| 591 | call SendKeyGroup(kcodes) |
| 592 | let ch = getcharstr(0) |
| 593 | let mod = getcharmod() |
| 594 | let keycode = eval('"\<' .. kstr .. '>"') |
| 595 | " call assert_equal(keycode, ch, $"key = {kstr}") |
| 596 | " call assert_equal(kmod, mod, $"mod = {kmod} key = {kstr}") |
| 597 | endfor |
| 598 | |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 599 | bw! |
| 600 | endfunc |
| 601 | |
Christopher Plewright | 7b0afc1 | 2022-12-30 16:54:58 +0000 | [diff] [blame^] | 602 | |
| 603 | " Test for QWERTY Ctrl+- which should result in ^_ |
| 604 | " issue #10817 |
| 605 | func Test_QWERTY_Ctrl_minus() |
| 606 | CheckMSWindows |
| 607 | new |
| 608 | |
| 609 | call SendKeyGroup([s:VK.CONTROL, s:VK.OEM_MINUS]) |
| 610 | let ch = getcharstr(0) |
| 611 | call assert_equal(nr2char(0x1f),ch) |
| 612 | |
| 613 | call SendKey(s:VK.KEY_I) |
| 614 | call SendKeyGroup([s:VK.CONTROL, s:VK.SUBTRACT]) |
| 615 | call SendKey(s:VK.ESCAPE) |
| 616 | call ExecuteBufferedKeys() |
| 617 | call assert_equal('-', getline('$')) |
| 618 | |
| 619 | %d _ |
| 620 | imapclear |
| 621 | imap <C-_> BINGO |
| 622 | call SendKey(s:VK.KEY_I) |
| 623 | call SendKeyGroup([s:VK.CONTROL, s:VK.OEM_MINUS]) |
| 624 | call SendKey(s:VK.ESCAPE) |
| 625 | call ExecuteBufferedKeys() |
| 626 | call assert_equal('BINGO', getline('$')) |
| 627 | |
| 628 | %d _ |
| 629 | imapclear |
| 630 | exec "imap \x1f BILBO" |
| 631 | call SendKey(s:VK.KEY_I) |
| 632 | call SendKeyGroup([s:VK.CONTROL, s:VK.OEM_MINUS]) |
| 633 | call SendKey(s:VK.ESCAPE) |
| 634 | call ExecuteBufferedKeys() |
| 635 | call assert_equal('BILBO', getline('$')) |
| 636 | |
| 637 | |
| 638 | |
| 639 | imapclear |
| 640 | bw! |
| 641 | endfunc |
| 642 | |
| 643 | " Test MS-Windows mouse events |
Christopher Plewright | 20b795e | 2022-12-20 20:01:58 +0000 | [diff] [blame] | 644 | func Test_mswin_mouse_event() |
| 645 | CheckMSWindows |
| 646 | new |
| 647 | |
| 648 | set mousemodel=extend |
| 649 | call test_override('no_query_mouse', 1) |
| 650 | call WaitForResponses() |
| 651 | |
| 652 | let msg = '' |
| 653 | |
| 654 | call setline(1, ['one two three', 'four five six']) |
| 655 | |
| 656 | " Test mouse movement |
| 657 | " by default, no mouse move events are generated |
| 658 | " this setting enables it to generate move events |
| 659 | set mousemev |
| 660 | |
| 661 | if !has('gui_running') |
| 662 | " console version needs a button pressed, |
| 663 | " otherwise it ignores mouse movements. |
| 664 | call MouseLeftClick(2, 3) |
| 665 | endif |
| 666 | call MSWinMouseEvent(0x700, 8, 13, 0, 0, 0) |
| 667 | if has('gui_running') |
| 668 | call feedkeys("\<Esc>", 'Lx!') |
| 669 | endif |
| 670 | let pos = getmousepos() |
| 671 | call assert_equal(8, pos.screenrow) |
| 672 | call assert_equal(13, pos.screencol) |
| 673 | |
| 674 | if !has('gui_running') |
| 675 | call MouseLeftClick(2, 3) |
| 676 | call MSWinMouseEvent(0x700, 6, 4, 1, 0, 0) |
| 677 | let pos = getmousepos() |
| 678 | call assert_equal(6, pos.screenrow) |
| 679 | call assert_equal(4, pos.screencol) |
| 680 | endif |
| 681 | |
| 682 | " test cells vs pixels |
| 683 | if has('gui_running') |
| 684 | let args = { } |
| 685 | let args.row = 9 |
| 686 | let args.col = 7 |
| 687 | let args.move = 1 |
| 688 | let args.cell = 1 |
| 689 | call test_mswin_event("mouse", args) |
| 690 | call feedkeys("\<Esc>", 'Lx!') |
| 691 | let pos = getmousepos() |
| 692 | call assert_equal(9, pos.screenrow) |
| 693 | call assert_equal(7, pos.screencol) |
| 694 | |
| 695 | let args.cell = 0 |
| 696 | call test_mswin_event("mouse", args) |
| 697 | call feedkeys("\<Esc>", 'Lx!') |
| 698 | let pos = getmousepos() |
| 699 | call assert_equal(1, pos.screenrow) |
| 700 | call assert_equal(1, pos.screencol) |
| 701 | |
| 702 | unlet args |
| 703 | endif |
| 704 | |
| 705 | " finish testing mouse movement |
| 706 | set mousemev& |
| 707 | |
| 708 | " place the cursor using left click and release in normal mode |
| 709 | call MouseLeftClick(2, 4) |
| 710 | call MouseLeftRelease(2, 4) |
| 711 | if has('gui_running') |
| 712 | call feedkeys("\<Esc>", 'Lx!') |
| 713 | endif |
| 714 | call assert_equal([0, 2, 4, 0], getpos('.')) |
| 715 | |
| 716 | " select and yank a word |
| 717 | let @" = '' |
| 718 | call MouseLeftClick(1, 9) |
| 719 | let args = #{button: 0, row: 1, col: 9, multiclick: 1, modifiers: 0} |
| 720 | call test_mswin_event('mouse', args) |
| 721 | call MouseLeftRelease(1, 9) |
| 722 | call feedkeys("y", 'Lx!') |
| 723 | call assert_equal('three', @") |
| 724 | |
| 725 | " create visual selection using right click |
| 726 | let @" = '' |
| 727 | |
| 728 | call MouseLeftClick(2 ,6) |
| 729 | call MouseLeftRelease(2, 6) |
| 730 | call MouseRightClick(2, 13) |
| 731 | call MouseRightRelease(2, 13) |
| 732 | call feedkeys("y", 'Lx!') |
| 733 | call assert_equal('five six', @") |
| 734 | |
| 735 | " paste using middle mouse button |
| 736 | let @* = 'abc ' |
| 737 | call feedkeys('""', 'Lx!') |
| 738 | call MouseMiddleClick(1, 9) |
| 739 | call MouseMiddleRelease(1, 9) |
| 740 | if has('gui_running') |
| 741 | call feedkeys("\<Esc>", 'Lx!') |
| 742 | endif |
| 743 | call assert_equal(['one two abc three', 'four five six'], getline(1, '$')) |
| 744 | |
| 745 | " test mouse scrolling (aka touchpad scrolling.) |
| 746 | %d _ |
| 747 | set scrolloff=0 |
| 748 | call setline(1, range(1, 100)) |
| 749 | |
| 750 | " Scroll Down |
| 751 | call MouseWheelDown(2, 1) |
| 752 | call MouseWheelDown(2, 1) |
| 753 | call MouseWheelDown(2, 1) |
| 754 | call feedkeys("H", 'Lx!') |
| 755 | call assert_equal(10, line('.')) |
| 756 | |
| 757 | " Scroll Up |
| 758 | call MouseWheelUp(2, 1) |
| 759 | call MouseWheelUp(2, 1) |
| 760 | call feedkeys("H", 'Lx!') |
| 761 | call assert_equal(4, line('.')) |
| 762 | |
| 763 | " Shift Scroll Down |
| 764 | call MouseShiftWheelDown(2, 1) |
| 765 | call feedkeys("H", 'Lx!') |
| 766 | " should scroll from where it is (4) + visible buffer height - cmdheight |
| 767 | let shift_scroll_height = line('w$') - line('w0') - &cmdheight |
| 768 | call assert_equal(4 + shift_scroll_height, line('.')) |
| 769 | |
| 770 | " Shift Scroll Up |
| 771 | call MouseShiftWheelUp(2, 1) |
| 772 | call feedkeys("H", 'Lx!') |
| 773 | call assert_equal(4, line('.')) |
| 774 | |
| 775 | if !has('gui_running') |
| 776 | " Shift Scroll Down (using MOD) |
| 777 | call MSWinMouseEvent(0x100, 2, 1, 0, 0, 0x04) |
| 778 | call feedkeys("H", 'Lx!') |
| 779 | " should scroll from where it is (4) + visible buffer height - cmdheight |
| 780 | let shift_scroll_height = line('w$') - line('w0') - &cmdheight |
| 781 | call assert_equal(4 + shift_scroll_height, line('.')) |
| 782 | |
| 783 | " Shift Scroll Up (using MOD) |
| 784 | call MSWinMouseEvent(0x200, 2, 1, 0, 0, 0x04) |
| 785 | call feedkeys("H", 'Lx!') |
| 786 | call assert_equal(4, line('.')) |
| 787 | endif |
| 788 | |
| 789 | set scrolloff& |
| 790 | |
| 791 | %d _ |
| 792 | set nowrap |
| 793 | " make the buffer 500 wide. |
| 794 | call setline(1, range(10)->join('')->repeat(50)) |
| 795 | " Scroll Right |
| 796 | call MouseWheelRight(1, 5) |
| 797 | call MouseWheelRight(1, 10) |
| 798 | call MouseWheelRight(1, 15) |
| 799 | call feedkeys('g0', 'Lx!') |
| 800 | call assert_equal(19, col('.')) |
| 801 | |
| 802 | " Scroll Left |
| 803 | call MouseWheelLeft(1, 15) |
| 804 | call MouseWheelLeft(1, 10) |
| 805 | call feedkeys('g0', 'Lx!') |
| 806 | call assert_equal(7, col('.')) |
| 807 | |
| 808 | " Shift Scroll Right |
| 809 | call MouseShiftWheelRight(1, 10) |
| 810 | call feedkeys('g0', 'Lx!') |
| 811 | " should scroll from where it is (7) + window width |
| 812 | call assert_equal(7 + winwidth(0), col('.')) |
| 813 | |
| 814 | " Shift Scroll Left |
| 815 | call MouseShiftWheelLeft(1, 50) |
| 816 | call feedkeys('g0', 'Lx!') |
| 817 | call assert_equal(7, col('.')) |
| 818 | set wrap& |
| 819 | |
| 820 | %d _ |
| 821 | call setline(1, repeat([repeat('a', 60)], 10)) |
| 822 | |
| 823 | " record various mouse events |
| 824 | let mouseEventNames = [ |
| 825 | \ 'LeftMouse', 'LeftRelease', '2-LeftMouse', '3-LeftMouse', |
| 826 | \ 'S-LeftMouse', 'A-LeftMouse', 'C-LeftMouse', 'MiddleMouse', |
| 827 | \ 'MiddleRelease', '2-MiddleMouse', '3-MiddleMouse', |
| 828 | \ 'S-MiddleMouse', 'A-MiddleMouse', 'C-MiddleMouse', |
| 829 | \ 'RightMouse', 'RightRelease', '2-RightMouse', |
| 830 | \ '3-RightMouse', 'S-RightMouse', 'A-RightMouse', 'C-RightMouse', |
| 831 | \ ] |
| 832 | let mouseEventCodes = map(copy(mouseEventNames), "'<' .. v:val .. '>'") |
| 833 | let g:events = [] |
| 834 | for e in mouseEventCodes |
| 835 | exe 'nnoremap ' .. e .. ' <Cmd>call add(g:events, "' .. |
| 836 | \ substitute(e, '[<>]', '', 'g') .. '")<CR>' |
| 837 | endfor |
| 838 | |
| 839 | " Test various mouse buttons |
| 840 | "(0 - Left, 1 - Middle, 2 - Right, |
| 841 | " 0x300 - MOUSE_X1/FROM_LEFT_3RD_BUTTON, |
| 842 | " 0x400 - MOUSE_X2/FROM_LEFT_4TH_BUTTON) |
| 843 | for button in [0, 1, 2, 0x300, 0x400] |
| 844 | " Single click |
| 845 | let args = #{button: button, row: 2, col: 5, multiclick: 0, modifiers: 0} |
| 846 | call test_mswin_event('mouse', args) |
| 847 | let args.button = 3 |
| 848 | call test_mswin_event('mouse', args) |
| 849 | |
| 850 | " Double Click |
| 851 | let args.button = button |
| 852 | call test_mswin_event('mouse', args) |
| 853 | let args.multiclick = 1 |
| 854 | call test_mswin_event('mouse', args) |
| 855 | let args.button = 3 |
| 856 | let args.multiclick = 0 |
| 857 | call test_mswin_event('mouse', args) |
| 858 | |
| 859 | " Triple Click |
| 860 | let args.button = button |
| 861 | call test_mswin_event('mouse', args) |
| 862 | let args.multiclick = 1 |
| 863 | call test_mswin_event('mouse', args) |
| 864 | call test_mswin_event('mouse', args) |
| 865 | let args.button = 3 |
| 866 | let args.multiclick = 0 |
| 867 | call test_mswin_event('mouse', args) |
| 868 | |
| 869 | " Shift click |
| 870 | let args = #{button: button, row: 3, col: 7, multiclick: 0, modifiers: 4} |
| 871 | call test_mswin_event('mouse', args) |
| 872 | let args.button = 3 |
| 873 | call test_mswin_event('mouse', args) |
| 874 | |
| 875 | " Alt click |
| 876 | let args.button = button |
| 877 | let args.modifiers = 8 |
| 878 | call test_mswin_event('mouse', args) |
| 879 | let args.button = 3 |
| 880 | call test_mswin_event('mouse', args) |
| 881 | |
| 882 | " Ctrl click |
| 883 | let args.button = button |
| 884 | let args.modifiers = 16 |
| 885 | call test_mswin_event('mouse', args) |
| 886 | let args.button = 3 |
| 887 | call test_mswin_event('mouse', args) |
| 888 | |
| 889 | call feedkeys("\<Esc>", 'Lx!') |
| 890 | endfor |
| 891 | |
| 892 | if has('gui_running') |
| 893 | call assert_equal(['LeftMouse', 'LeftRelease', 'LeftMouse', |
| 894 | \ '2-LeftMouse', 'LeftMouse', '2-LeftMouse', '3-LeftMouse', |
| 895 | \ 'S-LeftMouse', 'A-LeftMouse', 'C-LeftMouse', 'MiddleMouse', |
| 896 | \ 'MiddleRelease', 'MiddleMouse', '2-MiddleMouse', 'MiddleMouse', |
| 897 | \ '2-MiddleMouse', '3-MiddleMouse', 'S-MiddleMouse', 'A-MiddleMouse', |
| 898 | \ 'C-MiddleMouse', 'RightMouse', 'RightRelease', 'RightMouse', |
| 899 | \ '2-RightMouse', 'RightMouse', '2-RightMouse', '3-RightMouse', |
| 900 | \ 'S-RightMouse', 'A-RightMouse', 'C-RightMouse'], |
| 901 | \ g:events) |
| 902 | else |
| 903 | call assert_equal(['MiddleRelease', 'LeftMouse', '2-LeftMouse', |
| 904 | \ '3-LeftMouse', 'S-LeftMouse', 'MiddleMouse', '2-MiddleMouse', |
| 905 | \ '3-MiddleMouse', 'MiddleMouse', 'S-MiddleMouse', 'RightMouse', |
| 906 | \ '2-RightMouse', '3-RightMouse'], |
| 907 | \ g:events) |
| 908 | endif |
| 909 | |
| 910 | for e in mouseEventCodes |
| 911 | exe 'nunmap ' .. e |
| 912 | endfor |
| 913 | |
| 914 | bw! |
| 915 | call test_override('no_query_mouse', 0) |
| 916 | set mousemodel& |
| 917 | endfunc |
| 918 | |
| 919 | |
| 920 | " Test MS-Windows test_mswin_event error handling |
| 921 | func Test_mswin_event_error_handling() |
| 922 | |
| 923 | let args = #{button: 0xfff, row: 2, col: 4, move: 0, multiclick: 0, modifiers: 0} |
| 924 | if !has('gui_running') |
| 925 | call assert_fails("call test_mswin_event('mouse', args)",'E475:') |
| 926 | endif |
| 927 | let args = #{button: 0, row: 2, col: 4, move: 0, multiclick: 0, modifiers: 0} |
| 928 | call assert_fails("call test_mswin_event('a1b2c3', args)", 'E475:') |
| 929 | call assert_fails("call test_mswin_event(test_null_string(), {})", 'E475:') |
| 930 | |
| 931 | call assert_fails("call test_mswin_event([], args)", 'E1174:') |
| 932 | call assert_fails("call test_mswin_event('abc', [])", 'E1206:') |
| 933 | |
| 934 | call assert_false(test_mswin_event('mouse', test_null_dict())) |
| 935 | let args = #{row: 2, col: 4, multiclick: 0, modifiers: 0} |
| 936 | call assert_false(test_mswin_event('mouse', args)) |
| 937 | let args = #{button: 0, col: 4, multiclick: 0, modifiers: 0} |
| 938 | call assert_false(test_mswin_event('mouse', args)) |
| 939 | let args = #{button: 0, row: 2, multiclick: 0, modifiers: 0} |
| 940 | call assert_false(test_mswin_event('mouse', args)) |
| 941 | let args = #{button: 0, row: 2, col: 4, modifiers: 0} |
| 942 | call assert_false(test_mswin_event('mouse', args)) |
| 943 | let args = #{button: 0, row: 2, col: 4, multiclick: 0} |
| 944 | call assert_false(test_mswin_event('mouse', args)) |
| 945 | |
| 946 | call assert_false(test_mswin_event('key', test_null_dict())) |
| 947 | call assert_fails("call test_mswin_event('key', [])", 'E1206:') |
| 948 | call assert_fails("call test_mswin_event('key', {'event': 'keydown', 'keycode': 0x0})", 'E1291:') |
| 949 | call assert_fails("call test_mswin_event('key', {'event': 'keydown', 'keycode': [15]})", 'E745:') |
| 950 | call assert_fails("call test_mswin_event('key', {'event': 'keys', 'keycode': 0x41})", 'E475:') |
| 951 | call assert_fails("call test_mswin_event('key', {'keycode': 0x41})", 'E417:') |
| 952 | call assert_fails("call test_mswin_event('key', {'event': 'keydown'})", 'E1291:') |
| 953 | |
| 954 | call assert_fails("sandbox call test_mswin_event('key', {'event': 'keydown', 'keycode': 61 })", 'E48:') |
| 955 | |
| 956 | " flush out any garbage left in the buffer. |
| 957 | while getchar(0) |
| 958 | endwhile |
| 959 | endfunc |
| 960 | |
| 961 | |
| 962 | " vim: shiftwidth=2 sts=2 expandtab |