From 0a77f75839f9fca6d0b6d1862c135c179c41716d Mon Sep 17 00:00:00 2001 From: nosami Date: Sun, 29 Apr 2018 02:37:23 +0100 Subject: [PATCH] Initial jk support for search results pad. Re #193 --- XSVim/Addin.fs | 23 +++++++++++++++-- XSVim/Properties/AssemblyInfo.fs | 2 +- XSVim/Reflection.fs | 33 +++++++++++++++---------- XSVim/SearchResultsPad.fs | 42 ++++++++++++++++++++++++++++++++ XSVim/XSVim.fsproj | 1 + 5 files changed, 85 insertions(+), 16 deletions(-) create mode 100644 XSVim/SearchResultsPad.fs diff --git a/XSVim/Addin.fs b/XSVim/Addin.fs index ece324f..3b7fd41 100644 --- a/XSVim/Addin.fs +++ b/XSVim/Addin.fs @@ -3,17 +3,17 @@ open System open System.Collections.Generic open MonoDevelop.Components.Commands open MonoDevelop.Core -open MonoDevelop.Core.Text open MonoDevelop.Ide open MonoDevelop.Ide.Editor open MonoDevelop.Ide.Editor.Extension +open MonoDevelop.Ide.FindInFiles type XSVim() = inherit TextEditorExtension() let mutable disposables : IDisposable list = [] let mutable processingKey = false let mutable config = { insertModeEscapeKey = None } - + let searchPads = HashSet() let initConfig() = let mapping = SettingsPanel.InsertModeEscapeMapping() if mapping.Length = 2 then @@ -26,6 +26,24 @@ type XSVim() = else config <- { insertModeEscapeKey = None } + let initializeSearchResultsPads() = + IdeApp.Workbench + |> Option.ofObj + |> Option.iter(fun workbench -> + workbench.Pads + |> Seq.iter(fun pad -> + try + // fetching pad.Content can throw when there is an exception + // when initializing the pad + tryUnbox pad.Content + |> Option.iter(fun pad -> + let padId = pad.Window.Id + if not (searchPads.Contains padId) then + searchPads.Add padId |> ignore + searchResultsPad.initialize pad) + with + | _ -> ())) + member x.FileName = x.Editor.FileName.FullPath.ToString() member x.State @@ -34,6 +52,7 @@ type XSVim() = override x.Initialize() = treeViewPads.initialize() + x.Editor.FocusLost.Add(fun _ -> initializeSearchResultsPads()) initConfig() if not (Vim.editorStates.ContainsKey x.FileName) then diff --git a/XSVim/Properties/AssemblyInfo.fs b/XSVim/Properties/AssemblyInfo.fs index 408064c..ba44cef 100644 --- a/XSVim/Properties/AssemblyInfo.fs +++ b/XSVim/Properties/AssemblyInfo.fs @@ -5,7 +5,7 @@ open System.Runtime.CompilerServices [] module AddinVersion = [] - let version = "0.53.1" + let version = "0.54.1.1" [] // The assembly version has the format {Major}.{Minor}.{Build}.{Revision} diff --git a/XSVim/Reflection.fs b/XSVim/Reflection.fs index ac2e33b..efff20c 100644 --- a/XSVim/Reflection.fs +++ b/XSVim/Reflection.fs @@ -37,9 +37,9 @@ module Reflection = // Static member call (on value of type System.Type)? if (typeof).IsAssignableFrom(o.GetType()) then - let methods = (unbox o).GetMethods(staticFlags) |> Array.map asMethodBase - let ctors = (unbox o).GetConstructors(ctorFlags) |> Array.map asMethodBase - Array.concat [ methods; ctors ], null, args + let methods = (unbox o).GetMethods(staticFlags) |> Array.map asMethodBase + let ctors = (unbox o).GetConstructors(ctorFlags) |> Array.map asMethodBase + Array.concat [ methods; ctors ], null, args else o.GetType().GetMethods(instanceFlags) |> Array.map asMethodBase, o, args @@ -60,8 +60,8 @@ module Reflection = // The result type is not an F# function, so we're getting a property // When the 'o' object is 'System.Type', we access static properties let typ, flags, instance = - if (typeof).IsAssignableFrom(o.GetType()) - then unbox o, staticFlags, null + if (typeof).IsAssignableFrom(o.GetType()) + then unbox o, staticFlags, null else o.GetType(), instanceFlags, o // Find a property that we can call and get the value @@ -71,17 +71,24 @@ module Reflection = let nested = typ.Assembly.GetType(typ.FullName + "+" + name) // Return nested type if we found one if nested = null then - failwithf "Property or nested type '%s' not found in '%s'." name typ.Name + failwithf "Property nested type '%s' not found in '%s'." name typ.Name elif not ((typeof<'R>).IsAssignableFrom(typeof)) then - let rname = (typeof<'R>.Name) - failwithf "Cannot return nested type '%s' as a type '%s'." nested.Name rname + let rname = (typeof<'R>.Name) + failwithf "Cannot return nested type '%s' as a type '%s'." nested.Name rname else nested |> box |> unbox<'R> else - // Call property and return result if we found some - let meth = prop.GetGetMethod(true) - if prop = null then failwithf "Property '%s' found, but doesn't have 'get' method." name - try meth.Invoke(instance, [| |]) |> unbox<'R> - with _ -> failwithf "Failed to get value of '%s' property (of type '%s')" name typ.Name + if prop = null then + // if we didn't find a nested type then search for a field + let field = typ.GetField(name, flags) + if not (isNull field) then + field.GetValue(o) |> unbox<'R> + else + failwithf "Property '%s' found, but doesn't have 'get' method." name + else + // Call property and return result if we found some + let meth = prop.GetGetMethod(true) + try meth.Invoke(instance, [| |]) |> unbox<'R> + with _ -> failwithf "Failed to get value of '%s' property (of type '%s')" name typ.Name let (?<-) (this:obj) (property:string) (value:'Value) = this.GetType().GetProperty(property).SetValue(this, value, null) diff --git a/XSVim/SearchResultsPad.fs b/XSVim/SearchResultsPad.fs new file mode 100644 index 0000000..1c03132 --- /dev/null +++ b/XSVim/SearchResultsPad.fs @@ -0,0 +1,42 @@ +namespace XSVim +open System +open Gtk +open MonoDevelop.Ide.FindInFiles +open MonoDevelop.Ide.Gui.Components +open Reflection + +module searchResultsPad = + let select (tree:TreeView) path = + let column = tree.Columns.[0] + tree.Selection.SelectPath path + tree.SetCursor(path, column, false) + + let getSelectedPath (tree:TreeView) = + tree.Selection.GetSelectedRows().[0] + + let moveDown tree = + let path = getSelectedPath tree + path.Next() + select tree path + + let moveUp tree = + let path = getSelectedPath tree + path.Prev() |> ignore + select tree path + + let initialize (pad:SearchResultPad) = + let tree:PadTreeView = pad.Control?nativeWidget?treeviewSearchResults + let processKey (key:KeyPressEventArgs) = + match key.Event.Key with + | Gdk.Key.Escape -> + dispatchCommand "MonoDevelop.Ide.Commands.ViewCommands.FocusCurrentDocument" + key.RetVal <- false + | Gdk.Key.j -> + moveDown tree + key.RetVal <- true + | Gdk.Key.k -> + moveUp tree + key.RetVal <- true + | _ -> () + + tree.KeyPressEvent.Add processKey diff --git a/XSVim/XSVim.fsproj b/XSVim/XSVim.fsproj index 3761a7c..fa5dd3b 100644 --- a/XSVim/XSVim.fsproj +++ b/XSVim/XSVim.fsproj @@ -81,6 +81,7 @@ +