diff --git a/src/docset_locator_provider.cr b/src/docset_locator_provider.cr index 4365815..639674e 100644 --- a/src/docset_locator_provider.cr +++ b/src/docset_locator_provider.cr @@ -4,8 +4,11 @@ class DocsetLocatorProvider < LocatorProvider @metadata : DocsetMetadata @all_haystack : Fzy::PreparedHaystack? - # @methods_haystack : Fzy::PreparedHaystack? - # @classes_haystack : Fzy::PreparedHaystack? + @methods_haystack : Fzy::PreparedHaystack? + @classes_haystack : Fzy::PreparedHaystack? + @current_haystack : Fzy::PreparedHaystack? + @methods : Array(Doc)? + @classes : Array(Doc)? @haystacks_initialized = false @last_results = [] of Fzy::Match @@ -17,10 +20,22 @@ class DocsetLocatorProvider < LocatorProvider @icon_path = @metadata.icon_path end - def search_changed(search_text : String) : Result + def search_changed(search_text : String, kind : Doc::Kind?) : Result + Log.debug { "search changed: #{search_text}, #{kind}" } initialize_haystacks - @last_results = @all_haystack.not_nil!.search(search_text) + haystack = case kind + when Nil + @all_haystack + when .class? + @classes_haystack + when .method?, .function? + @methods_haystack + else + @all_haystack + end + @current_haystack = haystack + @last_results = haystack.not_nil!.search(search_text) @last_results.size end @@ -28,25 +43,42 @@ class DocsetLocatorProvider < LocatorProvider return if @haystacks_initialized @all_haystack = Fzy::PreparedHaystack.new(@metadata.docset.entries.map(&.key)) + + # TODO: Optimize this 💩ī¸, 😁ī¸đŸ˜…ī¸ + @methods = methods = @metadata.docset.entries.select { |doc| doc.kind.method? || doc.kind.function? } + @methods_haystack = Fzy::PreparedHaystack.new(methods.map(&.key)) + @classes = classes = @metadata.docset.entries.select(&.kind.class?) + @classes_haystack = Fzy::PreparedHaystack.new(classes.map(&.key)) + @haystacks_initialized = true end def bind(item : LocatorItem, pos : Int32) : Nil match = @last_results[pos] - - doc = @metadata.docset.entries[match.index] + doc = entries[match.index] item.name = doc.name item.description = doc.kind.to_s item.icon_name = doc.icon_name end + private def entries : Array(Doc) + case @current_haystack + when @all_haystack + @metadata.docset.entries + when @classes_haystack + @classes.not_nil! + when @methods_haystack + @methods.not_nil! + else + raise RtfmError.new("wtf?") + end + end + def activate(locator : Locator, pos : UInt32) : Bool match = @last_results[pos] - - docset = @metadata.docset - doc = docset.entries[match.index] - locator.activate_action("page.load_uri", docset.uri(doc)) + doc = entries[match.index] + locator.activate_action("page.load_uri", @metadata.docset.uri(doc)) true end end diff --git a/src/locator.cr b/src/locator.cr index b33a5d1..71c9d71 100644 --- a/src/locator.cr +++ b/src/locator.cr @@ -113,7 +113,7 @@ class Locator < Adw::Bin # TODO: Check search_text.starts_with?(@previous_search_text) to improve fzy search. # But I need to improve fzy.cr shard first 😅ī¸ - result = @current_locator_provider.search_changed(search_text) + result = @current_locator_provider.search_changed(*parse_search_text(search_text)) old_size = @result_size @result_size = result.as?(Int32) || 0 @@ -128,6 +128,24 @@ class Locator < Adw::Bin @previous_search_text = search_text if search_text end + private def parse_search_text(text : String) : {String, Doc::Kind?} + cmd = nil + term = nil + text.split(" ", 2) do |word| + term ||= word if cmd + cmd ||= word + end + return {text, nil.as(Doc::Kind?)} if term.nil? + + kind = case cmd + when "c" then Doc::Kind::Class + when "." then Doc::Kind::Method + else + return {text, nil.as(Doc::Kind?)} + end + {term, kind} + end + private def read_provider_channel_async(channel : Channel) : Nil spawn(name: "locator.update") do old_size = 0 diff --git a/src/locator.ui b/src/locator.ui index 14bd5d2..159449a 100644 --- a/src/locator.ui +++ b/src/locator.ui @@ -106,7 +106,6 @@ -