clack 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -1
- data/README.md +2 -2
- data/lib/clack/core/prompt.rb +1 -4
- data/lib/clack/prompts/autocomplete_multiselect.rb +5 -6
- data/lib/clack/prompts/group_multiselect.rb +8 -5
- data/lib/clack/prompts/multiselect.rb +2 -1
- data/lib/clack/prompts/range.rb +6 -5
- data/lib/clack/prompts/spinner.rb +1 -1
- data/lib/clack/task_log.rb +2 -3
- data/lib/clack/testing.rb +0 -2
- data/lib/clack/version.rb +1 -1
- data/lib/clack.rb +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1a59e5250ad3fb130ffda74b6fdfa5bda7bb4f57062cd6305c5c07f0af7b82ee
|
|
4
|
+
data.tar.gz: 8fb2da61ab0120a8f95189c9112463e742d87a7a915a30d9c5ae7d192c90475b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f64a271d61f1e0b93938b418d2907a173cde44a901a98ba1f691b3c45c84e97ef8096e6b1a1b6e7b94470287920340f75df65ec62a213b661707ab935f266ead
|
|
7
|
+
data.tar.gz: 6bf0a82964715fa130c64f15dc974a373aa00e996d285e19cf0518175b9916ff042b2fe7a042e1ea3d5720d3dee20c1fdbd914d5a77fd9f5a1f428f24622f7ee
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.3] - 2026-02-21
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Multiselect variants now ignore `initial_values` that don't match any option (prevents phantom values in return)
|
|
7
|
+
- SIGWINCH handler now uses `.dup` for safe array iteration inside signal trap
|
|
8
|
+
- `GroupMultiselect` propagates `:hint` into flat items so hints actually render
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- `AutocompleteMultiselect` final frame now shows selected labels instead of "N items selected", matching `Multiselect` behavior
|
|
12
|
+
- Removed dead `@mutex` from `Testing` module
|
|
13
|
+
- Removed unused `raw:` parameter from `TaskLog` and `TaskLogGroup` message methods
|
|
14
|
+
|
|
15
|
+
## [0.4.2] - 2026-02-20
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- `GroupMultiselect` now preserves `:hint` on options (was silently dropped during normalization)
|
|
19
|
+
- `GroupMultiselect` renders hints on active options, matching `Select` behavior
|
|
20
|
+
- `Spinner` no longer raises when finished in timer mode before the animation thread starts
|
|
21
|
+
- YARD docs: corrected `selectable_groups` default from `true` to `false`
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- `Range` prompt now accepts `initial_value:` for consistency with all other prompts (`default:` still works)
|
|
25
|
+
- README: corrected Range example to use `initial_value:` and tab completion description
|
|
26
|
+
|
|
3
27
|
## [0.4.1] - 2026-02-20
|
|
4
28
|
|
|
5
29
|
### Fixed
|
|
@@ -21,7 +45,7 @@
|
|
|
21
45
|
## [0.4.0] - 2026-02-19
|
|
22
46
|
|
|
23
47
|
### Added
|
|
24
|
-
- `range` slider prompt for numeric selection (`Clack.range(message:, min:, max:, step:,
|
|
48
|
+
- `range` slider prompt for numeric selection (`Clack.range(message:, min:, max:, step:, initial_value:)`)
|
|
25
49
|
- Tab completion on `text` prompt via `completions:` parameter (array or proc)
|
|
26
50
|
- Minimum terminal width warning (non-blocking, 40 columns)
|
|
27
51
|
|
data/README.md
CHANGED
|
@@ -198,7 +198,7 @@ name = Clack.text(
|
|
|
198
198
|
)
|
|
199
199
|
```
|
|
200
200
|
|
|
201
|
-
**Tab completion** - press `Tab` to
|
|
201
|
+
**Tab completion** - press `Tab` to fill the longest common prefix of matching candidates:
|
|
202
202
|
|
|
203
203
|
```ruby
|
|
204
204
|
# Tab completion from a static list
|
|
@@ -367,7 +367,7 @@ volume = Clack.range(
|
|
|
367
367
|
min: 0,
|
|
368
368
|
max: 100,
|
|
369
369
|
step: 5,
|
|
370
|
-
|
|
370
|
+
initial_value: 50
|
|
371
371
|
)
|
|
372
372
|
```
|
|
373
373
|
|
data/lib/clack/core/prompt.rb
CHANGED
|
@@ -32,9 +32,6 @@ module Clack
|
|
|
32
32
|
MIN_TERMINAL_WIDTH = 40
|
|
33
33
|
|
|
34
34
|
# Track active prompts for SIGWINCH notification.
|
|
35
|
-
# Signal handler may fire during register/unregister. We can't use
|
|
36
|
-
# .dup (allocates, forbidden in trap context) so we accept a benign
|
|
37
|
-
# race: worst case, a prompt misses one resize notification.
|
|
38
35
|
@active_prompts = []
|
|
39
36
|
|
|
40
37
|
class << self
|
|
@@ -57,7 +54,7 @@ module Clack
|
|
|
57
54
|
return unless Signal.list.key?("WINCH")
|
|
58
55
|
|
|
59
56
|
Signal.trap("WINCH") do
|
|
60
|
-
@active_prompts.each(&:request_redraw)
|
|
57
|
+
@active_prompts.dup.each(&:request_redraw)
|
|
61
58
|
end
|
|
62
59
|
end
|
|
63
60
|
end
|
|
@@ -53,7 +53,8 @@ module Clack
|
|
|
53
53
|
@cursor = 0
|
|
54
54
|
@selected_index = 0
|
|
55
55
|
@scroll_offset = 0
|
|
56
|
-
|
|
56
|
+
valid_values = Set.new(@all_options.map { |o| o[:value] })
|
|
57
|
+
@selected_values = Set.new(initial_values || []) & valid_values
|
|
57
58
|
update_filtered
|
|
58
59
|
end
|
|
59
60
|
|
|
@@ -167,11 +168,9 @@ module Clack
|
|
|
167
168
|
lines << "#{bar}\n"
|
|
168
169
|
lines << "#{symbol_for_state} #{@message}\n"
|
|
169
170
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
Colors.dim("#{@selected_values.size} items selected")
|
|
174
|
-
end
|
|
171
|
+
labels = @all_options.select { |o| @selected_values.include?(o[:value]) }.map { |o| o[:label] }
|
|
172
|
+
display_text = labels.join(", ")
|
|
173
|
+
display = (@state == :cancel) ? Colors.strikethrough(Colors.dim(display_text)) : Colors.dim(display_text)
|
|
175
174
|
lines << "#{bar} #{display}\n"
|
|
176
175
|
|
|
177
176
|
lines.join
|
|
@@ -55,7 +55,8 @@ module Clack
|
|
|
55
55
|
super(message:, **opts)
|
|
56
56
|
@groups = normalize_groups(options)
|
|
57
57
|
@flat_items = build_flat_items
|
|
58
|
-
|
|
58
|
+
valid_values = Set.new(@flat_items.select { |item| item[:type] == :option }.map { |item| item[:value] })
|
|
59
|
+
@selected = Set.new(initial_values) & valid_values
|
|
59
60
|
@required = required
|
|
60
61
|
@selectable_groups = selectable_groups
|
|
61
62
|
@group_spacing = group_spacing
|
|
@@ -152,9 +153,9 @@ module Clack
|
|
|
152
153
|
def normalize_option(opt)
|
|
153
154
|
case opt
|
|
154
155
|
when Hash
|
|
155
|
-
{value: opt[:value], label: opt[:label] || opt[:value].to_s, disabled: opt[:disabled] || false}
|
|
156
|
+
{value: opt[:value], label: opt[:label] || opt[:value].to_s, hint: opt[:hint], disabled: opt[:disabled] || false}
|
|
156
157
|
else
|
|
157
|
-
{value: opt, label: opt.to_s, disabled: false}
|
|
158
|
+
{value: opt, label: opt.to_s, hint: nil, disabled: false}
|
|
158
159
|
end
|
|
159
160
|
end
|
|
160
161
|
|
|
@@ -167,6 +168,7 @@ module Clack
|
|
|
167
168
|
type: :option,
|
|
168
169
|
value: opt[:value],
|
|
169
170
|
label: opt[:label],
|
|
171
|
+
hint: opt[:hint],
|
|
170
172
|
disabled: opt[:disabled],
|
|
171
173
|
group: group,
|
|
172
174
|
last_in_group: idx == group[:options].length - 1
|
|
@@ -261,13 +263,14 @@ module Clack
|
|
|
261
263
|
else
|
|
262
264
|
" "
|
|
263
265
|
end
|
|
266
|
+
hint = (item[:hint] && active) ? " #{Colors.dim("(#{item[:hint]})")}" : ""
|
|
264
267
|
|
|
265
268
|
if item[:disabled]
|
|
266
269
|
"#{active_bar} #{Colors.dim(prefix)}#{Colors.dim(Symbols::S_CHECKBOX_INACTIVE)} #{Colors.strikethrough(Colors.dim(item[:label]))}\n"
|
|
267
270
|
elsif active && selected
|
|
268
|
-
"#{active_bar} #{Colors.dim(prefix)}#{Colors.green(Symbols::S_CHECKBOX_SELECTED)} #{item[:label]}\n"
|
|
271
|
+
"#{active_bar} #{Colors.dim(prefix)}#{Colors.green(Symbols::S_CHECKBOX_SELECTED)} #{item[:label]}#{hint}\n"
|
|
269
272
|
elsif active
|
|
270
|
-
"#{active_bar} #{Colors.dim(prefix)}#{Colors.cyan(Symbols::S_CHECKBOX_ACTIVE)} #{item[:label]}\n"
|
|
273
|
+
"#{active_bar} #{Colors.dim(prefix)}#{Colors.cyan(Symbols::S_CHECKBOX_ACTIVE)} #{item[:label]}#{hint}\n"
|
|
271
274
|
elsif selected
|
|
272
275
|
"#{active_bar} #{Colors.dim(prefix)}#{Colors.green(Symbols::S_CHECKBOX_SELECTED)} #{Colors.dim(item[:label])}\n"
|
|
273
276
|
else
|
|
@@ -40,7 +40,8 @@ module Clack
|
|
|
40
40
|
def initialize(message:, options:, initial_values: [], required: true, max_items: nil, cursor_at: nil, **opts)
|
|
41
41
|
super(message:, **opts)
|
|
42
42
|
@options = normalize_options(options)
|
|
43
|
-
|
|
43
|
+
valid_values = Set.new(@options.map { |o| o[:value] })
|
|
44
|
+
@selected = Set.new(initial_values) & valid_values
|
|
44
45
|
@required = required
|
|
45
46
|
@max_items = max_items
|
|
46
47
|
@scroll_offset = 0
|
data/lib/clack/prompts/range.rb
CHANGED
|
@@ -10,11 +10,11 @@ module Clack
|
|
|
10
10
|
# @example Basic usage
|
|
11
11
|
# level = Clack.range(message: "Volume", min: 0, max: 100, step: 5)
|
|
12
12
|
#
|
|
13
|
-
# @example With
|
|
13
|
+
# @example With initial value
|
|
14
14
|
# workers = Clack.range(
|
|
15
15
|
# message: "Concurrency",
|
|
16
16
|
# min: 1, max: 16,
|
|
17
|
-
# step: 1,
|
|
17
|
+
# step: 1, initial_value: 4
|
|
18
18
|
# )
|
|
19
19
|
#
|
|
20
20
|
class Range < Core::Prompt
|
|
@@ -26,9 +26,10 @@ module Clack
|
|
|
26
26
|
# @param min [Numeric] minimum value (default: 0)
|
|
27
27
|
# @param max [Numeric] maximum value (default: 100)
|
|
28
28
|
# @param step [Numeric] increment size (default: 1)
|
|
29
|
-
# @param
|
|
29
|
+
# @param initial_value [Numeric, nil] initial value (defaults to min)
|
|
30
|
+
# @param default [Numeric, nil] deprecated alias for initial_value
|
|
30
31
|
# @param opts [Hash] additional options passed to {Core::Prompt}
|
|
31
|
-
def initialize(message:, min: 0, max: 100, step: 1, default: nil, **opts)
|
|
32
|
+
def initialize(message:, min: 0, max: 100, step: 1, initial_value: nil, default: nil, **opts)
|
|
32
33
|
super(message:, **opts)
|
|
33
34
|
|
|
34
35
|
raise ArgumentError, "min must be less than max" if min >= max
|
|
@@ -37,7 +38,7 @@ module Clack
|
|
|
37
38
|
@min = min
|
|
38
39
|
@max = max
|
|
39
40
|
@step = step
|
|
40
|
-
@value = clamp(default || min)
|
|
41
|
+
@value = clamp(initial_value || default || min)
|
|
41
42
|
end
|
|
42
43
|
|
|
43
44
|
protected
|
|
@@ -178,7 +178,7 @@ module Clack
|
|
|
178
178
|
@finished = true
|
|
179
179
|
@running = false
|
|
180
180
|
thread_to_join = @thread
|
|
181
|
-
suffix = (@indicator == :timer) ? " #{format_timer}" : ""
|
|
181
|
+
suffix = (@indicator == :timer && @start_time) ? " #{format_timer}" : ""
|
|
182
182
|
[message || @message, suffix]
|
|
183
183
|
end
|
|
184
184
|
|
data/lib/clack/task_log.rb
CHANGED
|
@@ -32,8 +32,7 @@ module Clack
|
|
|
32
32
|
|
|
33
33
|
# Add a message to the log
|
|
34
34
|
# @param msg [String] Message to display
|
|
35
|
-
|
|
36
|
-
def message(msg, raw: false)
|
|
35
|
+
def message(msg)
|
|
37
36
|
clear_buffer
|
|
38
37
|
@buffer << msg.to_s.gsub(/\e\[[\d;]*[ABCDEFGHfJKSTsu]/, "") # Strip cursor movement codes
|
|
39
38
|
apply_limit
|
|
@@ -155,7 +154,7 @@ module Clack
|
|
|
155
154
|
end
|
|
156
155
|
|
|
157
156
|
# Add a message to this group
|
|
158
|
-
def message(msg
|
|
157
|
+
def message(msg)
|
|
159
158
|
@parent.add_group_message(self, msg)
|
|
160
159
|
end
|
|
161
160
|
|
data/lib/clack/testing.rb
CHANGED
data/lib/clack/version.rb
CHANGED
data/lib/clack.rb
CHANGED
|
@@ -343,7 +343,7 @@ module Clack
|
|
|
343
343
|
# @option opts [Array, nil] :initial_values initially selected values
|
|
344
344
|
# @option opts [Boolean] :required require at least one selection (default: true)
|
|
345
345
|
# @option opts [Object, nil] :cursor_at value of initially focused option
|
|
346
|
-
# @option opts [Boolean] :selectable_groups allow toggling entire groups (default:
|
|
346
|
+
# @option opts [Boolean] :selectable_groups allow toggling entire groups (default: false)
|
|
347
347
|
# @option opts [Integer] :group_spacing lines between groups (default: 0)
|
|
348
348
|
# @return [Array, CANCEL] selected values or CANCEL if cancelled
|
|
349
349
|
def group_multiselect(message:, options:, **opts)
|
|
@@ -375,7 +375,7 @@ module Clack
|
|
|
375
375
|
# @option opts [Numeric] :min minimum value (default: 0)
|
|
376
376
|
# @option opts [Numeric] :max maximum value (default: 100)
|
|
377
377
|
# @option opts [Numeric] :step increment size (default: 1)
|
|
378
|
-
# @option opts [Numeric, nil] :
|
|
378
|
+
# @option opts [Numeric, nil] :initial_value initial value (defaults to min)
|
|
379
379
|
# @option opts [Proc, nil] :validate validation proc
|
|
380
380
|
# @option opts [String, nil] :help help text shown below the message
|
|
381
381
|
# @return [Numeric, CANCEL] selected value or CANCEL if cancelled
|