Class: TuiTui::Modal::CommandPalette
- Inherits:
-
Modal
- Object
- Modal
- TuiTui::Modal::CommandPalette
- Defined in:
- lib/tui_tui/modal/command_palette.rb
Overview
Fuzzy-filtered command palette modal (think Ctrl-P): type to narrow a list of commands, arrows or Ctrl-N/Ctrl-P to move, Enter to pick, Esc to cancel.
Items are arbitrary objects; pass a block to derive each one's display label (defaults to #to_s). Resolves to the chosen item on Enter and :cancel on escape; stays open (nil) while the query has no matches.
host.open(CommandPalette.new(commands) { |c| c.title }) { |cmd| cmd.run; self }
Constant Summary collapse
- MAX_ROWS =
10- MIN_INNER =
28- WHEEL =
3
Instance Method Summary collapse
- #draw(canvas, size) ⇒ Object
- #handle(key) ⇒ Object
-
#handle_mouse(event) ⇒ Object
Wheel scrolls the highlight; a click on a row picks it (returns the item), otherwise nil to stay open.
-
#initialize(items, prompt: "> ", placeholder: "Type to search…", theme: Theme::DEFAULT, &label) ⇒ CommandPalette
constructor
A new instance of CommandPalette.
- #query ⇒ Object
-
#selection ⇒ Object
The original item under the cursor, or nil when nothing matches.
Constructor Details
#initialize(items, prompt: "> ", placeholder: "Type to search…", theme: Theme::DEFAULT, &label) ⇒ CommandPalette
Returns a new instance of CommandPalette.
28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/tui_tui/modal/command_palette.rb', line 28 def initialize(items, prompt: "> ", placeholder: "Type to search…", theme: Theme::DEFAULT, &label) @items = items.to_a @label = label || :to_s.to_proc @prompt = DisplayText.new(prompt) @placeholder = DisplayText.new(placeholder) @theme = theme # The query buffer. Editing keys stay append-only here: the cursor is # pinned at the end (we never feed it left/right/Home/End), because those # keys drive the list below, not the query. @query = TextInput.new @list = Widget::ScrollList.new(0) refilter end |
Instance Method Details
#draw(canvas, size) ⇒ Object
79 80 81 82 83 84 85 86 87 |
# File 'lib/tui_tui/modal/command_palette.rb', line 79 def draw(canvas, size) rows = visible_rows(size) inner = [MIN_INNER, *@filtered.map { |_item, label, _pos| label.width }].max rect, col = panel(canvas, inner: inner, body_rows: rows + 2) draw_query(canvas, rect.row + 1, col, inner) draw_items(canvas, rect.row + 3, col, inner, rows) canvas end |
#handle(key) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/tui_tui/modal/command_palette.rb', line 47 def handle(key) case key when "\r" selection when :escape, KeyCode::CTRL_C :cancel when :up, KeyCode::CTRL_P move(-1) when :down, KeyCode::CTRL_N move(1) when :home move_to(0) when :end move_to(@list.last) when KeyCode::BACKSPACE, :backspace edit { @query.delete_back } when String edit { @query.type(key) } end end |
#handle_mouse(event) ⇒ Object
Wheel scrolls the highlight; a click on a row picks it (returns the item), otherwise nil to stay open.
70 71 72 73 74 75 76 77 |
# File 'lib/tui_tui/modal/command_palette.rb', line 70 def handle_mouse(event) case event.action when :wheel move(event. == :wheel_up ? -WHEEL : WHEEL) when :press click(event) end end |
#query ⇒ Object
42 |
# File 'lib/tui_tui/modal/command_palette.rb', line 42 def query = @query.value |
#selection ⇒ Object
The original item under the cursor, or nil when nothing matches.
45 |
# File 'lib/tui_tui/modal/command_palette.rb', line 45 def selection = @filtered[@list.cursor]&.first |