public virtual void KeyDown(VimKeyEventArgs args) { bool handled = true; if (_keyInputEvaluation == null) { _keyInputEvaluation = new VimKeyInputEvaluation(this.Host); } IVimAction action = null; string status_char = ""; VimKeyInputEvaluation.KeyEvalState eval_state = _keyInputEvaluation.Evaluate(args.KeyInput, out action, out status_char); if (eval_state == VimKeyInputEvaluation.KeyEvalState.InProcess) { Debug.Assert(status_char != null); if (status_char == VimKeyInputEvaluation.Status_Char_Backspace) { if (_statusText.Length > 0) { _statusText = _statusText.Substring(0, _statusText.Length - 1); } else { Debug.Assert(false); } } else { _statusText += status_char; } this.Host.UpdateStatus(_statusText); } else if (eval_state == VimKeyInputEvaluation.KeyEvalState.Success) { if (action != null) { // TODO live with some actions unimplemented if (action is IVimMotion) { (action as IVimMotion).Move(this.Host); } else if (action is IVimEdititon) { this.DoEdition(action as IVimEdititon); } else { Debug.Assert(false); } } this.ResetKeyValuationStatus(); } else if (eval_state == VimKeyInputEvaluation.KeyEvalState.Escape) { this.ResetKeyValuationStatus(); } else if (eval_state == VimKeyInputEvaluation.KeyEvalState.Error) { if (this.IsSpecialKeyInput(args.KeyInput.Value)) { handled = false; } this.ResetKeyValuationStatus(); } else { Debug.Assert(false); this.ResetKeyValuationStatus(); } args.Handled = handled; }
/// <summary> /// mayby too dedicated to VS's editor /// </summary> /// <param name="args"></param> public virtual void KeyDown(VimKeyEventArgs args) { // important for dealing some unexpected scene bool is_unsupported_key_last_input = false; if (_activeNoneCharKeyInput != NoneCharKeyInputType.None) { if (_activeNoneCharKeyInput == NoneCharKeyInputType.Unsupport) { is_unsupported_key_last_input = true; } else { // extends edition region regarding to last supported special key input if (this.Host.CurrentPosition.CompareTo(_insertArea.End) > 0) { // Key.Enter or Key.Tab _insertArea = _insertArea.ExtendEndTo(this.Host.CurrentPosition); } else { // Key.Backspace if (this.Host.CurrentPosition.CompareTo(_insertArea.Start) > 0) { // still in original insert area _insertArea = _insertArea.ExtendEndTo(this.Host.CurrentPosition); } } } _activeNoneCharKeyInput = NoneCharKeyInputType.None; } if (args.KeyInput.Value.Length == 1) { // KeyDown event is fired up before text's change, so the real position after input should be one char right by current. VimPoint previous_pos = this.Host.CurrentPosition; VimPoint next_pos = new VimPoint(previous_pos.X, previous_pos.Y + 1); if (!is_unsupported_key_last_input) { if (_insertArea.End.CompareTo(previous_pos) <= 0) { // previous_pos may bigger than _insertArea.End in some cases // in normally char input typing, simply extends insert area's end to current position _insertArea = _insertArea.ExtendEndTo(next_pos); } else { // Key.Backspace can invalidate current insert area, so need to renew it _insertArea = new VimSpan(previous_pos, next_pos); } } else { _insertArea = new VimSpan(previous_pos, next_pos); } } else if (args.KeyInput.Value == VimKeyInput.Escape) { if (!is_unsupported_key_last_input) { // Escape after normal key/char input, do some extra checks if (this.Host.CurrentPosition.CompareTo(_insertArea.End) != 0) { // you can't expect to get precise input text here, because everything is under control, but something wrong happened // so we reset the insert area _insertArea = new VimSpan(this.Host.CurrentPosition, this.Host.CurrentPosition); } } this.CausedEdition.Text = this.Host.GetText(_insertArea); this.Host.CurrentMode = PreviousMode; this.Host.DismissDisplayWindows(); // keep consistency with Vim new MotionCaretLeft(this.Host, 1).Move(this.Host); args.Handled = true; } else { _activeNoneCharKeyInput = NoneCharKeyInputType.None; if (this.Host.CurrentPosition.CompareTo(_insertArea.End) == 0) { // speical key input happens at the end of text input area, // we think it's a valid input, save it as a active special key input, // and in the next loop, to deal with it if (args.KeyInput.Value == VimKeyInput.Enter) { _activeNoneCharKeyInput = NoneCharKeyInputType.Enter; } else if (args.KeyInput.Value == VimKeyInput.Tab) { _activeNoneCharKeyInput = NoneCharKeyInputType.Tab; } else if (args.KeyInput.Value == VimKeyInput.Backspace) { _activeNoneCharKeyInput = NoneCharKeyInputType.Backspace; } else { _activeNoneCharKeyInput = NoneCharKeyInputType.Unsupport; } } } }