public void DisableAll() { _vimBuffer1.Process(GlobalSettings.DisableAllCommand); Assert.Equal(ModeKind.Disabled, _vimBuffer1.ModeKind); Assert.Equal(ModeKind.Disabled, _vimBuffer2.ModeKind); Assert.True(Vim.IsDisabled); }
/// <summary> /// Try and process the KeyInput from the Exec method /// </summary> private bool TryExec(ref Guid commandGroup, ref OleCommandData oleCommandData, KeyInput keyInput) { if (!_buffer.CanProcess(keyInput)) { // If the IVimBuffer can't process it then it doesn't matter return(false); } // Next we need to determine if we can process this directly or not. The only mode // we actively intercept KeyInput for is InsertMode because we need to route it // through IOleCommandTarget to get Intellisense and many other features. var mode = _buffer.ModeKind == ModeKind.Insert ? _buffer.InsertMode : null; if (mode == null) { return(_buffer.Process(keyInput)); } // Next we need to consider here are Key mappings. The CanProcess and Process APIs // will automatically map the KeyInput under the hood at the IVimBuffer level but // not at the individual IMode. Have to manually map here and test against the // mapped KeyInput KeyInput mapped; if (!TryGetSingleMapping(KeyRemapMode.Insert, keyInput, out mapped) || CanProcessDirectly(mode, mapped)) { return(_buffer.Process(keyInput)); } // At this point we've determined that we need to intercept this return(TryExecIntercepted(ref commandGroup, ref oleCommandData, keyInput, mapped)); }
/// <summary> /// Last chance at custom handling of user input. At this point we have the /// advantage that WPF has properly converted the user input into a char which /// can be effeciently mapped to a KeyInput value. /// </summary> public override void TextInput(TextCompositionEventArgs args) { bool handled = false; if (!String.IsNullOrEmpty(args.Text) && 1 == args.Text.Length && !IgnoreTextInput) { // Only want to intercept text coming from the keyboard. Let other // components edit without having to come through us var keyboard = args.Device as KeyboardDevice; if (keyboard != null) { var ki = KeyUtil.CharAndModifiersToKeyInput(args.Text[0], keyboard.Modifiers); handled = _buffer.CanProcess(ki) && _buffer.Process(ki); } } if (handled) { args.Handled = true; } else { base.TextInput(args); } }
/// <summary> /// The PreviewKeyDown event is raised before Visual Assist handles a key stroke and they respect the /// Handled property of the KeyEventArgs structure. This is our chance to intercept any keys that /// they will process in a way that conflicts with VsVim /// </summary> public override void PreviewKeyDown(KeyEventArgs args) { VimTrace.TraceInfo("VisualAssistKeyProcessor::PreviewKeyDown {0} {1}", args.Key, args.KeyboardDevice.Modifiers); if (IsTextViewFocused && _vimBuffer.ModeKind == ModeKind.Normal && args.Key == Key.OemPeriod && args.KeyboardDevice.Modifiers == ModifierKeys.None) { // Visual Assist in general won't process any keys when we are in normal mode because we have // the caret hidden. However it appears they check for the caret hidden on a timer or some // form of delay. This is provable by editting some text in insert mode then quickly hitting // Escape followed by '.'. If this happens fast enough they will process the '.' directly // instead of letting the key stroke go through. This will cause a '.' to appear in the code // instead of a repeat action. // // Experimentation shows that they only do this processing for a subset of keys including // '.'. Letter keys and the like don't have this behavior so we let them go through // normal processing. In the future though we may find more keys that need this exception _vimBuffer.Process(KeyInputUtil.CharToKeyInput('.')); args.Handled = true; } VimTrace.TraceInfo("VisualAssistKeyProcessor::KeyDown Handled = {0}", args.Handled); base.PreviewKeyDown(args); }
/// <summary> /// This method handles the KeyInput as it applies to command line editor. Make sure to /// mark the key as handled if we use it here. If we don't then it will propagate out to /// the editor and be processed again /// </summary> internal void HandleKeyEvent(KeyEventArgs e) { switch (e.Key) { case Key.Escape: _vimBuffer.Process(KeyInputUtil.EscapeKey); ChangeEditKind(EditKind.None); e.Handled = true; break; case Key.Return: ExecuteCommand(_margin.CommandLineTextBox.Text); e.Handled = true; break; case Key.Up: _vimBuffer.Process(KeyInputUtil.VimKeyToKeyInput(VimKey.Up)); e.Handled = true; break; case Key.Down: _vimBuffer.Process(KeyInputUtil.VimKeyToKeyInput(VimKey.Down)); e.Handled = true; break; } }
public void Repeat_Insert() { Create("the cat"); _buffer.SwitchMode(ModeKind.Insert, ModeArgument.NewInsertWithCount(2)); _buffer.Process("hi"); Assert.AreEqual(2, _textView.GetCaretPoint().Position); _buffer.Process(VimKey.Escape); Assert.AreEqual("hihithe cat", _textView.GetLine(0).GetText()); Assert.AreEqual(3, _textView.GetCaretPoint().Position); }
public static void Process(this IVimBuffer buf, string input, bool enter = false) { foreach (var c in input) { var i = KeyInputUtil.CharToKeyInput(c); buf.Process(i); } if (enter) { buf.Process(KeyInputUtil.EnterKey); } }
/// <summary> /// Try and process the KeyInput from the Exec method /// </summary> private bool TryProcessWithBuffer(ref Guid commandGroup, ref OleCommandData oleCommandData, KeyInput keyInput) { if (!_buffer.CanProcess(keyInput)) { // If the IVimBuffer can't process it then it doesn't matter return(false); } // Next we need to determine if we can process this directly or not. The only mode // we actively intercept KeyInput for is InsertMode because we need to route it // through IOleCommandTarget to get Intellisense and many other features. var insertMode = _buffer.ModeKind == ModeKind.Insert ? _buffer.InsertMode : null; if (insertMode == null) { return(_buffer.Process(keyInput).IsAnyHandled); } // Next we need to consider here are Key mappings. The CanProcess and Process APIs // will automatically map the KeyInput under the hood at the IVimBuffer level but // not at the individual IMode. Have to manually map here and test against the // mapped KeyInput KeyInput mapped; if (!TryGetSingleMapping(keyInput, out mapped) || !ShouldProcessWithCommandTargetOverInsertMode(insertMode, mapped)) { return(_buffer.Process(keyInput).IsAnyHandled); } // We are now intentionally by passing insert mode here. If there is an active // IWordCompletionSession here we need to manually dismiss it. Else it will remain // as we start typing a new word if (insertMode.ActiveWordCompletionSession.IsSome()) { insertMode.ActiveWordCompletionSession.Value.Dismiss(); } // We've successfully mapped the KeyInput (even if t's a no-op) and determined that // we don't want to process it directly if possible. Now we try and process the // potentially mapped value if (TryProcessWithExec(commandGroup, oleCommandData, insertMode, keyInput, mapped)) { return(true); } // If we couldn't map the KeyInput value into a Visual Studio command then go straight to the // ITextBuffer. Insert mode is already designed to handle these KeyInput values we'd just prefer // to pass them through Visual Studio.. Remember to use the original KeyInput value here as // going through IVimBuffer will process mappings return(_buffer.Process(keyInput).IsAnyHandled); }
public void Timeout_Single() { _vimBuffer.Vim.KeyMap.MapWithNoRemap("cat", "chase the cat", KeyRemapMode.Insert); _vimBuffer.SwitchMode(ModeKind.Insert, ModeArgument.None); _vimBuffer.Process('c'); Assert.Equal("", _vimBuffer.TextBuffer.GetLine(0).GetText()); WaitForTimer(); Assert.Equal("c", _vimBuffer.TextBuffer.GetLine(0).GetText()); }
public void Timeout_Single() { _vimBuffer.Vim.GlobalKeyMap.AddKeyMapping("cat", "chase the cat", allowRemap: false, KeyRemapMode.Insert); _vimBuffer.SwitchMode(ModeKind.Insert, ModeArgument.None); _vimBuffer.Process('c'); Assert.Equal("", _vimBuffer.TextBuffer.GetLine(0).GetText()); WaitForTimer(); Assert.Equal("c", _vimBuffer.TextBuffer.GetLine(0).GetText()); }
internal static void Process(this IVimBuffer vimBuffer, string input, bool enter = false) { foreach (var c in input) { var keyInput = KeyInputUtil.CharToKeyInput(c); vimBuffer.Process(keyInput); } if (enter) { vimBuffer.Process(KeyInputUtil.EnterKey); } }
/// <summary> /// Process the full notation as a series of KeyInput values /// </summary> public static void ProcessNotation(this IVimBuffer vimBuffer, string notation, bool enter = false) { var keyInputSet = KeyNotationUtil.StringToKeyInputSet(notation); foreach (var keyInput in keyInputSet.KeyInputs) { vimBuffer.Process(keyInput); } if (enter) { vimBuffer.Process(KeyInputUtil.EnterKey); } }
public override void PreviewKeyUp(KeyEventArgs args) { if (args.Key == Key.Escape) { // The Escape key was pressed and we are still inside of Insert mode. This means that R# // handled the key stroke to dismiss intellisense. Leave insert mode now to complete the operation if (_vimBuffer.ModeKind == ModeKind.Insert) { VimTrace.TraceInfo("ReSharperKeyUtil::PreviewKeyUp handled escape swallowed by ReSharper"); _vimBuffer.Process(KeyInputUtil.EscapeKey); } } base.PreviewKeyUp(args); }
public void MappedLeft() { // Reported in issue #1103. var command = "%s//g"; _vimBuffer.Process($":map Q :{command}<Left><Left>", enter: true); Assert.Equal(ModeKind.Normal, _vimBuffer.ModeKind); _vimBuffer.Process("Q"); Assert.Equal(ModeKind.Command, _vimBuffer.ModeKind); var expectedCaretPosition = command.Length - 2; var expectedCommand = new EditableCommand(command, expectedCaretPosition); Assert.Equal(expectedCommand, _vimBuffer.CommandMode.EditableCommand); Assert.Equal(":" + command, _control.CommandLineTextBox.Text); Assert.Equal(expectedCaretPosition + 1, _control.CommandLineTextBox.SelectionStart); }
/// <summary> /// The escape key was pressed. If we are currently in insert mode we need to leave it because it /// means that Visual Assist swallowed the key stroke /// </summary> private void HandleEscape() { if (_vimBuffer.ModeKind == ModeKind.Insert) { _vimBuffer.Process(KeyInputUtil.EscapeKey); } }
internal bool TryProcess(VimKey vimKey, int clickCount = 1) { var keyInput = KeyInputUtil.ApplyKeyModifiersToKey(vimKey, _keyboardDevice.KeyModifiers); keyInput = KeyInputUtil.ApplyClickCount(keyInput, clickCount); // If the user has explicitly set the mouse to be <nop> then we don't want to report this as // handled. Otherwise it will swallow the mouse event and as a consequence disable other // features that begin with a mouse click. // // There is really no other way for the user to opt out of mouse behavior besides mapping the // key to <nop> otherwise that would be done here. var keyInputSet = _vimBuffer.GetKeyInputMapping(keyInput).KeyInputSet; if (keyInputSet.Length > 0 && keyInputSet.KeyInputs[0].Key == VimKey.Nop) { return(false); } if (_vimBuffer.CanProcess(keyInput)) { return(_vimBuffer.Process(keyInput).IsAnyHandled); } return(false); }
/// <summary> /// This method handles the KeyInput as it applies to command line editor. Make sure to /// mark the key as handled if we use it here. If we don't then it will propagate out to /// the editor and be processed again /// </summary> internal void HandleKeyEvent(KeyEventArgs e) { switch (e.Key) { case Key.Escape: _vimBuffer.Process(KeyInputUtil.EscapeKey); ChangeEditKind(EditKind.None); e.Handled = true; break; case Key.Return: // ExecuteCommand(_margin.CommandLineTextBox.Text); ExecuteCommand(_commandText); e.Handled = true; break; case Key.Up: _vimBuffer.Process(KeyInputUtil.VimKeyToKeyInput(VimKey.Up)); e.Handled = true; break; case Key.Down: _vimBuffer.Process(KeyInputUtil.VimKeyToKeyInput(VimKey.Down)); e.Handled = true; break; case Key.R: if (e.KeyboardDevice.Modifiers == ModifierKeys.Control) { // During edits we are responsible for handling the command line. Need to // put a " into the box at the edit position // var textBox = _margin.CommandLineTextBox; // var text = textBox.Text; // var builder = new StringBuilder(); // var offset = textBox.SelectionStart; // builder.Append(text, 0, offset); // builder.Append('"'); // builder.Append(text, offset, text.Length - offset); // UpdateCommandLine(builder.ToString()); // textBox.Select(offset, 0); // Now move the buffer into paste wait _vimBuffer.Process(KeyInputUtil.ApplyKeyModifiersToChar('r', VimKeyModifiers.Control)); } break; case Key.U: if (e.KeyboardDevice.Modifiers == ModifierKeys.Control) { // var textBox = _margin.CommandLineTextBox; // var text = textBox.Text.Substring(textBox.SelectionStart); // textBox.Text = text; // // UpdateVimBufferStateWithCommandText(text); } break; } }
/// <summary> /// Process the VimKey values in sequence /// </summary> public static bool Process(this IVimBuffer buf, params VimKey[] keys) { var ret = false; foreach (var key in keys) { ret = buf.Process(KeyInputUtil.VimKeyToKeyInput(key)).IsAnyHandled; } return(ret); }
internal bool TryProcess(VimKey vimKey) { var keyInput = KeyInputUtil.VimKeyToKeyInput(vimKey); if (_vimBuffer.CanProcess(keyInput)) { return(_vimBuffer.Process(keyInput).IsAnyHandled); } return(false); }
public void TypeForwardShouldReplace() { Create("hello world"); _buffer.SwitchMode(ModeKind.Replace, ModeArgument.None); _buffer.Process("again"); Assert.AreEqual("again world", _textView.GetLine(0).GetText()); Assert.AreEqual(5, _textView.GetCaretPoint().Position); }
private bool TryProcess(KeyEventArgs e, KeyInput keyInput) { if (KeyEventIsDeadChar(e)) { // When a dead key combination is pressed we will get the key down events in // sequence after the combination is complete. The dead keys will come first // and be followed the final key which produces the char. That final key // is marked as DeadCharProcessed. // // All of these should be ignored. They will produce a TextInput value which // we can process in the TextInput event return(false); } if ((_vimBuffer.ModeKind.IsAnyInsert() || _vimBuffer.ModeKind.IsAnySelect()) && !_vimBuffer.CanProcessAsCommand(keyInput) && keyInput.Char > 0x1f && _vimBuffer.BufferedKeyInputs.IsEmpty && !_vimBuffer.Vim.MacroRecorder.IsRecording) { return(false); } if (_completionBroker.IsCompletionActive(_textView) && !IsEscapeKey(e)) { return(false); } if (_signatureHelpBroker.IsSignatureHelpActive(_textView) && !IsEscapeKey(e)) { return(false); } if (_inlineRenameListenerFactory.InRename) { return(false); } if (_vimBuffer.ModeKind.IsAnyInsert() && e.Characters == "\t") { // Allow tab key to work for snippet completion // // TODO: We should only really do this when the characters // to the left of the caret form a valid snippet return(false); } return(_vimBuffer.CanProcess(keyInput) && _vimBuffer.Process(keyInput).IsAnyHandled); }
public void KeyMap_ShiftAndReturn() { Create("cat", "dog"); _vimBuffer.Process(":map <S-RETURN> o<Esc>", enter: true); _simulation.Run(KeyInputUtil.ApplyModifiersToVimKey(VimKey.Enter, KeyModifiers.Shift)); Assert.Equal(3, _textBuffer.CurrentSnapshot.LineCount); Assert.Equal("cat", _textBuffer.GetLine(0).GetText()); Assert.Equal("", _textBuffer.GetLine(1).GetText()); Assert.Equal("dog", _textBuffer.GetLine(2).GetText()); }
/// <summary> /// This method handles keeping the history buffer in sync with the commandline display text /// which do not happen otherwise for EditKind.None. /// </summary> private bool HandleHistoryNavigation(KeyInput keyInput) { var handled = _vimBuffer.Process(keyInput).IsAnyHandled; var prefixChar = GetPrefixChar(_editKind); if (handled && _editKind != EditKind.None && prefixChar.HasValue) { switch (_editKind) { case EditKind.Command: UpdateCommandLine(prefixChar.ToString() + _vimBuffer.CommandMode.Command); break; case EditKind.SearchForward: case EditKind.SearchBackward: UpdateCommandLine(prefixChar.ToString() + _vimBuffer.IncrementalSearch.CurrentSearchText); break; } _margin.UpdateCaretPosition(EditPosition.End); } return(handled); }
public static bool Process(this IVimBuffer buf, VimKey key) { return(buf.Process(KeyInputUtil.VimKeyToKeyInput(key))); }
private void RunCommand(string command) { _buffer.Process(':'); _buffer.Process(command, enter: true); }
public void TestChar_h_1() { _textView.Caret.MoveTo(new SnapshotPoint(_textView.TextSnapshot, 2)); _buffer.Process('h'); Assert.Equal(1, _textView.Caret.Position.BufferPosition.Position); }
/// <summary> /// Try and process the KeyInput from the Exec method. This method decides whether or not /// a key should be processed directly by IVimBuffer or if should be going through /// IOleCommandTarget. Generally the key is processed by IVimBuffer but for many intellisense /// scenarios we want the key to be routed to Visual Studio directly. Issues to consider /// here are ... /// /// - How should the KeyInput participate in Macro playback? /// - Does both VsVim and Visual Studio need to process the key (Escape mainly) /// /// </summary> private bool TryProcessWithBuffer(KeyInput keyInput) { // If the IVimBuffer can't process it then it doesn't matter if (!_vimBuffer.CanProcess(keyInput)) { return(false); } // In the middle of a word completion session let insert mode handle the input. It's // displaying the intellisense itself and this method is meant to let custom intellisense // operate normally if (_vimBuffer.ModeKind == ModeKind.Insert && _vimBuffer.InsertMode.ActiveWordCompletionSession.IsSome()) { return(_vimBuffer.Process(keyInput).IsAnyHandled); } // If we are in a peek definition window and normal mode we need to let the Escape key // pass on to the next command target. This is necessary to close the peek definition // window if (_vimBuffer.ModeKind == ModeKind.Normal && _textView.IsPeekView() && keyInput == KeyInputUtil.EscapeKey) { return(false); } // The only time we actively intercept keys and route them through IOleCommandTarget // is when one of the IDisplayWindowBroker windows is active // // In those cases if the KeyInput is a command which should be handled by the // display window we route it through IOleCommandTarget to get the proper // experience for those features if (!_broker.IsAnyDisplayActive()) { return(_vimBuffer.Process(keyInput).IsAnyHandled); } // Next we need to consider here are Key mappings. The CanProcess and Process APIs // will automatically map the KeyInput under the hood at the IVimBuffer level but // not at the individual IMode. Have to manually map here and test against the // mapped KeyInput if (!TryGetSingleMapping(keyInput, out KeyInput mapped)) { return(_vimBuffer.Process(keyInput).IsAnyHandled); } bool handled; if (IsDisplayWindowKey(mapped)) { // If the key which actually needs to be processed is a display window key, say // down, up, etc..., then forward it on to the next IOleCommandTarget. It is responsible // for mapping that key to action against the display window handled = ErrorHandler.Succeeded(_nextOleCommandTarget.Exec(mapped)); } else { // Intentionally using keyInput here and not mapped. Process will do mapping on the // provided input hence we should be using the original keyInput here not mapped handled = _vimBuffer.Process(keyInput).IsAnyHandled; } // The Escape key should always dismiss the active completion session. However Vim // itself is mostly ignorant of display windows and typically won't dismiss them // as part of processing Escape (one exception is insert mode). Dismiss it here if // it's still active if (mapped.Key == VimKey.Escape && _broker.IsAnyDisplayActive()) { _broker.DismissDisplayWindows(); } return(handled); }
/// <summary> /// Try and process the given KeyInput with the IVimBuffer. This is overridable by /// derived classes in order for them to prevent any KeyInput from reaching the /// IVimBuffer /// </summary> protected virtual bool TryProcess(KeyInput keyInput) { return(_vimBuffer.CanProcess(keyInput) && _vimBuffer.Process(keyInput).IsAnyHandled); }
public void SwitchModeOneTimeCommand_SetProperty() { var mode = CreateAndAddInsertMode(MockBehavior.Loose); mode.Setup(x => x.Process(It.IsAny <KeyInput>())).Returns(ProcessResult.NewHandled(ModeSwitch.SwitchModeOneTimeCommand)); _vimBuffer.SwitchMode(ModeKind.Insert, ModeArgument.None); _vimBuffer.Process('c'); Assert.IsTrue(_vimBuffer.InOneTimeCommand.IsSome(ModeKind.Insert)); }
public static bool Process(this IVimBuffer buf, char c) { return(buf.Process(KeyInputUtil.CharToKeyInput(c)).IsAnyHandled); }