tty-reader 0.5.0 → 0.6.0

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
  SHA256:
3
- metadata.gz: 995b414e2605c556220168d30b3f894771e021f2956aa75821fb3504f5ae6589
4
- data.tar.gz: 4bfa84cd59cab3b14410d4eac314ae819765d94230c1c9b2a1ce94c09e13c80d
3
+ metadata.gz: 6193cf64fd770d652ff66d89ff395c28f52181521242ce432b3b651aa7b13d63
4
+ data.tar.gz: 7fa878638a8851265dfed9f8970f03fd360f975007c8ad0c865bf2bb304c64a1
5
5
  SHA512:
6
- metadata.gz: 061eeb4dc0698c1ff226ad3a2bc9fe69e4c519fe455642bda6bb9675e758e52c385335bb1604256f2002c75f6b2ba8528007e8df9d332815df8f072b75bd1388
7
- data.tar.gz: e964e5cf12b271ce1fee675afc1d348f7f6c59a01f007580936c2544e672f784a1297e0f7f8ee6acce2d6ee4f867ca32b2142d3d376f5a4a28c82e2ab6521713
6
+ metadata.gz: 91136b6cecab81d4705560af21775ae5e4140e860c1d2413e8c01b545652623f2d17c2a146494fcf790d0c3e996a4b38cab1a80741f1900d3422eb4018e861ac
7
+ data.tar.gz: bf159f08943f118a48c133171410bd5e9f8f6e8da0f83be54745e653648f9d3de7863025667a4a08da19d8ba27ab1c1c6cab0add921777de23a7a0b069c2ac15
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.6.0] - 2019-05-27
4
+
5
+ ### Added
6
+ * Add :value option to #read_line to allow pre-populating of line content
7
+
8
+ ### Changed
9
+ * Change to make InputInterrupt to derive from Interrupt by Samuel Williams(@ioquatix)
10
+ * Change #read_line to trigger before line is printed to allow for line changes in key callbacks
11
+ * Change Console#get_char :nonblock option to wait for readable input without blocking
12
+ * Change to remove bundler version constraints
13
+ * Change to update tty-screen dependency
14
+ * Change to update tty-cursor dependency
15
+
3
16
  ## [v0.5.0] - 2018-11-24
4
17
 
5
18
  ### Added
@@ -47,6 +60,7 @@
47
60
 
48
61
  * Initial implementation and release
49
62
 
63
+ [v0.6.0]: https://github.com/piotrmurach/tty-reader/compare/v0.5.0...v0.6.0
50
64
  [v0.5.0]: https://github.com/piotrmurach/tty-reader/compare/v0.4.0...v0.5.0
51
65
  [v0.4.0]: https://github.com/piotrmurach/tty-reader/compare/v0.3.0...v0.4.0
52
66
  [v0.3.0]: https://github.com/piotrmurach/tty-reader/compare/v0.2.0...v0.3.0
data/README.md CHANGED
@@ -140,7 +140,14 @@ You can also provide a line prefix displayed before input by passing it as a fir
140
140
 
141
141
  ```ruby
142
142
  reader.read_line(">> ")
143
- # >> input goes here ...
143
+ # >>
144
+ ```
145
+
146
+ To pre-populate the line content for editing use `:value` option:
147
+
148
+ ```ruby
149
+ reader.read_line("> ", value: "edit me")
150
+ # > edit me
144
151
  ```
145
152
 
146
153
  ### 2.3 read_multiline
@@ -230,13 +237,13 @@ class MyListener
230
237
  end
231
238
  ```
232
239
 
233
- Then subcribing is done:
240
+ Then subscribing is done:
234
241
 
235
242
  ```ruby
236
243
  reader.subscribe(MyListener.new)
237
244
  ```
238
245
 
239
- Alternatively, `subscribe` allows you to listen to events only for the dueration of block execution like so:
246
+ Alternatively, `subscribe` allows you to listen to events only for the duration of block execution like so:
240
247
 
241
248
  ```ruby
242
249
  reader.subscribe(MyListener) do
@@ -290,7 +297,7 @@ The available key events for character input are:
290
297
  * `:keyalpha`
291
298
  * `:keynum`
292
299
 
293
- The navigation relted key events are:
300
+ The navigation related key events are:
294
301
 
295
302
  * `:keydown`
296
303
  * `:keyup`
@@ -333,7 +340,7 @@ reader = TTY::Reader.new(interrupt: :signal)
333
340
 
334
341
  ### 3.2. `:track_history`
335
342
 
