mirror of
				https://github.com/vim/vim.git
				synced 2025-10-30 09:47:20 -04:00 
			
		
		
		
	patch 9.0.1146: MS-Windows: various special keys/modifiers are not mappable
Problem:    MS-Windows: various special keys and modifiers are not mappable.
Solution:   Adjust the handling of keys with modifiers. (Christian Plewright,
            closes #11768)
			
			
This commit is contained in:
		
				
					committed by
					
						 Bram Moolenaar
						Bram Moolenaar
					
				
			
			
				
	
			
			
			
						parent
						
							3ac1d97a1d
						
					
				
				
					commit
					c8b204952f
				
			| @@ -1,5 +1,7 @@ | |||||||
| version: "{build}" | version: "{build}" | ||||||
|  |  | ||||||
|  | image: Visual Studio 2015 | ||||||
|  |  | ||||||
| skip_tags: true | skip_tags: true | ||||||
|  |  | ||||||
| environment: | environment: | ||||||
|   | |||||||
| @@ -29,12 +29,12 @@ To build the installable .exe: | |||||||
|  |  | ||||||
| 4.  Get a "diff.exe" program.  If you skip this the built-in diff will always | 4.  Get a "diff.exe" program.  If you skip this the built-in diff will always | ||||||
|     be used (which is fine for most users).  If you do have your own |     be used (which is fine for most users).  If you do have your own | ||||||
|     "diff.exe" put it in the "../.." directory (above the "vim82" directory, |     "diff.exe" put it in the "../.." directory (above the "vim90" directory, | ||||||
|     it's the same for all Vim versions). |     it's the same for all Vim versions). | ||||||
|     You can find one in previous Vim versions or in this archive: |     You can find one in previous Vim versions or in this archive: | ||||||
| 		http://www.mossbayeng.com/~ron/vim/diffutils.tar.gz | 		http://www.mossbayeng.com/~ron/vim/diffutils.tar.gz | ||||||
|  |  | ||||||
| 5   Also put winpty32.dll and winpty-agent.exe in "../.." (above the "vim82" | 5   Also put winpty32.dll and winpty-agent.exe in "../.." (above the "vim90" | ||||||
|     directory).  This is required for the terminal window. |     directory).  This is required for the terminal window. | ||||||
|  |  | ||||||
| 6.  Do "make uganda.nsis.txt" in runtime/doc.  This requires sed, you may have | 6.  Do "make uganda.nsis.txt" in runtime/doc.  This requires sed, you may have | ||||||
|   | |||||||
							
								
								
									
										127
									
								
								src/os_win32.c
									
									
									
									
									
								
							
							
						
						
									
										127
									
								
								src/os_win32.c
									
									
									
									
									
								
							| @@ -1042,7 +1042,8 @@ win32_kbd_patch_key( | |||||||
| 	return 1; | 	return 1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (pker->uChar.UnicodeChar > 0 && pker->uChar.UnicodeChar < 0xfffd) |     // check if it already has a valid unicode character. | ||||||
|  |     if (pker->uChar.UnicodeChar > 0 && pker->uChar.UnicodeChar < 0xFFFD) | ||||||
| 	return 1; | 	return 1; | ||||||
|  |  | ||||||
|     CLEAR_FIELD(abKeystate); |     CLEAR_FIELD(abKeystate); | ||||||
| @@ -1118,13 +1119,12 @@ decode_key_event( | |||||||
|     { |     { | ||||||
| 	if (VirtKeyMap[i].wVirtKey == pker->wVirtualKeyCode) | 	if (VirtKeyMap[i].wVirtKey == pker->wVirtualKeyCode) | ||||||
| 	{ | 	{ | ||||||
| 	    if (nModifs == 0) | 	    *pch = VirtKeyMap[i].chAlone; | ||||||
| 		*pch = VirtKeyMap[i].chAlone; | 	    if ((nModifs & SHIFT) != 0) | ||||||
| 	    else if ((nModifs & SHIFT) != 0 && (nModifs & ~SHIFT) == 0) |  | ||||||
| 		*pch = VirtKeyMap[i].chShift; | 		*pch = VirtKeyMap[i].chShift; | ||||||
| 	    else if ((nModifs & CTRL) != 0 && (nModifs & ~CTRL) == 0) | 	    else if ((nModifs & CTRL) != 0 && (nModifs & ~CTRL) == 0) | ||||||
| 		*pch = VirtKeyMap[i].chCtrl; | 		*pch = VirtKeyMap[i].chCtrl; | ||||||
| 	    else if ((nModifs & ALT) != 0 && (nModifs & ~ALT) == 0) | 	    else if ((nModifs & ALT) != 0) | ||||||
| 		*pch = VirtKeyMap[i].chAlt; | 		*pch = VirtKeyMap[i].chAlt; | ||||||
|  |  | ||||||
| 	    if (*pch != 0) | 	    if (*pch != 0) | ||||||
| @@ -1133,6 +1133,74 @@ decode_key_event( | |||||||
| 		{ | 		{ | ||||||
| 		    *pch2 = *pch; | 		    *pch2 = *pch; | ||||||
| 		    *pch = K_NUL; | 		    *pch = K_NUL; | ||||||
|  | 		    if (pmodifiers) | ||||||
|  | 		    { | ||||||
|  | 			if (pker->wVirtualKeyCode >= VK_F1 | ||||||
|  | 			    && pker->wVirtualKeyCode <= VK_F12) | ||||||
|  | 			{ | ||||||
|  | 			    if ((nModifs & ALT) != 0) | ||||||
|  | 			    { | ||||||
|  | 				*pmodifiers |= MOD_MASK_ALT; | ||||||
|  | 				if ((nModifs & SHIFT) == 0) | ||||||
|  | 				    *pch2 = VirtKeyMap[i].chAlone; | ||||||
|  | 			    } | ||||||
|  | 			    if ((nModifs & CTRL) != 0) | ||||||
|  | 			    { | ||||||
|  | 				*pmodifiers |= MOD_MASK_CTRL; | ||||||
|  | 				if ((nModifs & SHIFT) == 0) | ||||||
|  | 				    *pch2 = VirtKeyMap[i].chAlone; | ||||||
|  | 			    } | ||||||
|  | 			} | ||||||
|  | 			else if (pker->wVirtualKeyCode >= VK_END | ||||||
|  | 				&& pker->wVirtualKeyCode <= VK_DOWN) | ||||||
|  | 			{ | ||||||
|  | 			    // VK_END   0x23 | ||||||
|  | 			    // VK_HOME  0x24 | ||||||
|  | 			    // VK_LEFT  0x25 | ||||||
|  | 			    // VK_UP    0x26 | ||||||
|  | 			    // VK_RIGHT 0x27 | ||||||
|  | 			    // VK_DOWN  0x28 | ||||||
|  | 			    *pmodifiers = 0; | ||||||
|  | 			    *pch2 = VirtKeyMap[i].chAlone; | ||||||
|  | 			    if ((nModifs & SHIFT) != 0 | ||||||
|  | 						    && (nModifs & ~SHIFT) == 0) | ||||||
|  | 			    { | ||||||
|  | 				*pch2 = VirtKeyMap[i].chShift; | ||||||
|  | 			    } | ||||||
|  | 			    else if ((nModifs & CTRL) != 0 | ||||||
|  | 						     && (nModifs & ~CTRL) == 0) | ||||||
|  | 			    { | ||||||
|  | 				*pch2 = VirtKeyMap[i].chCtrl; | ||||||
|  | 				if (pker->wVirtualKeyCode == VK_UP | ||||||
|  | 				    || pker->wVirtualKeyCode == VK_DOWN) | ||||||
|  | 				{ | ||||||
|  | 				    *pmodifiers |= MOD_MASK_CTRL; | ||||||
|  | 				    *pch2 = VirtKeyMap[i].chAlone; | ||||||
|  | 				} | ||||||
|  | 			    } | ||||||
|  | 			    else if ((nModifs & ALT) != 0 | ||||||
|  | 						      && (nModifs & ~ALT) == 0) | ||||||
|  | 			    { | ||||||
|  | 				*pch2 = VirtKeyMap[i].chAlt; | ||||||
|  | 			    } | ||||||
|  | 			    else if ((nModifs & SHIFT) != 0 | ||||||
|  | 						      && (nModifs & CTRL) != 0) | ||||||
|  | 			    { | ||||||
|  | 				*pmodifiers |= MOD_MASK_CTRL; | ||||||
|  | 				*pch2 = VirtKeyMap[i].chShift; | ||||||
|  | 			    } | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 			    *pch2 = VirtKeyMap[i].chAlone; | ||||||
|  | 			    if ((nModifs & SHIFT) != 0) | ||||||
|  | 				*pmodifiers |= MOD_MASK_SHIFT; | ||||||
|  | 			    if ((nModifs & CTRL) != 0) | ||||||
|  | 				*pmodifiers |= MOD_MASK_CTRL; | ||||||
|  | 			    if ((nModifs & ALT) != 0) | ||||||
|  | 				*pmodifiers |= MOD_MASK_ALT; | ||||||
|  | 			} | ||||||
|  | 		    } | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return TRUE; | 		return TRUE; | ||||||
| @@ -1178,10 +1246,11 @@ encode_key_event(dict_T *args, INPUT_RECORD *ir) | |||||||
| { | { | ||||||
|     static int s_dwMods = 0; |     static int s_dwMods = 0; | ||||||
|  |  | ||||||
|     char_u *event = dict_get_string(args, "event", TRUE); |     char_u *action = dict_get_string(args, "event", TRUE); | ||||||
|     if (event && (STRICMP(event, "keydown") == 0 |     if (action && (STRICMP(action, "keydown") == 0 | ||||||
| 					|| STRICMP(event, "keyup") == 0)) | 					|| STRICMP(action, "keyup") == 0)) | ||||||
|     { |     { | ||||||
|  | 	BOOL isKeyDown = STRICMP(action, "keydown") == 0; | ||||||
| 	WORD vkCode = dict_get_number_def(args, "keycode", 0); | 	WORD vkCode = dict_get_number_def(args, "keycode", 0); | ||||||
| 	if (vkCode <= 0 || vkCode >= 0xFF) | 	if (vkCode <= 0 || vkCode >= 0xFF) | ||||||
| 	{ | 	{ | ||||||
| @@ -1192,7 +1261,7 @@ encode_key_event(dict_T *args, INPUT_RECORD *ir) | |||||||
| 	ir->EventType = KEY_EVENT; | 	ir->EventType = KEY_EVENT; | ||||||
| 	KEY_EVENT_RECORD ker; | 	KEY_EVENT_RECORD ker; | ||||||
| 	ZeroMemory(&ker, sizeof(ker)); | 	ZeroMemory(&ker, sizeof(ker)); | ||||||
| 	ker.bKeyDown = STRICMP(event, "keydown") == 0; | 	ker.bKeyDown = isKeyDown; | ||||||
| 	ker.wRepeatCount = 1; | 	ker.wRepeatCount = 1; | ||||||
| 	ker.wVirtualScanCode = 0; | 	ker.wVirtualScanCode = 0; | ||||||
| 	ker.dwControlKeyState = 0; | 	ker.dwControlKeyState = 0; | ||||||
| @@ -1215,73 +1284,55 @@ encode_key_event(dict_T *args, INPUT_RECORD *ir) | |||||||
|  |  | ||||||
| 	if (vkCode == VK_LSHIFT || vkCode == VK_RSHIFT || vkCode == VK_SHIFT) | 	if (vkCode == VK_LSHIFT || vkCode == VK_RSHIFT || vkCode == VK_SHIFT) | ||||||
| 	{ | 	{ | ||||||
| 	    if (STRICMP(event, "keydown") == 0) | 	    if (isKeyDown) | ||||||
| 		s_dwMods |= SHIFT_PRESSED; | 		s_dwMods |= SHIFT_PRESSED; | ||||||
| 	    else | 	    else | ||||||
| 		s_dwMods &= ~SHIFT_PRESSED; | 		s_dwMods &= ~SHIFT_PRESSED; | ||||||
| 	} | 	} | ||||||
| 	else if (vkCode == VK_LCONTROL || vkCode == VK_CONTROL) | 	else if (vkCode == VK_LCONTROL || vkCode == VK_CONTROL) | ||||||
| 	{ | 	{ | ||||||
| 	    if (STRICMP(event, "keydown") == 0) | 	    if (isKeyDown) | ||||||
| 		s_dwMods |= LEFT_CTRL_PRESSED; | 		s_dwMods |= LEFT_CTRL_PRESSED; | ||||||
| 	    else | 	    else | ||||||
| 		s_dwMods &= ~LEFT_CTRL_PRESSED; | 		s_dwMods &= ~LEFT_CTRL_PRESSED; | ||||||
| 	} | 	} | ||||||
| 	else if (vkCode == VK_RCONTROL) | 	else if (vkCode == VK_RCONTROL) | ||||||
| 	{ | 	{ | ||||||
| 	    if (STRICMP(event, "keydown") == 0) | 	    if (isKeyDown) | ||||||
| 		s_dwMods |= RIGHT_CTRL_PRESSED; | 		s_dwMods |= RIGHT_CTRL_PRESSED; | ||||||
| 	    else | 	    else | ||||||
| 		s_dwMods &= ~RIGHT_CTRL_PRESSED; | 		s_dwMods &= ~RIGHT_CTRL_PRESSED; | ||||||
| 	} | 	} | ||||||
| 	else if (vkCode == VK_LMENU || vkCode == VK_MENU) | 	else if (vkCode == VK_LMENU || vkCode == VK_MENU) | ||||||
| 	{ | 	{ | ||||||
| 	    if (STRICMP(event, "keydown") == 0) | 	    if (isKeyDown) | ||||||
| 		s_dwMods |= LEFT_ALT_PRESSED; | 		s_dwMods |= LEFT_ALT_PRESSED; | ||||||
| 	    else | 	    else | ||||||
| 		s_dwMods &= ~LEFT_ALT_PRESSED; | 		s_dwMods &= ~LEFT_ALT_PRESSED; | ||||||
| 	} | 	} | ||||||
| 	else if (vkCode == VK_RMENU) | 	else if (vkCode == VK_RMENU) | ||||||
| 	{ | 	{ | ||||||
| 	    if (STRICMP(event, "keydown") == 0) | 	    if (isKeyDown) | ||||||
| 		s_dwMods |= RIGHT_ALT_PRESSED; | 		s_dwMods |= RIGHT_ALT_PRESSED; | ||||||
| 	    else | 	    else | ||||||
| 		s_dwMods &= ~RIGHT_ALT_PRESSED; | 		s_dwMods &= ~RIGHT_ALT_PRESSED; | ||||||
| 	} | 	} | ||||||
| 	ker.dwControlKeyState |= s_dwMods; | 	ker.dwControlKeyState |= s_dwMods; | ||||||
| 	ker.wVirtualKeyCode = vkCode; | 	ker.wVirtualKeyCode = vkCode; | ||||||
| 	win32_kbd_patch_key(&ker); | 	ker.uChar.UnicodeChar = 0xFFFD;  // UNICODE REPLACEMENT CHARACTER | ||||||
|  |  | ||||||
| 	for (int i = ARRAY_LENGTH(VirtKeyMap); i >= 0; --i) |  | ||||||
| 	{ |  | ||||||
| 	    if (VirtKeyMap[i].wVirtKey == vkCode) |  | ||||||
| 	    { |  | ||||||
| 		ker.uChar.UnicodeChar = 0xfffd;  // REPLACEMENT CHARACTER |  | ||||||
| 		break; |  | ||||||
| 	    } |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// The following are treated specially in Vim. |  | ||||||
| 	// Ctrl-6 is Ctrl-^ |  | ||||||
| 	// Ctrl-2 is Ctrl-@ |  | ||||||
| 	// Ctrl-- is Ctrl-_ |  | ||||||
| 	if ((vkCode == 0xBD || vkCode == '2' || vkCode == '6') |  | ||||||
| 					     && (ker.dwControlKeyState & CTRL)) |  | ||||||
| 	    ker.uChar.UnicodeChar = 0xfffd;  // REPLACEMENT CHARACTER |  | ||||||
|  |  | ||||||
| 	ir->Event.KeyEvent = ker; | 	ir->Event.KeyEvent = ker; | ||||||
| 	vim_free(event); | 	vim_free(action); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
| 	if (event == NULL) | 	if (action == NULL) | ||||||
| 	{ | 	{ | ||||||
| 	    semsg(_(e_missing_argument_str), "event"); | 	    semsg(_(e_missing_argument_str), "event"); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 	    semsg(_(e_invalid_value_for_argument_str_str), "event", event); | 	    semsg(_(e_invalid_value_for_argument_str_str), "event", action); | ||||||
| 	    vim_free(event); | 	    vim_free(action); | ||||||
| 	} | 	} | ||||||
| 	return FALSE; | 	return FALSE; | ||||||
|     } |     } | ||||||
| @@ -2432,6 +2483,8 @@ mch_inchar( | |||||||
|  |  | ||||||
| 	    c = tgetch(&modifiers, &ch2); | 	    c = tgetch(&modifiers, &ch2); | ||||||
|  |  | ||||||
|  | 	    c = simplify_key(c, &modifiers); | ||||||
|  |  | ||||||
| 	    // Some chars need adjustment when the Ctrl modifier is used. | 	    // Some chars need adjustment when the Ctrl modifier is used. | ||||||
| 	    ++no_reduce_keys; | 	    ++no_reduce_keys; | ||||||
| 	    c = may_adjust_key_for_ctrl(modifiers, c); | 	    c = may_adjust_key_for_ctrl(modifiers, c); | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ | |||||||
|  |  | ||||||
| source check.vim | source check.vim | ||||||
| CheckMSWindows | CheckMSWindows | ||||||
|  |  | ||||||
| source mouse.vim | source mouse.vim | ||||||
|  |  | ||||||
| " Helper function for sending a grouped sequence of low level key presses | " Helper function for sending a grouped sequence of low level key presses | ||||||
| @@ -54,7 +53,8 @@ func ExecuteBufferedKeys() | |||||||
|   endif |   endif | ||||||
| endfunc | endfunc | ||||||
|  |  | ||||||
|  | " Refer to the following page for the virtual key codes: | ||||||
|  | " https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes | ||||||
| let s:VK = { | let s:VK = { | ||||||
|     \ 'ENTER'      : 0x0D, |     \ 'ENTER'      : 0x0D, | ||||||
|     \ 'SPACE'      : 0x20, |     \ 'SPACE'      : 0x20, | ||||||
| @@ -296,11 +296,9 @@ let s:VK = { | |||||||
|     \ [[s:VK.CONTROL, s:VK.OEM_4], 0x1B], |     \ [[s:VK.CONTROL, s:VK.OEM_4], 0x1B], | ||||||
|     \ [[s:VK.CONTROL, s:VK.OEM_5], 0x1C], |     \ [[s:VK.CONTROL, s:VK.OEM_5], 0x1C], | ||||||
|     \ [[s:VK.CONTROL, s:VK.OEM_6], 0x1D], |     \ [[s:VK.CONTROL, s:VK.OEM_6], 0x1D], | ||||||
|  |     \ [[s:VK.CONTROL, s:VK.KEY_6], 0x1E], | ||||||
|  |     \ [[s:VK.CONTROL, s:VK.OEM_MINUS], 0x1F], | ||||||
|     \ ] |     \ ] | ||||||
| " The following non-printable ascii chars fail in the GUI, but work in the  |  | ||||||
| " console. 0x1e [^^] Record separator (RS), and 0x1f [^_] Unit separator (US) |  | ||||||
| "      \ [[s:VK.CONTROL, s:VK.SHIFT, s:VK.KEY_6], 0x1E], |  | ||||||
| "      \ [[s:VK.CONTROL, s:VK.SHIFT, s:VK.OEM_MINUS], 0x1F], |  | ||||||
|  |  | ||||||
| let s:test_extra_key_chars = [ | let s:test_extra_key_chars = [ | ||||||
|     \ [[s:VK.ALT, s:VK.KEY_1], '±'], |     \ [[s:VK.ALT, s:VK.KEY_1], '±'], | ||||||
| @@ -342,7 +340,7 @@ let s:test_extra_key_chars = [ | |||||||
|     \ ] |     \ ] | ||||||
|  |  | ||||||
| func s:LoopTestKeyArray(arr) | func s:LoopTestKeyArray(arr) | ||||||
| " flush out any garbage left in the buffer |   " flush out anything in the typeahead buffer | ||||||
|   while getchar(0) |   while getchar(0) | ||||||
|   endwhile |   endwhile | ||||||
|  |  | ||||||
| @@ -351,7 +349,7 @@ func s:LoopTestKeyArray(arr) | |||||||
|     call SendKeyGroup(kcodes) |     call SendKeyGroup(kcodes) | ||||||
|     let ch = getcharstr(0) |     let ch = getcharstr(0) | ||||||
|     " need to deal a bit differently with the non-printable ascii chars < 0x20 |     " need to deal a bit differently with the non-printable ascii chars < 0x20 | ||||||
|     if kstr < 0x20 && index([s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL],  kcodes[0]) >= 0 |     if kstr < 0x20 && index([s:VK.CONTROL, s:VK.LCONTROL, s:VK.RCONTROL], kcodes[0]) >= 0 | ||||||
|       call assert_equal(nr2char(kstr), $"{ch}") |       call assert_equal(nr2char(kstr), $"{ch}") | ||||||
|     else |     else | ||||||
|       call assert_equal(kstr, $"{ch}") |       call assert_equal(kstr, $"{ch}") | ||||||
| @@ -389,7 +387,7 @@ func s:LoopTestKeyArray(arr) | |||||||
|     call assert_equal(0, mod_mask, $"key = {kstr}") |     call assert_equal(0, mod_mask, $"key = {kstr}") | ||||||
|   endfor |   endfor | ||||||
|  |  | ||||||
|   " flush out any garbage left in the buffer |   " flush out anything in the typeahead buffer | ||||||
|   while getchar(0) |   while getchar(0) | ||||||
|   endwhile |   endwhile | ||||||
|  |  | ||||||
| @@ -489,29 +487,23 @@ func Test_mswin_key_event() | |||||||
|     endfor |     endfor | ||||||
|   endif |   endif | ||||||
|  |  | ||||||
|   " Windows intercepts some of these keys in the GUI |   " Test for Function Keys 'F1' to 'F12' | ||||||
|  |   " VK codes 112(0x70) - 123(0x7B) | ||||||
|  |   " Also with ALL permutatios of modifiers; Shift, Ctrl & Alt | ||||||
|  |   " NOTE: Windows intercepts some of these keys in the GUI | ||||||
|   if !has("gui_running") |   if !has("gui_running") | ||||||
|     " Test for Function Keys 'F1' to 'F12' |  | ||||||
|     for n in range(1, 12) |  | ||||||
|       let kstr = $"F{n}" |  | ||||||
|       let keycode = eval('"\<' .. kstr .. '>"') |  | ||||||
|       call SendKey(111+n) |  | ||||||
|       let ch = getcharstr(0) |  | ||||||
|       call assert_equal(keycode, $"{ch}", $"key = <{kstr}>") |  | ||||||
|     endfor |  | ||||||
|     "  NOTE: mod + Fn Keys not working in CI Testing!? |  | ||||||
|     " Test for Function Keys 'F1' to 'F12' |  | ||||||
|     " VK codes 112(0x70) - 123(0x7B) |  | ||||||
|     " With ALL permutatios of modifiers; Shift, Ctrl & Alt |  | ||||||
|     for [mod_str, vim_mod_mask, mod_keycodes] in s:vim_key_modifiers |     for [mod_str, vim_mod_mask, mod_keycodes] in s:vim_key_modifiers | ||||||
|       for n in range(1, 12) |       for n in range(1, 12) | ||||||
|         let kstr = $"{mod_str}F{n}" |         let kstr = $"{mod_str}F{n}" | ||||||
|         let keycode = eval('"\<' .. kstr .. '>"') |         let keycode = eval('"\<' .. kstr .. '>"') | ||||||
|  |         " flush out anything in the typeahead buffer | ||||||
|  |         while getchar(0) | ||||||
|  |         endwhile | ||||||
|         " call SendKeyGroup(mod_keycodes + [111+n]) |         " call SendKeyGroup(mod_keycodes + [111+n]) | ||||||
|         call SendKeyWithModifiers(111+n, vim_mod_mask) |         call SendKeyWithModifiers(111+n, vim_mod_mask) | ||||||
|         let ch = getcharstr(0) |         let ch = getcharstr(0) | ||||||
|         let mod_mask = getcharmod() |         let mod_mask = getcharmod() | ||||||
|         """"""  call assert_equal(keycode, $"{ch}", $"key = {kstr}") |         call assert_equal(keycode, $"{ch}", $"key = {kstr}") | ||||||
|         " workaround for the virtual termcap maps changing the character instead |         " workaround for the virtual termcap maps changing the character instead | ||||||
|         " of sending Shift |         " of sending Shift | ||||||
|         for mod_key in mod_keycodes |         for mod_key in mod_keycodes | ||||||
| @@ -519,14 +511,12 @@ func Test_mswin_key_event() | |||||||
|             let mod_mask = mod_mask + s:vim_MOD_MASK_SHIFT |             let mod_mask = mod_mask + s:vim_MOD_MASK_SHIFT | ||||||
|           endif |           endif | ||||||
|         endfor |         endfor | ||||||
|         """"""call assert_equal(vim_mod_mask, mod_mask, $"mod = {vim_mod_mask} for key = {kstr}") |         call assert_equal(vim_mod_mask, mod_mask, $"mod = {vim_mod_mask} for key = {kstr}") | ||||||
|       endfor |       endfor | ||||||
|     endfor |     endfor | ||||||
|   endif |   endif | ||||||
|  |  | ||||||
|   " Test for the various Ctrl and Shift key combinations. |   " Test for the various Ctrl and Shift key combinations. | ||||||
|   " Refer to the following page for the virtual key codes: |  | ||||||
|   " https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes |  | ||||||
|   let keytests = [ |   let keytests = [ | ||||||
|     \ [[s:VK.SHIFT,    s:VK.PRIOR], "S-Pageup", 2], |     \ [[s:VK.SHIFT,    s:VK.PRIOR], "S-Pageup", 2], | ||||||
|     \ [[s:VK.LSHIFT,   s:VK.PRIOR], "S-Pageup", 2], |     \ [[s:VK.LSHIFT,   s:VK.PRIOR], "S-Pageup", 2], | ||||||
| @@ -586,14 +576,13 @@ func Test_mswin_key_event() | |||||||
|     \ [[s:VK.CONTROL,  s:VK.OEM_MINUS], "C-_", 0] |     \ [[s:VK.CONTROL,  s:VK.OEM_MINUS], "C-_", 0] | ||||||
|     \ ] |     \ ] | ||||||
|  |  | ||||||
|   " Not working in CI Testing yet!? |  | ||||||
|   for [kcodes, kstr, kmod] in keytests |   for [kcodes, kstr, kmod] in keytests | ||||||
|     call SendKeyGroup(kcodes) |     call SendKeyGroup(kcodes) | ||||||
|     let ch = getcharstr(0) |     let ch = getcharstr(0) | ||||||
|     let mod = getcharmod() |     let mod = getcharmod() | ||||||
|     let keycode = eval('"\<' .. kstr .. '>"') |     let keycode = eval('"\<' .. kstr .. '>"') | ||||||
| "      call assert_equal(keycode, ch, $"key = {kstr}") |     call assert_equal(keycode, ch, $"key = {kstr}") | ||||||
| "      call assert_equal(kmod, mod, $"mod = {kmod} key = {kstr}") |     call assert_equal(kmod, mod, $"mod = {kmod} key = {kstr}") | ||||||
|   endfor |   endfor | ||||||
|  |  | ||||||
|   bw! |   bw! | ||||||
| @@ -634,8 +623,6 @@ func Test_QWERTY_Ctrl_minus() | |||||||
|   call ExecuteBufferedKeys() |   call ExecuteBufferedKeys() | ||||||
|   call assert_equal('BILBO', getline('$')) |   call assert_equal('BILBO', getline('$')) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   imapclear |   imapclear | ||||||
|   bw! |   bw! | ||||||
| endfunc | endfunc | ||||||
| @@ -953,7 +940,7 @@ func Test_mswin_event_error_handling() | |||||||
|  |  | ||||||
|   call assert_fails("sandbox call test_mswin_event('key', {'event': 'keydown', 'keycode': 61 })", 'E48:') |   call assert_fails("sandbox call test_mswin_event('key', {'event': 'keydown', 'keycode': 61 })", 'E48:') | ||||||
|  |  | ||||||
|   " flush out any garbage left in the buffer. |   " flush out anything in the typeahead buffer | ||||||
|   while getchar(0) |   while getchar(0) | ||||||
|   endwhile |   endwhile | ||||||
| endfunc | endfunc | ||||||
|   | |||||||
| @@ -695,6 +695,8 @@ static char *(features[]) = | |||||||
|  |  | ||||||
| static int included_patches[] = | static int included_patches[] = | ||||||
| {   /* Add new patch number below this line */ | {   /* Add new patch number below this line */ | ||||||
|  | /**/ | ||||||
|  |     1146, | ||||||
| /**/ | /**/ | ||||||
|     1145, |     1145, | ||||||
| /**/ | /**/ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user