diff --git a/XSVim.Tests/KeyParsing.fs b/XSVim.Tests/KeyParsing.fs index be80a09..283ff98 100644 --- a/XSVim.Tests/KeyParsing.fs +++ b/XSVim.Tests/KeyParsing.fs @@ -6,7 +6,7 @@ open NUnit.Framework module ``Key parsing tests`` = let test keys = let keys = [for c in keys -> c.ToString()] - let state = { keys=keys; mode=NormalMode; visualStartOffset=0; findCharCommand=None; lastAction=[]; desiredColumn=None} + let state = { keys=keys; mode=NormalMode; visualStartOffset=0; findCharCommand=None; lastAction=[]; desiredColumn=None; undoGroup=None } let action, _state = Vim.parseKeys state let first = action.Head first.repeat, first.commandType, first.textObject diff --git a/XSVim.Tests/MiscTests.fs b/XSVim.Tests/MiscTests.fs index 8ccc864..b20d582 100644 --- a/XSVim.Tests/MiscTests.fs +++ b/XSVim.Tests/MiscTests.fs @@ -37,7 +37,7 @@ module ``Miscellaneous tests`` = [] let ``Undo insert mode``() = - assertText "abc$" "adefu" "abc$" + assertText "abc$" "adef ghi jklu" "abc$" [] diff --git a/XSVim.Tests/TestHelpers.fs b/XSVim.Tests/TestHelpers.fs index 9005c66..5b9f171 100644 --- a/XSVim.Tests/TestHelpers.fs +++ b/XSVim.Tests/TestHelpers.fs @@ -107,12 +107,14 @@ module TestHelpers = editor.CaretOffset <- caret-1 let plugin = new XSVim() - let state = { keys=[]; mode=NormalMode; visualStartOffset=0; findCharCommand=None; lastAction=[]; desiredColumn=None } + let state = { keys=[]; mode=NormalMode; visualStartOffset=0; findCharCommand=None; lastAction=[]; desiredColumn=None; undoGroup=None } let keyDescriptors = parseKeys keys let newState = keyDescriptors |> Array.fold(fun state c -> let newState, handledKeyPress = Vim.handleKeyPress state c editor + if state.mode = InsertMode && c.SpecialKey <> SpecialKey.Escape then + editor.InsertAtCaret (c.KeyChar.ToString()) newState) state let cursor = if newState.mode = InsertMode then "|" else "$" diff --git a/XSVim/Properties/AddinInfo.fs b/XSVim/Properties/AddinInfo.fs index e12eb79..86d6080 100644 --- a/XSVim/Properties/AddinInfo.fs +++ b/XSVim/Properties/AddinInfo.fs @@ -5,7 +5,7 @@ open MonoDevelop [] [] diff --git a/XSVim/XSVim.fs b/XSVim/XSVim.fs index fb8e3d8..29a8318 100755 --- a/XSVim/XSVim.fs +++ b/XSVim/XSVim.fs @@ -105,6 +105,7 @@ type VimState = { findCharCommand: VimAction option // f,F,t or T command to be repeated with ; lastAction: VimAction list // used by . command to repeat the last action desiredColumn: int option + undoGroup: IDisposable option } [] @@ -435,9 +436,10 @@ module Vim = | InsertMode, Block -> EditActions.SwitchCaretMode editor | _ -> () - let switchToInsertMode state = + let switchToInsertMode (editor:TextEditor) state = + let group = editor.OpenUndoGroup() setCaretMode Insert - { state with mode = InsertMode; keys = [] } + { state with mode = InsertMode; keys = []; undoGroup = Some group } let rec processCommands count vimState = let start, finish = VimHelpers.getRange vimState editor command.textObject @@ -483,7 +485,7 @@ module Vim = delete vimState start finish else vimState - switchToInsertMode state + switchToInsertMode editor state | Yank -> let finish = match command.textObject with @@ -556,13 +558,14 @@ module Vim = editor.CaretColumn <- Math.Min(editor.CaretColumn, selectionStartLocation.Column) editor.SetSelection(new DocumentLocation (topLine, selectionStartLocation.Column),new DocumentLocation (bottomLine, selectionStartLocation.Column)) if editor.SelectionMode = SelectionMode.Normal then dispatch TextEditorCommands.ToggleBlockSelectionMode - switchToInsertMode vimState + switchToInsertMode editor vimState | SwitchMode mode -> match mode with | NormalMode -> editor.ClearSelection() setCaretMode Block - { vimState with mode = mode } + vimState.undoGroup |> Option.iter(fun d -> d.Dispose()) + { vimState with mode = mode; undoGroup = None } | VisualMode | VisualLineMode | VisualBlockMode -> setCaretMode Block let start, finish = VimHelpers.getRange vimState editor command.textObject @@ -573,7 +576,8 @@ module Vim = | _, SelectionMode.Block -> dispatch TextEditorCommands.ToggleBlockSelectionMode | _ -> () newState - | InsertMode -> switchToInsertMode vimState + | InsertMode -> + switchToInsertMode editor vimState | _ -> vimState if count = 1 then newState else processCommands (count-1) newState let count = @@ -581,7 +585,8 @@ module Vim = | Some r -> r | None -> 1 - use _group = editor.OpenUndoGroup() + use group = editor.OpenUndoGroup() + processCommands count vimState let (|Digit|_|) character = @@ -839,7 +844,7 @@ type XSVim() = override x.Initialize() = if not (editorStates.ContainsKey x.FileName) then - editorStates.Add(x.FileName, { keys=[]; mode=NormalMode; visualStartOffset=0; findCharCommand=None; lastAction=[]; desiredColumn=None }) + editorStates.Add(x.FileName, { keys=[]; mode=NormalMode; visualStartOffset=0; findCharCommand=None; lastAction=[]; desiredColumn=None; undoGroup=None }) EditActions.SwitchCaretMode x.Editor disposable <- Some (IdeApp.Workbench.DocumentClosed.Subscribe (fun e -> let documentName = e.Document.Name