336
- The `read_line` and `read_multiline` provide history buffer that tracks all the lines entered during `TTY::Reader.new` interactions. The history buffer provides previoius or next lines when user presses up/down arrows respectively. However, if you wish to disable this behaviour use `:track_history` option like so:
343
+ The `read_line` and `read_multiline` provide history buffer that tracks all the lines entered during `TTY::Reader.new` interactions. The history buffer provides previous or next lines when user presses up/down arrows respectively. However, if you wish to disable this behaviour use `:track_history` option like so:
337
344
 
338
345
  ```ruby
339
346
  reader = TTY::Reader.new(track_history: false)
@@ -357,7 +364,7 @@ reader = TTY::Reader.new(history_duplicates: false)
357
364
 
358
365
  ### 3.5. `:history_exclude`
359
366
 
360
- This option allows you to exclude lines from being stored in history. It accepts a `Proc` with a line as a first argument. By default it is set to exlude empty lines. To change this:
367
+ This option allows you to exclude lines from being stored in history. It accepts a `Proc` with a line as a first argument. By default it is set to exclude empty lines. To change this:
361
368
 
362
369
  ```ruby
363
370
  reader = TTY::Reader.new(history_exclude: ->(line) { ... })
@@ -0,0 +1,17 @@
1
+ require_relative '../lib/tty-reader'
2
+
3
+ reader = TTY::Reader.new
4
+
5
+ puts "Press a key (or Ctrl-X to exit)"
6
+
7
+ loop do
8
+ print reader.cursor.clear_line
9
+ print "=> "
10
+ char = reader.read_keypress(nonblock: true)
11
+ if ?\C-x == char
12
+ puts "Exiting..."
13
+ exit
14
+ elsif char
15
+ puts "#{char.inspect} [#{char.ord}] (hex: #{char.ord.to_s(16)})"
16
+ end
17
+ end
data/lib/tty/reader.rb CHANGED
@@ -23,7 +23,7 @@ module TTY
23
23
  # Raised when the user hits the interrupt key(Control-C)
24
24
  #
25
25
  # @api public
26
- InputInterrupt = Class.new(StandardError)
26
+ InputInterrupt = Class.new(Interrupt)
27
27
 
28
28
  # Check if Windowz mode
29
29
  #
@@ -215,6 +215,9 @@ module TTY
215
215
  # @param [String] prompt
216
216
  # the prompt to display before input
217
217
  #
218
+ # @param [String] value
219
+ # the value to pre-populate line with
220
+ #
218
221
  # @param [Boolean] echo
219
222
  # if true echo back characters, output nothing otherwise
220
223
  #
@@ -223,10 +226,11 @@ module TTY
223
226
  # @api public
224
227
  def read_line(prompt = '', **options)
225
228
  opts = { echo: true, raw: true }.merge(options)
226
- line = Line.new(prompt: prompt)
229
+ value = options.fetch(:value, '')
230
+ line = Line.new(value, prompt: prompt)
227
231
  screen_width = TTY::Screen.width
228
232
 
229
- output.print(line.prompt)
233
+ output.print(line)
230
234
 
231
235
  while (codes = get_codes(opts)) && (code = codes[0])
232
236
  char = codes.pack('U*')
@@ -277,6 +281,9 @@ module TTY
277
281
  end
278
282
  end
279
283
 
284
+ # trigger before line is printed to allow for line changes
285
+ trigger_key_event(char, line: line.to_s)
286
+
280
287
  if opts[:raw] && opts[:echo]
281
288
  output.print(line.to_s)
282
289
  if char == "\n"
@@ -286,8 +293,6 @@ module TTY
286
293
  end
287
294
  end
288
295
 
289
- trigger_key_event(char, line: line.to_s)
290
-
291
296
  if [CARRIAGE_RETURN, NEWLINE].include?(code)
292
297
  output.puts unless opts[:echo]
293
298
  break
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'io/wait'
4
+
3
5
  require_relative 'keys'
4
6
  require_relative 'mode'
5
7
 
@@ -9,6 +11,8 @@ module TTY
9
11
  ESC = "\e".freeze
10
12
  CSI = "\e[".freeze
11
13
 
14
+ TIMEOUT = 0.1
15
+
12
16
  # Key codes
13
17
  #
14
18
  # @return [Hash[Symbol]]
@@ -43,14 +47,12 @@ module TTY
43
47
  mode.raw(options[:raw]) do
44
48
  mode.echo(options[:echo]) do
45
49
  if options[:nonblock]
