tty-prompt 0.13.0 → 0.13.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 +12 -0
- data/examples/keypress.rb +1 -1
- data/examples/pause.rb +3 -1
- data/lib/tty/prompt/keypress.rb +20 -15
- data/lib/tty/prompt/reader/win_api.rb +12 -0
- data/lib/tty/prompt/reader/win_console.rb +37 -6
- data/lib/tty/prompt/reader.rb +1 -3
- data/lib/tty/prompt/timeout.rb +7 -2
- data/lib/tty/prompt/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6826fe5bd7ea9efb4e7e901d1bf2aaa34671bd0d
|
4
|
+
data.tar.gz: 440b8acadbc509ffe2260562c1cf9d8e2b192ce0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4ba64116ae4982a55d032e60a6cee47d28a165e4ab1286c294e3e3109e602f4e6c174febfbe81507d0676eadbd0771565e73fc65c79bda5b914e1fd02405e67
|
7
|
+
data.tar.gz: 3213c42f59d3c3df70a826ed6d2e69f8328725a7483a9ce57437b1464f1c4ae8a2c99a70cd1c43451c8b55d14bcb3ee02e1b98421145397ee08f9892424669bf
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## [v0.13.1] - 2017-08-16
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Add ability to manually cancel the time scheduler
|
7
|
+
|
8
|
+
### Changed
|
9
|
+
* Change #keypress to use new scheduler cancelling
|
10
|
+
* Change Reader to inline interrupt to allow for early exit
|
11
|
+
|
12
|
+
### Fix
|
13
|
+
* Fix keypress reading on Windows to distinguish between blocking & non-blocking IO
|
14
|
+
|
3
15
|
## [v0.13.0] - 2017-08-11
|
4
16
|
|
5
17
|
### Changed
|
data/examples/keypress.rb
CHANGED
data/examples/pause.rb
CHANGED
@@ -4,4 +4,6 @@ require 'tty-prompt'
|
|
4
4
|
|
5
5
|
prompt = TTY::Prompt::new
|
6
6
|
|
7
|
-
prompt.keypress("Press space or enter to continue, continuing automatically in :countdown ...", keys: [:space, :return], timeout: 3)
|
7
|
+
answer = prompt.keypress("Press space or enter to continue, continuing automatically in :countdown ...", keys: [:space, :return], timeout: 3)
|
8
|
+
|
9
|
+
puts "Answer: #{answer.inspect}"
|
data/lib/tty/prompt/keypress.rb
CHANGED
@@ -21,14 +21,16 @@ module TTY
|
|
21
21
|
@interval = options.fetch(:interval) {
|
22
22
|
(@timeout != UndefinedSetting && @timeout < 1) ? @timeout : 1
|
23
23
|
}
|
24
|
-
@pause = true
|
25
24
|
@countdown = @timeout
|
26
25
|
@interval_handler = proc { |time|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
unless @done
|
27
|
+
question = render_question
|
28
|
+
@prompt.print(refresh(question.lines.count))
|
29
|
+
countdown(time)
|
30
|
+
@prompt.print(render_question)
|
31
|
+
end
|
31
32
|
}
|
33
|
+
@scheduler = Timeout.new(interval_handler: @interval_handler)
|
32
34
|
|
33
35
|
@prompt.subscribe(self)
|
34
36
|
end
|
@@ -50,11 +52,13 @@ module TTY
|
|
50
52
|
|
51
53
|
def keypress(event)
|
52
54
|
if any_key?
|
53
|
-
@
|
55
|
+
@done = true
|
56
|
+
@scheduler.cancel
|
54
57
|
elsif @keys.is_a?(Array) && @keys.include?(event.key.name)
|
55
|
-
@
|
58
|
+
@done = true
|
59
|
+
@scheduler.cancel
|
56
60
|
else
|
57
|
-
@
|
61
|
+
@done = false
|
58
62
|
end
|
59
63
|
end
|
60
64
|
|
@@ -66,10 +70,9 @@ module TTY
|
|
66
70
|
|
67
71
|
def process_input(question)
|
68
72
|
time do
|
69
|
-
|
70
|
-
@input = @prompt.read_keypress
|
73
|
+
until @done
|
74
|
+
@input = @prompt.read_keypress(nonblock: true)
|
71
75
|
end
|
72
|
-
@pause
|
73
76
|
end
|
74
77
|
@evaluator.(@input)
|
75
78
|
end
|
@@ -78,14 +81,16 @@ module TTY
|
|
78
81
|
@prompt.clear_lines(lines)
|
79
82
|
end
|
80
83
|
|
81
|
-
|
84
|
+
# Wait for keypress or timeout
|
85
|
+
#
|
86
|
+
# @api private
|
87
|
+
def time(&job)
|
82
88
|
if timeout?
|
83
89
|
time = Float(@timeout)
|
84
90
|
interval = Float(@interval)
|
85
|
-
scheduler
|
86
|
-
scheduler.timeout(time, interval, &block)
|
91
|
+
@scheduler.timeout(time, interval, &job)
|
87
92
|
else
|
88
|
-
|
93
|
+
job.()
|
89
94
|
end
|
90
95
|
rescue Timeout::Error
|
91
96
|
end
|
@@ -12,12 +12,24 @@ module TTY
|
|
12
12
|
|
13
13
|
CRT_HANDLE = Handle.new("msvcrt") rescue Handle.new("crtdll")
|
14
14
|
|
15
|
+
# Get a character from the console without echo.
|
16
|
+
#
|
17
|
+
# @return [String]
|
18
|
+
# return the character read
|
19
|
+
#
|
20
|
+
# @api public
|
15
21
|
def getch
|
16
22
|
@@getch ||= Fiddle::Function.new(CRT_HANDLE["_getch"], [], TYPE_INT)
|
17
23
|
@@getch.call
|
18
24
|
end
|
19
25
|
module_function :getch
|
20
26
|
|
27
|
+
# Gets a character from the console with echo.
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
# return the character read
|
31
|
+
#
|
32
|
+
# @api public
|
21
33
|
def getche
|
22
34
|
@@getche ||= Fiddle::Function.new(CRT_HANDLE["_getche"], [], TYPE_INT)
|
23
35
|
@@getche.call
|
@@ -31,20 +31,30 @@ module TTY
|
|
31
31
|
@escape_codes = [[NUL_HEX.ord], [ESC.ord], EXT_HEX.bytes.to_a]
|
32
32
|
end
|
33
33
|
|
34
|
-
# Get a character from console
|
34
|
+
# Get a character from console blocking for input
|
35
35
|
#
|
36
36
|
# @param [Hash[Symbol]] options
|
37
37
|
# @option options [Symbol] :echo
|
38
|
-
# the echo toggle
|
38
|
+
# the echo mode toggle
|
39
|
+
# @option options [Symbol] :raw
|
40
|
+
# the raw mode toggle
|
39
41
|
#
|
40
42
|
# @return [String]
|
41
43
|
#
|
42
44
|
# @api private
|
43
45
|
def get_char(options)
|
44
|
-
if options[:raw]
|
45
|
-
|
46
|
+
if options[:raw] && options[:echo]
|
47
|
+
if options[:nonblock]
|
48
|
+
get_char_echo_non_blocking
|
49
|
+
else
|
50
|
+
get_char_echo_blocking
|
51
|
+
end
|
52
|
+
elsif options[:raw] && !options[:echo]
|
53
|
+
options[:nonblock] ? get_char_non_blocking : get_char_blocking
|
54
|
+
elsif !options[:raw] && !options[:echo]
|
55
|
+
options[:nonblock] ? get_char_non_blocking : get_char_blocking
|
46
56
|
else
|
47
|
-
|
57
|
+
@input.getc
|
48
58
|
end
|
49
59
|
end
|
50
60
|
|
@@ -52,7 +62,28 @@ module TTY
|
|
52
62
|
#
|
53
63
|
# @api private
|
54
64
|
def get_char_non_blocking
|
55
|
-
|
65
|
+
input_ready? ? get_char_blocking : nil
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_char_echo_non_blocking
|
69
|
+
input_ready? ? get_char_echo_blocking : nil
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_char_blocking
|
73
|
+
WinAPI.getch.chr
|
74
|
+
end
|
75
|
+
|
76
|
+
def get_char_echo_blocking
|
77
|
+
WinAPI.getche.chr
|
78
|
+
end
|
79
|
+
|
80
|
+
# Check if IO has user input
|
81
|
+
#
|
82
|
+
# @return [Boolean]
|
83
|
+
#
|
84
|
+
# @api private
|
85
|
+
def input_ready?
|
86
|
+
!WinAPI.kbhit.zero?
|
56
87
|
end
|
57
88
|
end # Console
|
58
89
|
end # Reader
|
data/lib/tty/prompt/reader.rb
CHANGED
@@ -119,7 +119,6 @@ module TTY
|
|
119
119
|
char = codes ? codes.pack('U*') : nil
|
120
120
|
|
121
121
|
trigger_key_event(char) if char
|
122
|
-
handle_interrupt if char == console.keys[:ctrl_c]
|
123
122
|
char
|
124
123
|
end
|
125
124
|
alias read_char read_keypress
|
@@ -135,6 +134,7 @@ module TTY
|
|
135
134
|
def get_codes(options = {}, codes = [])
|
136
135
|
opts = { echo: true, raw: false }.merge(options)
|
137
136
|
char = console.get_char(opts)
|
137
|
+
handle_interrupt if char == console.keys[:ctrl_c]
|
138
138
|
return if char.nil?
|
139
139
|
codes << char.ord
|
140
140
|
|
@@ -184,8 +184,6 @@ module TTY
|
|
184
184
|
elsif [console.keys[:ctrl_d],
|
185
185
|
console.keys[:ctrl_z]].include?(char)
|
186
186
|
break
|
187
|
-
elsif console.keys[:ctrl_c] == char
|
188
|
-
handle_interrupt
|
189
187
|
elsif ctrls.include?(console.keys.key(char))
|
190
188
|
# skip
|
191
189
|
elsif console.keys[:up] == char
|
data/lib/tty/prompt/timeout.rb
CHANGED
@@ -29,12 +29,17 @@ module TTY
|
|
29
29
|
# the interval time for each tick
|
30
30
|
#
|
31
31
|
# @api public
|
32
|
-
def timeout(time, interval, &
|
32
|
+
def timeout(time, interval, &job)
|
33
33
|
@runner = async_run(time, interval)
|
34
|
-
|
34
|
+
job.()
|
35
35
|
@runner.join
|
36
36
|
end
|
37
37
|
|
38
|
+
def cancel
|
39
|
+
return unless @running
|
40
|
+
@running = false
|
41
|
+
end
|
42
|
+
|
38
43
|
def async_run(time, interval)
|
39
44
|
Thread.new do
|
40
45
|
Thread.current.abort_on_exception = true
|
data/lib/tty/prompt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tty-prompt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.13.
|
4
|
+
version: 0.13.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: necromancer
|