tty-prompt 0.13.0 → 0.13.1

Sign up to get free protection for your applications and to get access to all the features.
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