Skip to content

Commit

Permalink
Implement search by class and by method/function.
Browse files Browse the repository at this point in the history
  • Loading branch information
hugopl committed Feb 23, 2024
1 parent a2aacca commit 4101ca4
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 13 deletions.
52 changes: 42 additions & 10 deletions src/docset_locator_provider.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -17,36 +20,65 @@ 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

private def initialize_haystacks
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
20 changes: 19 additions & 1 deletion src/locator.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/locator.ui
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@
<style><class name="body" /></style>
</object>
</child>
<!--
<child>
<object class="GtkLabel">
<property name="label">c Foo</property>
Expand Down Expand Up @@ -135,6 +134,7 @@
<style><class name="body" /></style>
</object>
</child>
<!--
<child>
<object class="GtkLabel">
<property name="label">c Foo . bar</property>
Expand Down
2 changes: 1 addition & 1 deletion src/locator_provider.cr
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ abstract class LocatorProvider < GObject::Object
# For assync providers, send 0 (zero) as last value to inform there's no more data.
#
# See `#bind`.
abstract def search_changed(search_text : String) : Result
abstract def search_changed(search_text : String, kind : Doc::Kind?) : Result

# Bind locator data to a Locatoritem that will be used as backend on ListView.
abstract def bind(item : LocatorItem, pos : Int32) : Nil
Expand Down

0 comments on commit 4101ca4

Please sign in to comment.