Class: Strata::CLI::Autocomplete

Inherits:
Object
  • Object
show all
Defined in:
lib/strata/cli/ui/autocomplete.rb

Overview

Reusable autocomplete component for fuzzy search selection. Works with any collection of items - tables, models, dimensions, etc.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(prompt: TTY::Prompt.new) ⇒ Autocomplete

Returns a new instance of Autocomplete.



13
14
15
# File 'lib/strata/cli/ui/autocomplete.rb', line 13

def initialize(prompt: TTY::Prompt.new)
  @prompt = prompt
end

Instance Attribute Details

#promptObject (readonly)

Returns the value of attribute prompt.



11
12
13
# File 'lib/strata/cli/ui/autocomplete.rb', line 11

def prompt
  @prompt
end

Instance Method Details

#multi_select(message, items, per_page: 10) ⇒ Array<String>

Multi-select with fuzzy search

Parameters:

  • message (String)

    The prompt message

  • items (Array<String>)

    Items to search through

Returns:

  • (Array<String>)

    Selected items



79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/strata/cli/ui/autocomplete.rb', line 79

def multi_select(message, items, per_page: 10)
  return [] if items.empty?

  prompt.multi_select(
    message,
    items,
    filter: true,
    per_page: per_page,
    show_help: :always,
    help: "(Type to filter, Space to select, Enter to confirm)"
  )
rescue TTY::Reader::InputInterrupt
  []
end

#select(message, items, per_page: 10, display_transform: nil, default_filter: nil) ⇒ String?

Select an item with fuzzy search filtering

Parameters:

  • message (String)

    The prompt message

  • items (Array<String>)

    Items to search through

  • per_page (Integer) (defaults to: 10)

    Number of items to show at once

  • display_transform (Proc, nil) (defaults to: nil)

    Optional proc to transform display names

  • default_filter (String, nil) (defaults to: nil)

    Optional initial filter to pre-apply

Returns:

  • (String, nil)

    Selected item or nil if cancelled



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/strata/cli/ui/autocomplete.rb', line 24

def select(message, items, per_page: 10, display_transform: nil, default_filter: nil)
  return nil if items.empty?

  # Create display mapping if transform provided
  display_map = {}
  display_items = if display_transform
    items.map do |item|
      display_name = display_transform.call(item)
      display_map[display_name] = item
      display_name
    end
  else
    items
  end

  # Pre-filter items if default_filter provided
  filtered_items = display_items
  if default_filter && !default_filter.empty?
    pattern = Regexp.new(Regexp.escape(default_filter), Regexp::IGNORECASE)
    filtered_items = display_items.select { |item| item.match?(pattern) }

    # If filter matches exactly one item, still show all but highlight the match
    # If filter matches some items, show those
    # If no matches, show all items
    filtered_items = display_items if filtered_items.empty?
  end

  # Build the prompt message with filter hint
  full_message = if default_filter && !default_filter.empty? && filtered_items.length < display_items.length
    "#{message} (filtered by '#{default_filter}'. Type in characters to apply different filter)"
  else
    message
  end

  selected_display = prompt.select(
    full_message,
    filtered_items,
    filter: true,
    per_page: per_page,
    show_help: :always,
    help: "(Type to filter, ↑/↓ to navigate)"
  )

  return nil if selected_display.nil?

  # Map back to original item if transform was used
  display_transform ? display_map[selected_display] : selected_display
rescue TTY::Reader::InputInterrupt
  nil
end