46
- input.read_nonblock(1)
50
+ input.wait_readable(TIMEOUT) ? input.getc : nil
47
51
  else
48
52
  input.getc
49
53
  end
50
54
  end
51
55
  end
52
- rescue IO::WaitReadable, EOFError
53
- # no more bytes to read
54
56
  end
55
57
 
56
58
  protected
@@ -209,16 +209,19 @@ module TTY
209
209
  # Remove char from the line at current position
210
210
  #
211
211
  # @api public
212
- def delete
213
- @text.slice!(@cursor, 1)
212
+ def delete(n = 1)
213
+ @text.slice!(@cursor, n)
214
214
  end
215
215
 
216
216
  # Remove char from the line in front of the cursor
217
217
  #
218
+ # @param [Integer] n
219
+ # the number of chars to remove
220
+ #
218
221
  # @api public
219
- def remove
220
- left
221
- @text.slice!(@cursor, 1)
222
+ def remove(n = 1)
223
+ left(n)
224
+ @text.slice!(@cursor, n)
222
225
  end
223
226
 
224
227
  # Full line with prompt as string
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class Reader
5
- VERSION = '0.5.0'
5
+ VERSION = '0.6.0'
6
6
  end # Reader
7
7
  end # TTY
data/spec/spec_helper.rb CHANGED
@@ -16,6 +16,12 @@ end
16
16
  require "bundler/setup"
17
17
  require "tty-reader"
18
18
 
19
+ class StringIO
20
+ def wait_readable(*)
21
+ true
22
+ end
23
+ end
24
+
19
25
  RSpec.configure do |config|
20
26
  # Enable flags like --only-failures and --next-failure
21
27
  config.example_status_persistence_file_path = ".rspec_status"
@@ -108,8 +108,7 @@ RSpec.describe TTY::Reader::Line do
108
108
  line = described_class.new('abcdef')
109
109
  expect(line.cursor).to eq(6)
110
110
 
111
- line.remove
112
- line.remove
111
+ line.remove(2)
113
112
  expect(line.text).to eq('abcd')
114
113
  expect(line.cursor).to eq(4)
115
114
 
@@ -10,14 +10,18 @@ RSpec.describe TTY::Reader, '#read_line' do
10
10
  it 'masks characters' do
11
11
  input << "password\n"
12
12
  input.rewind
13
+
13
14
  answer = reader.read_line(echo: false)
15
+
14
16
  expect(answer).to eq("password\n")
15
17
  end
16
18
 
17
19
  it "echoes characters back" do
18
20
  input << "password\n"
19
21
  input.rewind
22
+
20
23
  answer = reader.read_line
24
+
21
25
  expect(answer).to eq("password\n")
