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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9160061443d7a4ab50c00c9684f6db737d60edaf
4
- data.tar.gz: f83459eb7604c90e7ba32694338204bc0b0ada16
3
+ metadata.gz: 6826fe5bd7ea9efb4e7e901d1bf2aaa34671bd0d
4
+ data.tar.gz: 440b8acadbc509ffe2260562c1cf9d8e2b192ce0
5
5
  SHA512:
6
- metadata.gz: 5c858da34bb58566bf958d685f7431eefdb3f369736412798cdc1d3c7048908e7b49e00b0ad47164e77a6f8729c78ce3b804eb9b563fbc25ffa920577fc7cedd
7
- data.tar.gz: 6457ad7692bd6c47bfce3e4e25bc2b8a14ff664f9c60a4b5e4e34e24b39c65a7b43edc95dde183e70f2e2d54494bc5c2df6efff2df272d2f841b5ea20f8f3ac6
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
@@ -6,4 +6,4 @@ prompt = TTY::Prompt::new
6
6
 
7
7
  answer = prompt.keypress("Press any key to continue")
8
8
 
9
- puts "Answer: #{answer}"
9
+ puts "Answer: #{answer.inspect}"
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}"
@@ -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
- question = render_question
28
- @prompt.print(refresh(question.lines.count))
29
- countdown(time)
30
- @prompt.print(render_question)
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
- @pause = false
55
+ @done = true
56
+ @scheduler.cancel
54
57
  elsif @keys.is_a?(Array) && @keys.include?(event.key.name)
55
- @pause = false
58
+ @done = true
59
+ @scheduler.cancel
56
60
  else
57
- @pause = true
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
- while @pause
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
- def time(&block)
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 = Timeout.new(interval_handler: @interval_handler)
86
- scheduler.timeout(time, interval, &block)
91
+ @scheduler.timeout(time, interval, &job)
87
92
  else
88
- block.()
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 with echo
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
- get_char_non_blocking
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
- options[:echo] ? @input.getc : get_char_non_blocking
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
- WinAPI.kbhit.zero? ? nil : WinAPI.getch.chr
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
@@ -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
@@ -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, &block)
32
+ def timeout(time, interval, &job)
33
33
  @runner = async_run(time, interval)
34
- @running = block.()
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class Prompt
5
- VERSION = "0.13.0"
5
+ VERSION = "0.13.1"
6
6
  end # Prompt
7
7
  end # TTY
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.0
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-10 00:00:00.000000000 Z
11
+ date: 2017-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: necromancer