Skip to content

Commit

Permalink
Add substitute command mode. Fixes #191
Browse files Browse the repository at this point in the history
  • Loading branch information
nosami committed Jun 25, 2018
1 parent 3c4446d commit fdec866
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 5 deletions.
5 changes: 5 additions & 0 deletions XSVim.Tests/ExModeTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,8 @@ module ``Ex mode tests`` =

"""11111
5$5555"""

[<Test>]
let ``Switching to substitute command mode with a selection``() =
let _, state, _ = test "a$bc" "v:"
state.statusMessage |> should equal (Some ":'<,'>")
18 changes: 18 additions & 0 deletions XSVim/ExMode.fs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
namespace XSVim
open System
open System.Text.RegularExpressions
open MonoDevelop.Core
open MonoDevelop.Core.ProgressMonitoring
open MonoDevelop.Ide
open MonoDevelop.Ide.Commands
open MonoDevelop.Ide.Editor.Extension
Expand Down Expand Up @@ -34,6 +36,18 @@ module exMode =
else
None

let (|Substitute|_|) input =
let matches = Regex.Matches(input, "(.*)s/(.*)/(.*)", RegexOptions.Compiled)
if matches.Count = 1 then
let m = matches.[0]
match m.Groups.[1].Value with
| "%" -> Some { find = m.Groups.[2].Value; replace = m.Groups.[3].Value; scope = Document }
| "'<,'>" -> Some { find = m.Groups.[2].Value; replace = m.Groups.[3].Value; scope = Selection }
| _ -> None
else
None


let processKey (state:VimState) (key:KeyDescriptor) =
let setMessage message = { state with statusMessage = message }
let normalMode = { state with statusMessage = None; mode = NormalMode }
Expand Down Expand Up @@ -132,6 +146,10 @@ module exMode =
[ runOnce Move (Jump (StartOfLineNumber startLine))
runOnce DeleteWholeLines (Jump (StartOfLineNumber endLine)) ]
normalMode, actions
| Substitute substition ->
match Substitute.substitute substition with
| true -> normalMode, resetKeys
| false -> state, resetKeys
| _ ->
{ state with statusMessage = sprintf "Could not parse :%s" rest |> Some; mode = NormalMode; }
, resetKeys
Expand Down
2 changes: 1 addition & 1 deletion XSVim/Properties/AssemblyInfo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ open System.Runtime.CompilerServices
[<AutoOpen>]
module AddinVersion =
[<Literal>]
let version = "0.60.6"
let version = "0.61.0"

[<assembly: AssemblyTitle("XSVim")>]
// The assembly version has the format {Major}.{Minor}.{Build}.{Revision}
Expand Down
43 changes: 43 additions & 0 deletions XSVim/SubstituteCommand.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace XSVim
open System
open MonoDevelop.Core
open MonoDevelop.Core.ProgressMonitoring
open MonoDevelop.Ide
open MonoDevelop.Ide.FindInFiles

type SubstituteScope = Selection | Document

type Substitution = { find: string; replace: string; scope: SubstituteScope }

module Substitute =
let substitute substitution =
let find = FindInFiles.FindReplace()
let options = FindInFiles.FilterOptions()
options.RegexSearch <- true
if not(find.ValidatePattern(options, substitution.find)) then
MessageService.ShowError (GettextCatalog.GetString ("Search pattern is invalid"));
false
elif not(find.ValidatePattern(options, substitution.replace)) then
MessageService.ShowError (GettextCatalog.GetString ("Replace pattern is invalid"));
false
else
use monitor =
match IdeApp.Workbench with
| null -> new ConsoleProgressMonitor() :> ProgressMonitor
| workbench ->
let monitor = workbench.ProgressMonitors.GetSearchProgressMonitor (true)
monitor.PathMode <- PathMode.Hidden
monitor :> ProgressMonitor
let scope =
match substitution.scope with
| Document -> DocumentScope() :> Scope
| Selection -> SelectionScope() :> Scope

find.FindAll(scope, monitor, substitution.find, substitution.replace, options, Threading.CancellationToken.None)
|> Seq.iter(fun res ->
match monitor with
| :? SearchProgressMonitor as mon ->
mon.ReportResult res
| _ -> printfn "%A" res)

true
2 changes: 1 addition & 1 deletion XSVim/Types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type VimMode =
| VisualLineMode
| InsertMode
| ReplaceMode
| ExMode of char // initial char typed to get to command line
| ExMode of string // initial char typed to get to command line


type MoveRightBehaviour = StopAtEndOfLine | MoveToNextLineAtEnd | IncludeDelimiter
Expand Down
7 changes: 4 additions & 3 deletions XSVim/XSVim.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1522,9 +1522,10 @@ module Vim =
| NotInsertMode, [ "*" ] -> [ run (Star After) Nothing ]
| NotInsertMode, [ "#" ] -> [ run (Star Before) Nothing ]
| NotInsertMode, [ "£" ] -> [ run (Star Before) Nothing ]
| NotInsertMode, [ SearchChar c ] -> [ switchMode (ExMode c); runOnce (SetSearchAction Move) Nothing ]
| NotInsertMode, [ ":" ] -> [ switchMode (ExMode ':') ]
| NotInsertMode, [ Action action; SearchChar c ] -> [ switchMode (ExMode c); runOnce (SetSearchAction action) Nothing ]
| NotInsertMode, [ SearchChar c ] -> [ switchMode (ExMode (string c)); runOnce (SetSearchAction Move) Nothing ]
| VisualModes, [ ":" ] -> [ switchMode (ExMode ":'<,'>") ]
| NotInsertMode, [ ":" ] -> [ switchMode (ExMode ":") ]
| NotInsertMode, [ Action action; SearchChar c ] -> [ switchMode (ExMode (string c)); runOnce (SetSearchAction action) Nothing ]
| NormalMode, [ "z"; "z" ] -> [ dispatch ViewCommands.CenterAndFocusCurrentDocument ]
| NormalMode, [ "z"; ] -> wait
| NormalMode, [ "<C-y>" ] -> [ dispatch TextEditorCommands.ScrollLineUp ]
Expand Down
1 change: 1 addition & 0 deletions XSVim/XSVim.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
<Compile Include="Classes.fs" />
<Compile Include="Types.fs" />
<Compile Include="WindowManagement.fs" />
<Compile Include="SubstituteCommand.fs" />
<Compile Include="ExMode.fs" />
<Compile Include="PadTreeViews.fs" />
<Compile Include="TreeViewPads.fs" />
Expand Down

0 comments on commit fdec866

Please sign in to comment.