Class: BruteCLI::REPL::FzfMenu

Inherits:
Object
  • Object
show all
Defined in:
lib/brute_cli/repl/fzf_menu.rb

Overview

A simple state-machine menu system powered by fzf.

Each menu is a named bag of choices. Each choice points to either:

- a Symbol  → the name of the next menu to show
- nil       → exit the menu loop (Ctrl-C / Escape does the same)
- anything else → returned to the caller as an "action" value

The engine is just: while current.is_a?(Symbol) { current = show(menu) }

Menus can be static (block evaluated at definition time) or dynamic (block with arity > 0, evaluated fresh each time the menu is shown).

Titles can be strings or callables (lambdas) for dynamic labels.

Example:

app = BruteCLI::REPL::FzfMenu.new do
  menu :main, "Cool Menu" do
    choice "Status",  :status
    choice "Manage",  :manage
    choice "Exit",    nil
  end
end

result = app.call          # starts at :main
result = app.call(:models) # jump straight to :models

Defined Under Namespace

Classes: Menu

Instance Method Summary collapse

Constructor Details

#initialize(&definition) ⇒ FzfMenu

Returns a new instance of FzfMenu.



53
54
55
56
57
# File 'lib/brute_cli/repl/fzf_menu.rb', line 53

def initialize(&definition)
  @menus   = {}   # name → Menu (static)
  @dynamic = {}   # name → [title, block] (dynamic, built at render time)
  instance_eval(&definition) if definition
end

Instance Method Details

#call(start = nil) ⇒ Object

Run the menu loop starting at the given menu name. Returns the final non-Symbol value chosen (or nil on escape/Ctrl-C).



83
84
85
86
87
88
89
90
91
92
# File 'lib/brute_cli/repl/fzf_menu.rb', line 83

def call(start = nil)
  start ||= @menus.keys.first || @dynamic.keys.first
  current = start

  while current.is_a?(Symbol)
    current = show(resolve_menu(current))
  end

  current
end

Define a named menu.

Static (block with no params — evaluated once at definition):

menu :main, "Title" do
  choice "Foo", :foo
end

Dynamic (block with one param — evaluated each time the menu is shown):

menu :models, "Title" do |m|
  m.choice "Foo", :foo
end


71
72
73
74
75
76
77
78
79
# File 'lib/brute_cli/repl/fzf_menu.rb', line 71

def menu(name, title = nil, &block)
  if block.arity > 0
    @dynamic[name] = [title, block]
  else
    m = Menu.new(title)
    m.instance_eval(&block)
    @menus[name] = m
  end
end

All registered menu names (static + dynamic).



95
96
97
# File 'lib/brute_cli/repl/fzf_menu.rb', line 95

def menu_names
  @menus.keys | @dynamic.keys
end