22
26
  expect(output.string).to eq([
23
27
  "\e[2K\e[1Gp",
@@ -35,7 +39,9 @@ RSpec.describe TTY::Reader, '#read_line' do
35
39
  it "doesn't echo characters back" do
36
40
  input << "password\n"
37
41
  input.rewind
42
+
38
43
  answer = reader.read_line(echo: false)
44
+
39
45
  expect(answer).to eq("password\n")
40
46
  expect(output.string).to eq("\n")
41
47
  end
@@ -43,7 +49,9 @@ RSpec.describe TTY::Reader, '#read_line' do
43
49
  it "displays a prompt before input" do
44
50
  input << "aa\n"
45
51
  input.rewind
52
+
46
53
  answer = reader.read_line('>> ')
54
+
47
55
  expect(answer).to eq("aa\n")
48
56
  expect(output.string).to eq([
49
57
  ">> ",
@@ -53,17 +61,36 @@ RSpec.describe TTY::Reader, '#read_line' do
53
61
  ].join)
54
62
  end
55
63
 
64
+ it "displays custom input with a prompt" do
65
+ input << "aa\n"
66
+ input.rewind
67
+
68
+ answer = reader.read_line("> ", value: "xx")
69
+
70
+ expect(answer).to eq("xxaa\n")
71
+ expect(output.string).to eq([
72
+ "> xx",
73
+ "\e[2K\e[1G> xxa",
74
+ "\e[2K\e[1G> xxaa",
75
+ "\e[2K\e[1G> xxaa\n"
76
+ ].join)
77
+ end
78
+
56
79
  it 'deletes characters when backspace pressed' do
57
80
  input << "aa\ba\bcc\n"
58
81
  input.rewind
82
+
59
83
  answer = reader.read_line
84
+
60
85
  expect(answer).to eq("acc\n")
61
86
  end
62
87
 
63
88
  it 'reads multibyte line' do
64
89
  input << "한글"
65
90
  input.rewind
91
+
66
92
  answer = reader.read_line
93
+
67
94
  expect(answer).to eq("한글")
68
95
  end
69
96
  end
data/tty-reader.gemspec CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
6
6
  spec.name = "tty-reader"
7
7
  spec.version = TTY::Reader::VERSION
8
8
  spec.authors = ["Piotr Murach"]
9
- spec.email = [""]
9
+ spec.email = ["me@piotrmurach.com"]
10
10
  spec.summary = %q{A set of methods for processing keyboard input in character, line and multiline modes.}
11
11
  spec.description = %q{A set of methods for processing keyboard input in character, line and multiline modes. It maintains history of entered input with an ability to recall and re-edit those inputs. It lets you register to listen for keystroke events and trigger custom key events yourself.}
12
12
  spec.homepage = "https://piotrmurach.github.io/tty"
@@ -22,10 +22,10 @@ Gem::Specification.new do |spec|
22
22
  spec.required_ruby_version = '>= 2.0.0'
23
23
 
24
24
  spec.add_dependency "wisper", "~> 2.0.0"
25
- spec.add_dependency "tty-screen", "~> 0.6.4"
26
- spec.add_dependency "tty-cursor", "~> 0.6.0"
25
+ spec.add_dependency "tty-screen", "~> 0.7"
26
+ spec.add_dependency "tty-cursor", "~> 0.7"
27
27
 
28
- spec.add_development_dependency "bundler", ">= 1.5.0", "< 2.0"
29
- spec.add_development_dependency "rake", "~> 12.0"
28
+ spec.add_development_dependency "bundler", ">= 1.5.0"
29
+ spec.add_development_dependency "rake"
30
30
  spec.add_development_dependency "rspec", "~> 3.0"
31
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty-reader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-24 00:00:00.000000000 Z
11
+ date: 2019-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: wisper
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.6.4
33
+ version: '0.7'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.6.4
40
+ version: '0.7'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: tty-cursor
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.6.0
47
+ version: '0.7'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.6.0
54
+ version: '0.7'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -59,9 +59,6 @@ dependencies:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: 1.5.0
62
- - - "<"
63
- - !ruby/object:Gem::Version
64
- version: '2.0'
65
62
  type: :development
66
63
  prerelease: false
67
64
  version_requirements: !ruby/object:Gem::Requirement
@@ -69,23 +66,20 @@ dependencies:
69
66
  - - ">="
70
67
  - !ruby/object:Gem::Version
71
68
  version: 1.5.0
72
- - - "<"
73
- - !ruby/object:Gem::Version
74
- version: '2.0'
75
69
  - !ruby/object:Gem::Dependency
76
70
  name: rake
77
71
  requirement: !ruby/object:Gem::Requirement
78
72
  requirements:
79
- - - "~>"
73
+ - - ">="
80
74
  - !ruby/object:Gem::Version
81
- version: '12.0'
75
+ version: '0'
82
76
  type: :development
83
77
  prerelease: false
84
78
  version_requirements: !ruby/object:Gem::Requirement
85
79
  requirements:
86
- - - "~>"
80
+ - - ">="
87
81
  - !ruby/object:Gem::Version
88
- version: '12.0'
82
+ version: '0'
89
83
  - !ruby/object:Gem::Dependency
90
84
  name: rspec
91
85
  requirement: !ruby/object:Gem::Requirement
@@ -105,7 +99,7 @@ description: A set of methods for processing keyboard input in character, line a
105
99
  and re-edit those inputs. It lets you register to listen for keystroke events and
106
100
  trigger custom key events yourself.
107
101
  email:
108
- - ''
102
+ - me@piotrmurach.com
109
103
  executables: []
110
104
  extensions: []
111
105
  extra_rdoc_files: []
@@ -119,6 +113,7 @@ files:
119
113
  - bin/console
120
114
  - bin/setup
121
115
  - examples/keypress.rb
116
+ - examples/keypress_nonblock.rb
122
117
  - examples/line.rb
123
118
  - examples/multiline.rb
124
119
  - examples/noecho.rb
@@ -166,8 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
161
  - !ruby/object:Gem::Version
167
162
  version: '0'
168
163
  requirements: []
169
- rubyforge_project:
170
- rubygems_version: 2.7.3
164
+ rubygems_version: 3.0.3
171
165
  signing_key:
172
166
  specification_version: 4
173
167
  summary: A set of methods for processing keyboard input in character, line and multiline