Module: Clack::Core::Settings
- Defined in:
- lib/clack/core/settings.rb
Overview
Global configuration for key bindings, guide bar display, keyboard hint display, input classification, and the user-facing cancel/error strings.
Constant Summary collapse
- ACTIONS =
Navigation and control actions
%i[up down left right space enter cancel].freeze
- KEY_BACKSPACE =
Key code constants
"\b"- KEY_DELETE =
ASCII 8: Backspace
"\u007F"- KEY_CTRL_C =
ASCII 127: Delete (often sent by backspace key)
"\u0003"- KEY_CTRL_D =
ASCII 3: Ctrl+C (interrupt)
"\u0004"- KEY_ESCAPE =
ASCII 4: Ctrl+D (EOF, used for multiline submit)
"\e"- KEY_ENTER =
ASCII 27: Escape
"\r"- KEY_NEWLINE =
ASCII 13: Carriage return
"\n"- KEY_SPACE =
ASCII 10: Line feed
" "- KEY_HOME =
ASCII 32: Space
"\e[H"- KEY_END =
Canonical Home (CSI H)
"\e[F"- PRINTABLE_CHAR_MIN =
First printable ASCII character (space)
32- ALIASES =
Key to action mappings
{ "k" => :up, "j" => :down, "h" => :left, "l" => :right, "\e[A" => :up, "\e[B" => :down, "\e[C" => :right, "\e[D" => :left, KEY_ENTER => :enter, KEY_NEWLINE => :enter, KEY_SPACE => :space, KEY_ESCAPE => :cancel, KEY_CTRL_C => :cancel }.freeze
- KEY_NORMALIZE =
Terminals encode the same key in several ways: SS3 (+ESC O x+) in application cursor mode, and Home/End as
ESC [ H,ESC [ 1 ~orESC [ 7 ~depending on the terminal. KeyReader folds every variant into the canonical code on the right, so prompts and aliases only ever deal with one code per key. { "\eOA" => "\e[A", "\eOB" => "\e[B", "\eOC" => "\e[C", "\eOD" => "\e[D", "\eOH" => KEY_HOME, "\e[1~" => KEY_HOME, "\e[7~" => KEY_HOME, "\eOF" => KEY_END, "\e[4~" => KEY_END, "\e[8~" => KEY_END }.freeze
- DEFAULT_MESSAGES =
Default user-facing strings, overridable via update(messages:) for localization.
{cancel: "Cancelled", error: "Something went wrong"}.freeze
- MESSAGE_KEYS =
DEFAULT_MESSAGES.keys.freeze
Class Method Summary collapse
-
.action?(key) ⇒ Symbol?
Look up the action mapped to a key code.
-
.backspace?(key) ⇒ Boolean
Check if a key is a backspace/delete.
-
.config ⇒ Hash
Get a copy of the current global config.
-
.message(key) ⇒ String
Look up one user-facing string.
-
.messages ⇒ Hash{Symbol=>String}
Current cancel/error strings.
-
.normalize_key(key) ⇒ String
Fold terminal-specific escape sequence variants into one canonical code.
-
.printable?(key) ⇒ Boolean
Check if a key is a printable character (handles combining marks and multi-codepoint grapheme clusters).
-
.reset! ⇒ Object
Reset settings to defaults.
-
.show_instructions?(override = nil) ⇒ Boolean
Resolve whether keyboard hint footers are shown.
-
.update(aliases: nil, with_guide: nil, show_instructions: nil, ci_mode: nil, messages: nil) ⇒ Hash
Update global settings.
-
.with_guide?(override = nil) ⇒ Boolean
Resolve whether guide bars are shown.
Class Method Details
.action?(key) ⇒ Symbol?
Look up the action mapped to a key code.
149 150 151 152 |
# File 'lib/clack/core/settings.rb', line 149 def action?(key) aliases = @config_mutex.synchronize { @config[:aliases] } aliases[key] if ACTIONS.include?(aliases[key]) end |
.backspace?(key) ⇒ Boolean
Check if a key is a backspace/delete
167 168 169 |
# File 'lib/clack/core/settings.rb', line 167 def backspace?(key) [KEY_BACKSPACE, KEY_DELETE].include?(key) end |
.config ⇒ Hash
Get a copy of the current global config
78 79 80 |
# File 'lib/clack/core/settings.rb', line 78 def config @config_mutex.synchronize { @config.dup } end |
.message(key) ⇒ String
Look up one user-facing string.
113 |
# File 'lib/clack/core/settings.rb', line 113 def (key) = .fetch(key) |
.messages ⇒ Hash{Symbol=>String}
Current cancel/error strings.
107 |
# File 'lib/clack/core/settings.rb', line 107 def = @config_mutex.synchronize { @config[:messages] } |
.normalize_key(key) ⇒ String
Fold terminal-specific escape sequence variants into one canonical code.
157 158 159 |
# File 'lib/clack/core/settings.rb', line 157 def normalize_key(key) KEY_NORMALIZE.fetch(key, key) end |
.printable?(key) ⇒ Boolean
Check if a key is a printable character (handles combining marks and multi-codepoint grapheme clusters)
162 163 164 |
# File 'lib/clack/core/settings.rb', line 162 def printable?(key) key && key.grapheme_clusters.length == 1 && key.ord >= PRINTABLE_CHAR_MIN end |
.reset! ⇒ Object
Reset settings to defaults
116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/clack/core/settings.rb', line 116 def reset! @config_mutex.synchronize do @config = { aliases: ALIASES.dup, with_guide: true, show_instructions: true, ci_mode: false, messages: DEFAULT_MESSAGES } end end |
.show_instructions?(override = nil) ⇒ Boolean
Resolve whether keyboard hint footers are shown.
140 141 142 143 144 |
# File 'lib/clack/core/settings.rb', line 140 def show_instructions?(override = nil) return override unless override.nil? @config_mutex.synchronize { @config[:show_instructions] } end |
.update(aliases: nil, with_guide: nil, show_instructions: nil, ci_mode: nil, messages: nil) ⇒ Hash
Update global settings
91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/clack/core/settings.rb', line 91 def update(aliases: nil, with_guide: nil, show_instructions: nil, ci_mode: nil, messages: nil) () if @config_mutex.synchronize do @config[:aliases] = ALIASES.merge(aliases) if aliases @config[:with_guide] = with_guide unless with_guide.nil? @config[:show_instructions] = show_instructions unless show_instructions.nil? @config[:ci_mode] = ci_mode unless ci_mode.nil? # Values are frozen too (-value dedups without to_s), so a caller's # mutable String cannot change global state after the fact. @config[:messages] = @config[:messages].merge(.transform_values { |value| -value }).freeze if @config.dup end end |
.with_guide?(override = nil) ⇒ Boolean
Resolve whether guide bars are shown.
131 132 133 134 135 |
# File 'lib/clack/core/settings.rb', line 131 def with_guide?(override = nil) return override unless override.nil? @config_mutex.synchronize { @config[:with_guide] } end |