clack 0.6.0 → 0.6.1
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 +8 -0
- data/README.md +4 -1
- data/lib/clack/core/key_reader.rb +11 -10
- data/lib/clack/core/selection_manager.rb +18 -0
- data/lib/clack/environment.rb +26 -0
- data/lib/clack/prompts/autocomplete_multiselect.rb +1 -1
- data/lib/clack/prompts/group_multiselect.rb +1 -1
- data/lib/clack/prompts/multiselect.rb +1 -1
- data/lib/clack/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 01366d1d6cc81f2514adc5c7bbdc726b3dec22d6697ae2bf26077c2db84efa1b
|
|
4
|
+
data.tar.gz: e1e96b35ef913ee377ed38c0fd98612aa1d758760991ee39ba27ac1cf8dc6136
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ac79a1a3887e261b9d2f14b989381430c35796a1acac47a449e44c773314bcea8985b294880a646213c53bd004900e9e749f9a0d69db55a19dfecd2b4d6eab34
|
|
7
|
+
data.tar.gz: 891cea3cc9b0047602a627396c40950c4397a968aa2ca021b4e2f71719ce40463d62b01db19c3b59ea92fd9efd9e0807b9120afa6cfacbbe5df90fcb391d328a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.6.1] - 2026-06-21
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `CLACK_ESCAPE_TIMEOUT` env var to tune the Escape-sequence detection window (milliseconds) for high-latency links like slow SSH, where arrow keys could otherwise be misread as a standalone Escape
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
- `multiselect`, `group_multiselect`, and `autocomplete_multiselect` now warn on stderr when `initial_values` contains values that don't match any option (still dropped, but no longer silently)
|
|
10
|
+
|
|
3
11
|
## [0.6.0] - 2026-05-30
|
|
4
12
|
|
|
5
13
|
### Added
|
data/README.md
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
<i>CLI prompts for Ruby. Zero dependencies.</i>
|
|
8
8
|
<br>
|
|
9
9
|
<br>
|
|
10
|
+
<sub>A faithful Ruby port of <a href="https://github.com/bombshell-dev/clack"><code>@clack/prompts</code></a>.</sub>
|
|
11
|
+
<br>
|
|
12
|
+
<br>
|
|
10
13
|
<a href="https://rubygems.org/gems/clack"><img src="https://img.shields.io/gem/v/clack?style=flat-square&color=cc342d" alt="Gem Version"></a>
|
|
11
14
|
<a href="https://github.com/swhitt/clackrb/actions"><img src="https://img.shields.io/github/actions/workflow/status/swhitt/clackrb/ci.yml?style=flat-square&label=tests" alt="Tests"></a>
|
|
12
15
|
<a href="https://www.ruby-lang.org"><img src="https://img.shields.io/badge/ruby-3.2%2B-cc342d?style=flat-square" alt="Ruby 3.2+"></a>
|
|
@@ -782,7 +785,7 @@ COVERAGE=true bundle exec rake spec # With coverage
|
|
|
782
785
|
|
|
783
786
|
## Credits
|
|
784
787
|
|
|
785
|
-
This is a Ruby port of [
|
|
788
|
+
This is a Ruby port of [`@clack/prompts`](https://github.com/bombshell-dev/clack), created by [Nate Moore](https://github.com/natemoo-re) and the [Astro](https://astro.build) team.
|
|
786
789
|
|
|
787
790
|
## License
|
|
788
791
|
|
|
@@ -6,15 +6,10 @@ module Clack
|
|
|
6
6
|
module Core
|
|
7
7
|
# Reads single keystrokes from the terminal in raw mode.
|
|
8
8
|
# Handles escape sequences for arrow keys and other special keys.
|
|
9
|
+
#
|
|
10
|
+
# The Escape detection window is tunable via the +CLACK_ESCAPE_TIMEOUT+
|
|
11
|
+
# env var (see {Environment.escape_timeout}) for high-latency links.
|
|
9
12
|
module KeyReader
|
|
10
|
-
# Timeout for detecting if Escape is part of a sequence (50ms).
|
|
11
|
-
# If no follow-up character arrives, treat Escape as a standalone key.
|
|
12
|
-
ESCAPE_TIMEOUT = 0.05
|
|
13
|
-
|
|
14
|
-
# Timeout for reading additional characters in a CSI sequence (10ms).
|
|
15
|
-
# Short because subsequent bytes in a sequence arrive almost instantly.
|
|
16
|
-
SEQUENCE_TIMEOUT = 0.01
|
|
17
|
-
|
|
18
13
|
class << self
|
|
19
14
|
# Read a single keystroke in raw mode.
|
|
20
15
|
# When input is an IO backed by a console, uses raw mode.
|
|
@@ -42,14 +37,20 @@ module Clack
|
|
|
42
37
|
return char if char.nil? # EOF
|
|
43
38
|
return char unless char == "\e"
|
|
44
39
|
|
|
40
|
+
escape_timeout = Environment.escape_timeout
|
|
41
|
+
# Subsequent bytes in a sequence normally arrive almost instantly, so
|
|
42
|
+
# the inter-byte wait stays much shorter, but it scales with the
|
|
43
|
+
# escape timeout so high-latency links still assemble full sequences.
|
|
44
|
+
sequence_timeout = escape_timeout / 5.0
|
|
45
|
+
|
|
45
46
|
# Check for escape sequence - wait briefly for follow-up
|
|
46
|
-
return char unless io.respond_to?(:wait_readable) && io.wait_readable(
|
|
47
|
+
return char unless io.respond_to?(:wait_readable) && io.wait_readable(escape_timeout)
|
|
47
48
|
|
|
48
49
|
seq = io.getc.to_s
|
|
49
50
|
return "\e#{seq}" unless seq == "["
|
|
50
51
|
|
|
51
52
|
# Read CSI sequence until no more characters arrive
|
|
52
|
-
while io.respond_to?(:wait_readable) && io.wait_readable(
|
|
53
|
+
while io.respond_to?(:wait_readable) && io.wait_readable(sequence_timeout)
|
|
53
54
|
seq += io.getc.to_s
|
|
54
55
|
end
|
|
55
56
|
"\e[#{seq[1..]}"
|
|
@@ -11,6 +11,24 @@ module Clack
|
|
|
11
11
|
module SelectionManager
|
|
12
12
|
REQUIRED_ERROR = "Please select at least one option. Press %s to select, %s to submit"
|
|
13
13
|
|
|
14
|
+
# Resolve requested pre-selections against the selectable option values.
|
|
15
|
+
#
|
|
16
|
+
# Values that don't match any current option are dropped and reported on
|
|
17
|
+
# stderr, since they're almost always a typo in +initial_values+ rather
|
|
18
|
+
# than an intentional no-op.
|
|
19
|
+
#
|
|
20
|
+
# @param initial_values [Array] the requested pre-selections
|
|
21
|
+
# @param valid_values [Set] the set of selectable option values
|
|
22
|
+
# @return [Set] the subset of initial_values that map to real options
|
|
23
|
+
def resolve_initial_selection(initial_values, valid_values)
|
|
24
|
+
requested = Set.new(initial_values)
|
|
25
|
+
unknown = requested - valid_values
|
|
26
|
+
unless unknown.empty?
|
|
27
|
+
warn "[clack] ignoring unknown initial_values: #{unknown.to_a.inspect}"
|
|
28
|
+
end
|
|
29
|
+
requested & valid_values
|
|
30
|
+
end
|
|
31
|
+
|
|
14
32
|
# Toggle a value in the selection set.
|
|
15
33
|
# @param value [Object] the value to toggle
|
|
16
34
|
def toggle_value(value)
|
data/lib/clack/environment.rb
CHANGED
|
@@ -6,6 +6,9 @@ module Clack
|
|
|
6
6
|
# Environment detection utilities for cross-platform compatibility
|
|
7
7
|
# and CI/terminal environment awareness.
|
|
8
8
|
module Environment
|
|
9
|
+
# Default Escape-sequence detection timeout, in seconds.
|
|
10
|
+
DEFAULT_ESCAPE_TIMEOUT = 0.05
|
|
11
|
+
|
|
9
12
|
class << self
|
|
10
13
|
# Check if running on Windows
|
|
11
14
|
# @return [Boolean]
|
|
@@ -127,6 +130,29 @@ module Clack
|
|
|
127
130
|
end
|
|
128
131
|
end
|
|
129
132
|
|
|
133
|
+
# Escape-sequence detection timeout, in seconds.
|
|
134
|
+
#
|
|
135
|
+
# After an Escape byte arrives, the key reader waits this long for a
|
|
136
|
+
# follow-up byte to decide whether it's a standalone Escape or the start
|
|
137
|
+
# of an arrow-key / CSI sequence. The 50ms default is fine locally but too
|
|
138
|
+
# tight over high-latency links (slow SSH, mosh), where the follow-up
|
|
139
|
+
# bytes lag and arrow keys get misread as a bare Escape (cancelling the
|
|
140
|
+
# prompt). Override with the +CLACK_ESCAPE_TIMEOUT+ env var, in
|
|
141
|
+
# milliseconds, e.g. +CLACK_ESCAPE_TIMEOUT=250+ for a slow connection.
|
|
142
|
+
#
|
|
143
|
+
# Invalid or non-positive values fall back to the default.
|
|
144
|
+
#
|
|
145
|
+
# @return [Float] timeout in seconds
|
|
146
|
+
def escape_timeout
|
|
147
|
+
raw = ENV["CLACK_ESCAPE_TIMEOUT"]
|
|
148
|
+
return DEFAULT_ESCAPE_TIMEOUT unless raw
|
|
149
|
+
|
|
150
|
+
ms = Float(raw, exception: false)
|
|
151
|
+
return DEFAULT_ESCAPE_TIMEOUT unless ms&.positive?
|
|
152
|
+
|
|
153
|
+
ms / 1000.0
|
|
154
|
+
end
|
|
155
|
+
|
|
130
156
|
# Reset cached environment checks (useful for testing)
|
|
131
157
|
def reset!
|
|
132
158
|
remove_instance_variable(:@windows) if defined?(@windows)
|
|
@@ -56,7 +56,7 @@ module Clack
|
|
|
56
56
|
@option_index = 0
|
|
57
57
|
@scroll_offset = 0
|
|
58
58
|
valid_values = Set.new(@all_options.map { |o| o.value })
|
|
59
|
-
@selected =
|
|
59
|
+
@selected = resolve_initial_selection(initial_values, valid_values)
|
|
60
60
|
update_filtered
|
|
61
61
|
end
|
|
62
62
|
|
|
@@ -61,7 +61,7 @@ module Clack
|
|
|
61
61
|
@groups = normalize_groups(options)
|
|
62
62
|
@flat_items = build_flat_items
|
|
63
63
|
valid_values = Set.new(@flat_items.select { |item| item.is_a?(Core::GroupOption) }.map(&:value))
|
|
64
|
-
@selected =
|
|
64
|
+
@selected = resolve_initial_selection(initial_values, valid_values)
|
|
65
65
|
@required = required
|
|
66
66
|
@selectable_groups = selectable_groups
|
|
67
67
|
@group_spacing = group_spacing
|
|
@@ -45,7 +45,7 @@ module Clack
|
|
|
45
45
|
super(message:, **opts)
|
|
46
46
|
@options = normalize_options(options)
|
|
47
47
|
valid_values = Set.new(@options.map { |o| o.value })
|
|
48
|
-
@selected =
|
|
48
|
+
@selected = resolve_initial_selection(initial_values, valid_values)
|
|
49
49
|
@required = required
|
|
50
50
|
@max_items = max_items
|
|
51
51
|
@scroll_offset = 0
|
data/lib/clack/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: clack
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Steve Whittaker
|
|
@@ -103,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
103
103
|
- !ruby/object:Gem::Version
|
|
104
104
|
version: '0'
|
|
105
105
|
requirements: []
|
|
106
|
-
rubygems_version:
|
|
106
|
+
rubygems_version: 4.0.10
|
|
107
107
|
specification_version: 4
|
|
108
108
|
summary: Beautiful, minimal CLI prompts
|
|
109
109
|
test_files: []
|