/Test/VsVimSharedTest/OleCommandUtilTest.cs

https://github.com/jhamm/VsVim · C# · 265 lines · 198 code · 27 blank · 40 comment · 2 complexity · a5e3e9154005486b87b21e9444f50e34 MD5 · raw file

  1. using System;
  2. using Microsoft.VisualStudio;
  3. using Vim;
  4. using Vim.UnitTest;
  5. using Vim.VisualStudio.UnitTest.Utils;
  6. using Xunit;
  7. namespace Vim.VisualStudio.UnitTest
  8. {
  9. public sealed class OleCommandUtilTest : VimTestBase
  10. {
  11. internal EditCommand ConvertTypeChar(char data)
  12. {
  13. using (var ptr = CharPointer.Create(data))
  14. {
  15. Assert.True(OleCommandUtil.TryConvert(VSConstants.VSStd2K, (uint)VSConstants.VSStd2KCmdID.TYPECHAR, ptr.IntPtr, VimKeyModifiers.None, out EditCommand command));
  16. return command;
  17. }
  18. }
  19. private void VerifyConvertWithShift(VSConstants.VSStd2KCmdID cmd, VimKey vimKey, EditCommandKind kind)
  20. {
  21. var keyInput = KeyInputUtil.ApplyKeyModifiers(KeyInputUtil.VimKeyToKeyInput(vimKey), VimKeyModifiers.Shift);
  22. VerifyConvert(cmd, keyInput, kind);
  23. }
  24. private void VerifyConvert(VSConstants.VSStd2KCmdID cmd, VimKey vimKey, EditCommandKind kind)
  25. {
  26. VerifyConvert(cmd, KeyInputUtil.VimKeyToKeyInput(vimKey), kind);
  27. }
  28. private void VerifyConvert(VSConstants.VSStd2KCmdID cmd, KeyInput ki, EditCommandKind kind)
  29. {
  30. VerifyConvert(cmd, VimKeyModifiers.None, ki, kind);
  31. }
  32. private void VerifyConvert(VSConstants.VSStd2KCmdID cmd, VimKeyModifiers modifiers, KeyInput ki, EditCommandKind kind)
  33. {
  34. Assert.True(OleCommandUtil.TryConvert(VSConstants.VSStd2K, (uint)cmd, IntPtr.Zero, modifiers, out EditCommand command));
  35. Assert.Equal(ki, command.KeyInput);
  36. Assert.Equal(kind, command.EditCommandKind);
  37. }
  38. private void VerifyConvert(VSConstants.VSStd97CmdID cmd, VimKey vimKey, EditCommandKind kind)
  39. {
  40. VerifyConvert(cmd, KeyInputUtil.VimKeyToKeyInput(vimKey), kind);
  41. }
  42. private void VerifyConvert(VSConstants.VSStd97CmdID cmd, KeyInput ki, EditCommandKind kind)
  43. {
  44. Assert.True(OleCommandUtil.TryConvert(VSConstants.GUID_VSStandardCommandSet97, (uint)cmd, IntPtr.Zero, VimKeyModifiers.None, out EditCommand command));
  45. Assert.Equal(ki, command.KeyInput);
  46. Assert.Equal(kind, command.EditCommandKind);
  47. }
  48. /// <summary>
  49. /// Verify we can convert the given VimKey to the specified command id
  50. /// </summary>
  51. private void VerifyConvert(VimKey vimKey, VSConstants.VSStd2KCmdID cmd)
  52. {
  53. var keyInput = KeyInputUtil.VimKeyToKeyInput(vimKey);
  54. Assert.True(OleCommandUtil.TryConvert(keyInput, false, out OleCommandData oleCommandData));
  55. Assert.Equal(VSConstants.VSStd2K, oleCommandData.Group);
  56. Assert.Equal(new OleCommandData(cmd), oleCommandData);
  57. }
  58. /// <summary>
  59. /// Verify the given VimKey converts to the provided command id and vice versa
  60. /// </summary>
  61. private void VerifyBothWays(VSConstants.VSStd2KCmdID cmd, VimKey vimKey, EditCommandKind kind = EditCommandKind.UserInput)
  62. {
  63. VerifyConvert(cmd, vimKey, kind);
  64. }
  65. /// <summary>
  66. /// When processing a raw character we shouldn't be reapplying the existing modifiers. That only needs
  67. /// to be done for non-char commands
  68. ///
  69. /// Issue 961
  70. /// </summary>
  71. [WpfFact]
  72. public void TypeChar_WithModifiers()
  73. {
  74. var source = @"@£$€{[]}\";
  75. var modifiers = VimKeyModifiers.Alt | VimKeyModifiers.Control;
  76. foreach (var c in source)
  77. {
  78. using (var ptr = CharPointer.Create(c))
  79. {
  80. Assert.True(OleCommandUtil.TryConvert(VSConstants.VSStd2K, (uint)VSConstants.VSStd2KCmdID.TYPECHAR, ptr.IntPtr, modifiers, out EditCommand command));
  81. Assert.Equal(c, command.KeyInput.Char);
  82. }
  83. }
  84. }
  85. [WpfFact]
  86. public void ArrowKeys()
  87. {
  88. VerifyConvert(VSConstants.VSStd2KCmdID.LEFT, VimKey.Left, EditCommandKind.UserInput);
  89. VerifyConvert(VSConstants.VSStd2KCmdID.RIGHT, VimKey.Right, EditCommandKind.UserInput);
  90. VerifyConvert(VSConstants.VSStd2KCmdID.UP, VimKey.Up, EditCommandKind.UserInput);
  91. VerifyConvert(VSConstants.VSStd2KCmdID.DOWN, VimKey.Down, EditCommandKind.UserInput);
  92. }
  93. [WpfFact]
  94. public void ArrowKey_WithModifiers()
  95. {
  96. var modifiers = VimKeyModifiers.Alt | VimKeyModifiers.Control;
  97. Assert.True(OleCommandUtil.TryConvert(VSConstants.VSStd2K, (uint)VSConstants.VSStd2KCmdID.LEFT, IntPtr.Zero, modifiers, out EditCommand command));
  98. Assert.Equal(modifiers, command.KeyInput.KeyModifiers);
  99. }
  100. /// <summary>
  101. /// The selection extender versions of the arrow keys should register as commands. Something we
  102. /// shouldn't be processing
  103. /// </summary>
  104. [WpfFact]
  105. public void Selectors_ArrowKeys()
  106. {
  107. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.LEFT_EXT, VimKey.Left, EditCommandKind.VisualStudioCommand);
  108. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.LEFT_EXT_COL, VimKey.Left, EditCommandKind.VisualStudioCommand);
  109. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.RIGHT_EXT, VimKey.Right, EditCommandKind.VisualStudioCommand);
  110. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.RIGHT_EXT_COL, VimKey.Right, EditCommandKind.VisualStudioCommand);
  111. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.UP_EXT, VimKey.Up, EditCommandKind.VisualStudioCommand);
  112. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.UP_EXT_COL, VimKey.Up, EditCommandKind.VisualStudioCommand);
  113. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.DOWN_EXT, VimKey.Down, EditCommandKind.VisualStudioCommand);
  114. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.DOWN_EXT_COL, VimKey.Down, EditCommandKind.VisualStudioCommand);
  115. }
  116. [WpfFact]
  117. public void Selectors_Others()
  118. {
  119. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.PAGEUP_EXT, VimKey.PageUp, EditCommandKind.VisualStudioCommand);
  120. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.PAGEDN_EXT, VimKey.PageDown, EditCommandKind.VisualStudioCommand);
  121. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.EOL_EXT, VimKey.End, EditCommandKind.VisualStudioCommand);
  122. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.EOL_EXT_COL, VimKey.End, EditCommandKind.VisualStudioCommand);
  123. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.BOL_EXT, VimKey.Home, EditCommandKind.VisualStudioCommand);
  124. VerifyConvertWithShift(VSConstants.VSStd2KCmdID.BOL_EXT_COL, VimKey.Home, EditCommandKind.VisualStudioCommand);
  125. }
  126. [WpfFact]
  127. public void Tab()
  128. {
  129. VerifyConvert(VSConstants.VSStd2KCmdID.TAB, KeyInputUtil.TabKey, EditCommandKind.UserInput);
  130. }
  131. [WpfFact]
  132. public void BackTab()
  133. {
  134. VerifyConvert(VSConstants.VSStd2KCmdID.BACKTAB, KeyInputUtil.ApplyKeyModifiers(KeyInputUtil.TabKey, VimKeyModifiers.Shift), EditCommandKind.UserInput);
  135. }
  136. /// <summary>
  137. /// Verify that the shift modifier is properly applied to a tab
  138. /// </summary>
  139. [WpfFact]
  140. public void Tab_WithShift()
  141. {
  142. var keyInput = KeyInputUtil.ApplyKeyModifiers(KeyInputUtil.TabKey, VimKeyModifiers.Shift);
  143. Assert.Equal(VimKeyModifiers.Shift, keyInput.KeyModifiers);
  144. VerifyConvert(VSConstants.VSStd2KCmdID.TAB, VimKeyModifiers.Shift, keyInput, EditCommandKind.UserInput);
  145. }
  146. [WpfFact]
  147. public void F1Help1()
  148. {
  149. VerifyConvert(VSConstants.VSStd97CmdID.F1Help, VimKey.F1, EditCommandKind.UserInput);
  150. }
  151. [WpfFact]
  152. public void Escape()
  153. {
  154. VerifyConvert(VSConstants.VSStd97CmdID.Escape, KeyInputUtil.EscapeKey, EditCommandKind.UserInput);
  155. VerifyConvert(VSConstants.VSStd2KCmdID.CANCEL, KeyInputUtil.EscapeKey, EditCommandKind.UserInput);
  156. }
  157. [WpfFact]
  158. public void PageUp()
  159. {
  160. VerifyConvert(VSConstants.VSStd2KCmdID.PAGEUP, VimKey.PageUp, EditCommandKind.UserInput);
  161. }
  162. [WpfFact]
  163. public void PageDown()
  164. {
  165. VerifyConvert(VSConstants.VSStd2KCmdID.PAGEDN, VimKey.PageDown, EditCommandKind.UserInput);
  166. }
  167. [WpfFact]
  168. public void Backspace()
  169. {
  170. VerifyConvert(VSConstants.VSStd2KCmdID.BACKSPACE, VimKey.Back, EditCommandKind.UserInput);
  171. }
  172. /// <summary>
  173. /// Ensure we can map back and forth every KeyInput value which is considered t obe
  174. /// text input. This is important for intercepting commands
  175. /// </summary>
  176. [WpfFact]
  177. public void TryConvert_TextInputToOleCommandData()
  178. {
  179. var textView = CreateTextView("");
  180. var buffer = Vim.CreateVimBuffer(textView);
  181. buffer.SwitchMode(ModeKind.Insert, ModeArgument.None);
  182. foreach (var cur in KeyInputUtil.VimKeyInputList)
  183. {
  184. if (!buffer.InsertMode.IsDirectInsert(cur))
  185. {
  186. continue;
  187. }
  188. var oleCommandData = OleCommandData.Empty;
  189. try
  190. {
  191. Assert.True(OleCommandUtil.TryConvert(cur, out oleCommandData));
  192. // We lose fidelity on these keys because they both get written out as numbers
  193. // at this point
  194. if (VimKeyUtil.IsKeypadKey(cur.Key))
  195. {
  196. continue;
  197. }
  198. Assert.True(OleCommandUtil.TryConvert(oleCommandData, out KeyInput converted));
  199. Assert.Equal(converted, cur);
  200. }
  201. finally
  202. {
  203. oleCommandData.Dispose();
  204. }
  205. }
  206. }
  207. /// <summary>
  208. /// Make sure the End key converts.
  209. ///
  210. /// Even though the VSStd2KCmdID enumeration defines an END value, it appears to use EOL when
  211. /// the End key is hit.
  212. /// </summary>
  213. [WpfFact]
  214. public void TryConvert_End()
  215. {
  216. VerifyConvert(VSConstants.VSStd2KCmdID.EOL, VimKey.End, EditCommandKind.UserInput);
  217. }
  218. /// <summary>
  219. /// Make sure the Home key converts.
  220. ///
  221. /// Even though the VSStd2KCmdID enumeration defines an HOME value, it appears to use BOL when
  222. /// the Home key is hit.
  223. /// </summary>
  224. [WpfFact]
  225. public void TryConvert_Home()
  226. {
  227. VerifyConvert(VSConstants.VSStd2KCmdID.BOL, VimKey.Home, EditCommandKind.UserInput);
  228. }
  229. /// <summary>
  230. /// Verify we can convert the Insert key in both directions
  231. /// </summary>
  232. [WpfFact]
  233. public void TryConvert_Insert()
  234. {
  235. VerifyBothWays(VSConstants.VSStd2KCmdID.TOGGLE_OVERTYPE_MODE, VimKey.Insert);
  236. }
  237. }
  238. }