class Rooibos::Router::KeymapBuilder
Builder for keymap DSL.
Attributes
Returns the registered handlers hash.
Public Instance Methods
Source
# File lib/rooibos/router.rb, line 358 def key(*args, action: nil, route: nil, when: nil, if: nil, only: nil, guard: nil, unless: nil, except: nil, skip: nil, **bindings) # Parse args: all symbols/strings are keys, last callable is handler key_names = [] #: Array[Symbol | String] handler = nil action_name = action args.each do |arg| if arg.is_a?(Hash) # Hash passed positionally: key({q: -> { ... }}) bindings.merge!(arg) elsif arg.respond_to?(:call) handler = arg elsif arg.is_a?(Symbol) || arg.is_a?(String) # Could be a key name or action name (positional action from old API) key_names << arg end end # Keyword syntax: key ctrl_c: -> { ... } # Each kwarg is key_name => handler bindings.each do |key_name, handler_or_action| if handler_or_action.respond_to?(:call) register_key_handler(key_name, handler_or_action, nil, route, nil) else register_key_handler(key_name, nil, handler_or_action, route, nil) end end # If we had keyword bindings, skip positional processing return if bindings.any? # Old API: key :q, :quit - last symbol is the action if handler.nil? && action_name.nil? && key_names.size >= 2 # Check if last "key" is actually an action by seeing if it looks like a handler action_name = key_names.pop end guards = @guard_stack.dup # Positive guards (when, if, only, guard) positive = binding.local_variable_get(:when) || binding.local_variable_get(:if) || only || guard guards << positive if positive # Negative guards (unless, except, skip) - wrap to invert negative = binding.local_variable_get(:unless) || except || skip if negative guards << -> (model) { !negative.call(model) } end combined_guard = if guards.any? -> (model) { guards.all? { |g| g.call(model) } } end # Register each key key_names.each do |key_name| register_key_handler(key_name, handler, action_name, route, combined_guard) end end
Registers a key handler.
Supports multiple forms:
key :q, -> { Command.exit } # Single key with handler
key :q, :quit # Single key with action name
key :down, :j, action: :move_down # Multiple keys with action
key :enter, -> { ... }, route: :foo # With options
- *key_names
-
One or more key names (String or Symbol).
- handler_or_action
-
Callable or Symbol (action name) - optional if action: given.
- action
-
Action name as keyword arg (alternative to positional).
- route
-
Optional route prefix for the command result.
- when/if/only/guard
-
Guard that runs if truthy (aliases).
- unless/except/skip
-
Guard that runs if falsy (negative aliases).
Also aliased as: keys
Alias for key (reads better with multiple keys)
Alias for: key
Source
# File lib/rooibos/router.rb, line 435 def only(when: nil, if: nil, only: nil, guard: nil, &) arg_count = 0 arg_count += 1 if binding.local_variable_get(:when) arg_count += 1 if binding.local_variable_get(:if) arg_count += 1 if only arg_count += 1 if guard if arg_count > 1 raise ArgumentError, "only accepts exactly one of: when, if, only, guard" end positive = binding.local_variable_get(:when) || binding.local_variable_get(:if) || only || guard with_guard(positive, &) end
Applies a guard to all keys in the block.
- when/if/only/guard
-
Guard that runs if truthy.
Source
# File lib/rooibos/router.rb, line 456 def skip(when: nil, if: nil, skip: nil, guard: nil, &) arg_count = 0 arg_count += 1 if binding.local_variable_get(:when) arg_count += 1 if binding.local_variable_get(:if) arg_count += 1 if skip arg_count += 1 if guard if arg_count > 1 raise ArgumentError, "skip accepts exactly one of: when, if, skip, guard" end skip_guard = binding.local_variable_get(:when) || binding.local_variable_get(:if) || skip || guard # Invert the guard: skip when true means run when false inverted = skip_guard ? -> (model) { !skip_guard.call(model) } : nil with_guard(inverted, &) end
Skips all keys in the block when the guard is true.
- when/if/skip/guard
-
Guard that skips if truthy.