From 05b2b4c683264fcdf7c6ef48fc12fcf57ad5bebb Mon Sep 17 00:00:00 2001 From: nosami Date: Sun, 28 May 2017 21:39:43 +0100 Subject: [PATCH] c2w fixes #62 --- XSVim.Tests/ChangeTests.fs | 16 ++++++++++++ XSVim/Properties/AddinInfo.fs | 2 +- XSVim/XSVim.fs | 47 ++++++++++++++++++++--------------- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/XSVim.Tests/ChangeTests.fs b/XSVim.Tests/ChangeTests.fs index 8cfcb0c..414541a 100644 --- a/XSVim.Tests/ChangeTests.fs +++ b/XSVim.Tests/ChangeTests.fs @@ -11,6 +11,22 @@ module ``Change tests`` = let ``cw changes word``() = assertText "a$bc def" "cw" "| def" + [] + let ``cw changes space``() = + assertText "abc $def" "cw" "abc|def" + + [] + let ``c2w changes two words``() = + assertText "a$bc def ghi" "c2w" "| ghi" + + [] + let ``undo works after cw``() = + assertText "a$bc def ghi" "cwu" "a$bc def ghi" + + [] + let ``undo works after c2w``() = + assertText "a$bc def ghi" "c2wu" "a$bc def ghi" + [] let ``ce changes word``() = assertText "a$bc def" "ce" "| def" diff --git a/XSVim/Properties/AddinInfo.fs b/XSVim/Properties/AddinInfo.fs index 2fa7a4d..a5c36d0 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 4014ca7..5d3f672 100755 --- a/XSVim/XSVim.fs +++ b/XSVim/XSVim.fs @@ -356,16 +356,21 @@ module Vim = EditActions.ClipboardCut editor state - let setCaretMode caretMode = - match vimState.mode, caretMode with + let setCaretMode state caretMode = + match state.mode, caretMode with | NotInsertMode, Insert -> EditActions.SwitchCaretMode editor | InsertMode, Block -> EditActions.SwitchCaretMode editor | _ -> () - let switchToInsertMode (editor:TextEditor) state = - let group = editor.OpenUndoGroup() - setCaretMode Insert - { state with mode = InsertMode; statusMessage = "-- INSERT --" |> Some; keys = []; undoGroup = Some group } + let switchToInsertMode (editor:TextEditor) state isInitial = + //let group = state.undoGroup |> Option.orElse (editor.OpenUndoGroup() |> Some) + let group = + if isInitial + then editor.OpenUndoGroup() |> Some + else + state.undoGroup + setCaretMode state Insert + { state with mode = InsertMode; statusMessage = "-- INSERT --" |> Some; keys = []; undoGroup = group } let toggleCase state start finish = if command.textObject <> SelectedText then @@ -382,7 +387,7 @@ module Vim = editor.CaretOffset <- state.visualStartOffset state - let rec processCommands count vimState command = + let rec processCommands count vimState command isInitial = let start, finish = VimHelpers.getRange vimState editor command let newState = match command.commandType with @@ -434,13 +439,18 @@ module Vim = let finish = editor.GetLineByOffset(max).EndOffsetIncludingDelimiter delete vimState start finish | DeleteLeft -> if editor.CaretColumn > 1 then delete vimState (editor.CaretOffset - 1) editor.CaretOffset else vimState - | Change -> + | Change -> + let finish = + if count <> 1 && editor.[finish] = ' ' then + finish + 1 + else + finish let state = if start <> finish then delete vimState start finish else vimState - switchToInsertMode editor state + switchToInsertMode editor state isInitial | Yank -> let finish = match command.textObject with @@ -521,16 +531,16 @@ 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 editor vimState + switchToInsertMode editor vimState isInitial | SwitchMode mode -> match mode with | NormalMode -> editor.ClearSelection() - setCaretMode Block + setCaretMode vimState Block vimState.undoGroup |> Option.iter(fun d -> d.Dispose()) { vimState with mode = mode; undoGroup = None; statusMessage = None } | VisualMode | VisualLineMode | VisualBlockMode -> - setCaretMode Block + setCaretMode vimState Block let start, finish = VimHelpers.getRange vimState editor command let newState = { vimState with mode = mode; visualStartOffset = editor.CaretOffset; statusMessage = None } setSelection newState editor command start finish @@ -540,7 +550,7 @@ module Vim = | _ -> () newState | InsertMode -> - switchToInsertMode editor vimState + switchToInsertMode editor vimState isInitial | Star After -> match wordAtCaret editor with | Some word -> @@ -560,7 +570,7 @@ module Vim = editor.CaretOffset <- offset vimState | None -> - processCommands 1 vimState (runOnce Move WordForwards) + processCommands 1 vimState (runOnce Move WordForwards) isInitial | Star Before -> match wordAtCaret editor with | Some word -> @@ -586,15 +596,12 @@ module Vim = editor.InsertAtCaret c vimState | _ -> vimState - if count = 1 then newState else processCommands (count-1) newState command - let count = - match command.repeat with - | Some r -> r - | None -> 1 + if count = 1 then newState else processCommands (count-1) newState command false + let count = command.repeat |> Option.defaultValue 1 use group = editor.OpenUndoGroup() - processCommands count vimState command + processCommands count vimState command true let (|Digit|_|) character = if character >= "0" && character <= "9" then