Module: OllamaChat::Utils::Chooser

Extended by:
SearchUI, Term::ANSIColor
Defined in:
lib/ollama_chat/utils/chooser.rb

Overview

A module that provides interactive selection functionality using fuzzy matching and search capabilities.

The Chooser module enables users to interactively select items from a list using a search interface with fuzzy matching. It leverages the Amatch library for similarity matching and SearchUI for the interactive display and selection experience.

Examples:

Using the chooser in an interactive menu

entries = ['apple', 'banana', 'cherry']
selected = OllamaChat::Utils::Chooser.choose(entries, prompt: 'Choose a fruit:')

Returning immediately if only one entry exists

entries = ['single_option']
result = OllamaChat::Utils::Chooser.choose(entries, return_immediately: true)
# Returns 'single_option' directly without user interaction

Class Method Summary collapse

Class Method Details

.choose(entries, prompt: 'Search? %s', return_immediately: false) ⇒ Object

The choose method presents a list of entries and prompts the user for input, allowing them to select one entry based on their input.

Examples:

choose(['entry1', 'entry2'], prompt: 'Choose an option:')


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
# File 'lib/ollama_chat/utils/chooser.rb', line 38

def choose(entries, prompt: 'Search? %s', return_immediately: false)
  if return_immediately && entries.size <= 1
    return entries.first
  end
  entry = Search.new(
    prompt:,
    match: -> answer {
      matcher = Amatch::PairDistance.new(answer.downcase)
      matches = entries.map { |n| [ n, -matcher.similar(n.to_s.downcase) ] }.
        select { |_, s| s < 0 }.sort_by(&:last).map(&:first)
      matches.empty? and matches = entries
      matches.first(Tins::Terminal.lines - 1)
    },
    query: -> _answer, matches, selector {
      matches.each_with_index.map { |m, i|
        i == selector ? "#{blue{?⮕}} #{on_blue{m}}" : "  #{m.to_s}"
      } * ?\n
    },
    found: -> _answer, matches, selector {
      matches[selector]
    },
    output: STDOUT
  ).start
  if entry
    entry
  else
    print clear_screen, move_home
    nil
  end
end