Method: Doing::WWID#fuzzy_filter_items

Defined in:
lib/doing/wwid/filter.rb

#fuzzy_filter_items(items, query, case_type: :smart) ⇒ Items

Use fzf to filter an Items object with a search query. Faster than #filter_items when all you need is a text search of the title and note

Parameters:

  • items (Items)

    an Items object

  • query (String)

    The search query

  • case_type (Symbol) (defaults to: :smart)

    The case type (:smart, :sensitive, :ignore)

Returns:

  • (Items)

    Filtered Items array



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/doing/wwid/filter.rb', line 15

def fuzzy_filter_items(items, query, case_type: :smart)
  scannable = items.map.with_index { |item, idx| "#{item.title} #{item.note.join(' ')}".gsub(/[|*?!]/, '') + "|#{idx}"  }.join("\n")

  fzf_args = [
    '--multi',
    %(--filter="#{query.sub(/^'?/, "'")}"),
    '--no-sort',
    '-d "\|"',
    '--nth=1'
  ]
  fzf_args << case case_type.normalize_case
              when :smart
                query =~ /[A-Z]/ ? '+i' : '-i'
              when :sensitive
                '+i'
              when :ignore
                '-i'
              end

  # fzf_args << '-e' if opt[:exact]
  # puts fzf_args.join(' ')
  res = `echo #{Shellwords.escape(scannable)}|#{Prompt.fzf} #{fzf_args.join(' ')}`
  selected = Items.new
  res.split(/\n/).each do |item|
    idx = item.match(/\|(\d+)$/)[1].to_i
    selected.push(items[idx])
  end
  selected
end