tty-reader 0.8.0 → 0.9.0
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 +16 -0
- data/LICENSE.txt +1 -1
- data/README.md +11 -10
- data/lib/tty/reader.rb +105 -65
- data/lib/tty/reader/console.rb +10 -7
- data/lib/tty/reader/history.rb +37 -12
- data/lib/tty/reader/version.rb +1 -1
- data/lib/tty/reader/win_console.rb +13 -12
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7766384b749f39d5646ce4ff20d95c1bdfdaac5af096d4a996a7a347379874ee
|
4
|
+
data.tar.gz: c5a85b72fae90d018f79acdd9303c9926b75236fb67a2b24e641f6737a001372
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74bd44d949d086d8debe53bdd571755b263fce26d991dd7798d45fbb24513cdadea0a29c31e3388a65ce8f81f3b3514955d69c44c30af87465ba32933f5f6997
|
7
|
+
data.tar.gz: 4ad0c8d086506a2672f2a8bb8db1fbd9f951e2f1f9200f4c258e82967cf61bbea209a33fdd86aa4cfb99adf4e5b7fcdcf6e5b0f992da6fe9956daa5d5aade238
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## [v0.9.0] - 2020-12-08
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Add buffer to save input when traversing history and restore it back
|
7
|
+
similar to shell
|
8
|
+
|
9
|
+
### Changed
|
10
|
+
* Pressing :down no longer erases the #read_line input if history is disabled by Charles Pence (@pencechp)
|
11
|
+
* Change Reader initializer to use keyword arguments in place of options hash
|
12
|
+
* Change history to only exclude empty lines without any space or invisible characters
|
13
|
+
* Change all input reading methods to use explicit keyword arguments
|
14
|
+
|
15
|
+
### Fix
|
16
|
+
* Fix #read_multiline :value parameter to insert content only once in the first line
|
17
|
+
|
3
18
|
## [v0.8.0] - 2020-06-28
|
4
19
|
|
5
20
|
### Changed
|
@@ -73,6 +88,7 @@
|
|
73
88
|
|
74
89
|
* Initial implementation and release
|
75
90
|
|
91
|
+
[v0.9.0]: https://github.com/piotrmurach/tty-reader/compare/v0.8.0...v0.9.0
|
76
92
|
[v0.8.0]: https://github.com/piotrmurach/tty-reader/compare/v0.7.0...v0.8.0
|
77
93
|
[v0.7.0]: https://github.com/piotrmurach/tty-reader/compare/v0.6.0...v0.7.0
|
78
94
|
[v0.6.0]: https://github.com/piotrmurach/tty-reader/compare/v0.5.0...v0.6.0
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2017 Piotr Murach
|
3
|
+
Copyright (c) 2017 Piotr Murach (https://piotrmurach.com)
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
<div align="center">
|
2
|
-
<a href="https://
|
2
|
+
<a href="https://ttytoolkit.org"><img width="130" src="https://github.com/piotrmurach/tty/raw/master/images/tty.png" alt="TTY Toolkit logo" /></a>
|
3
3
|
</div>
|
4
4
|
|
5
5
|
# TTY::Reader [][gitter]
|
6
6
|
|
7
7
|
[][gem]
|
8
|
-
[][gh_actions_ci]
|
9
9
|
[][appveyor]
|
10
10
|
[][codeclimate]
|
11
11
|
[][coverage]
|
@@ -13,6 +13,7 @@
|
|
13
13
|
|
14
14
|
[gitter]: https://gitter.im/piotrmurach/tty
|
15
15
|
[gem]: http://badge.fury.io/rb/tty-reader
|
16
|
+
[gh_actions_ci]: https://github.com/piotrmurach/tty-reader/actions?query=workflow%3ACI
|
16
17
|
[travis]: http://travis-ci.org/piotrmurach/tty-reader
|
17
18
|
[appveyor]: https://ci.appveyor.com/project/piotrmurach/tty-reader
|
18
19
|
[codeclimate]: https://codeclimate.com/github/piotrmurach/tty-reader/maintainability
|
@@ -48,7 +49,7 @@ The `tty-reader` is not compatible with the GNU Readline and doesn't aim to be.
|
|
48
49
|
Add this line to your application's Gemfile:
|
49
50
|
|
50
51
|
```ruby
|
51
|
-
gem
|
52
|
+
gem "tty-reader"
|
52
53
|
```
|
53
54
|
|
54
55
|
And then execute:
|
@@ -99,7 +100,7 @@ Finally, keep asking user for line input with a `=>` as a prompt:
|
|
99
100
|
|
100
101
|
```ruby
|
101
102
|
loop do
|
102
|
-
reader.read_line(
|
103
|
+
reader.read_line("=> ")
|
103
104
|
end
|
104
105
|
```
|
105
106
|
|
@@ -207,11 +208,11 @@ For example, to add listen to vim like navigation keys, one would do the followi
|
|
207
208
|
|
208
209
|
```ruby
|
209
210
|
reader.on(:keypress) do |event|
|
210
|
-
if event.value ==
|
211
|
+
if event.value == "j"
|
211
212
|
...
|
212
213
|
end
|
213
214
|
|
214
|
-
if event.value ==
|
215
|
+
if event.value == "k"
|
215
216
|
...
|
216
217
|
end
|
217
218
|
end
|
@@ -220,8 +221,8 @@ end
|
|
220
221
|
You can subscribe to more than one event:
|
221
222
|
|
222
223
|
```ruby
|
223
|
-
|
224
|
-
.on(:keydown) { |
|
224
|
+
reader.on(:keypress) { |event| ... }
|
225
|
+
.on(:keydown) { |event| ... }
|
225
226
|
```
|
226
227
|
|
227
228
|
### 2.5 subscribe
|
@@ -274,10 +275,10 @@ To add vim bindings for line editing you could discern between alphanumeric inpu
|
|
274
275
|
|
275
276
|
```ruby
|
276
277
|
reader.on(:keypress) do |event|
|
277
|
-
if event.value ==
|
278
|
+
if event.value == "j"
|
278
279
|
reader.trigger(:keydown)
|
279
280
|
end
|
280
|
-
if evevnt.value ==
|
281
|
+
if evevnt.value == "k"
|
281
282
|
reader.trigger(:keyup)
|
282
283
|
end
|
283
284
|
end
|
data/lib/tty/reader.rb
CHANGED
@@ -20,6 +20,15 @@ module TTY
|
|
20
20
|
class Reader
|
21
21
|
include Wisper::Publisher
|
22
22
|
|
23
|
+
# Key codes
|
24
|
+
CARRIAGE_RETURN = 13
|
25
|
+
NEWLINE = 10
|
26
|
+
BACKSPACE = 8
|
27
|
+
DELETE = 127
|
28
|
+
|
29
|
+
# Keys that terminate input
|
30
|
+
EXIT_KEYS = [:ctrl_d, :ctrl_z]
|
31
|
+
|
23
32
|
# Raised when the user hits the interrupt key(Control-C)
|
24
33
|
#
|
25
34
|
# @api public
|
@@ -47,42 +56,44 @@ module TTY
|
|
47
56
|
|
48
57
|
attr_reader :cursor
|
49
58
|
|
50
|
-
# Key codes
|
51
|
-
CARRIAGE_RETURN = 13
|
52
|
-
NEWLINE = 10
|
53
|
-
BACKSPACE = 8
|
54
|
-
DELETE = 127
|
55
|
-
|
56
59
|
# Initialize a Reader
|
57
60
|
#
|
58
61
|
# @param [IO] input
|
59
62
|
# the input stream
|
60
63
|
# @param [IO] output
|
61
64
|
# the output stream
|
62
|
-
# @param [
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
65
|
+
# @param [Symbol] interrupt
|
66
|
+
# the way to handle the Ctrl+C key out of :signal, :exit, :noop
|
67
|
+
# @param [Hash] env
|
68
|
+
# the environment variables
|
69
|
+
# @param [Boolean] track_history
|
66
70
|
# disable line history tracking, true by default
|
71
|
+
# @param [Boolean] history_cycle
|
72
|
+
# allow cycling through history, false by default
|
73
|
+
# @param [Boolean] history_duplicates
|
74
|
+
# allow duplicate entires, false by default
|
75
|
+
# @param [Proc] history_exclude
|
76
|
+
# exclude lines from history, by default all lines are stored
|
67
77
|
#
|
68
78
|
# @api public
|
69
|
-
def initialize(
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
@
|
74
|
-
|
75
|
-
@
|
76
|
-
@
|
77
|
-
|
78
|
-
@
|
79
|
-
@
|
80
|
-
|
81
|
-
|
82
|
-
@
|
83
|
-
|
84
|
-
h.
|
85
|
-
h.
|
79
|
+
def initialize(input: $stdin, output: $stdout, interrupt: :error,
|
80
|
+
env: ENV, track_history: true, history_cycle: false,
|
81
|
+
history_exclude: History::DEFAULT_EXCLUDE,
|
82
|
+
history_duplicates: false)
|
83
|
+
@input = input
|
84
|
+
@output = output
|
85
|
+
@interrupt = interrupt
|
86
|
+
@env = env
|
87
|
+
@track_history = track_history
|
88
|
+
@history_cycle = history_cycle
|
89
|
+
@history_exclude = history_exclude
|
90
|
+
@history_duplicates = history_duplicates
|
91
|
+
|
92
|
+
@console = select_console(input)
|
93
|
+
@history = History.new do |h|
|
94
|
+
h.cycle = history_cycle
|
95
|
+
h.duplicates = history_duplicates
|
96
|
+
h.exclude = history_exclude
|
86
97
|
end
|
87
98
|
@stop = false # gathering input
|
88
99
|
@cursor = TTY::Cursor
|
@@ -155,24 +166,26 @@ module TTY
|
|
155
166
|
output.sync = bufferring
|
156
167
|
end
|
157
168
|
|
158
|
-
# Read a keypress
|
159
|
-
#
|
169
|
+
# Read a keypress including invisible multibyte codes and return
|
170
|
+
# a character as a string.
|
160
171
|
# Nothing is echoed to the console. This call will block for a
|
161
172
|
# single keypress, but will not wait for Enter to be pressed.
|
162
173
|
#
|
163
|
-
# @param [
|
164
|
-
# @option options [Boolean] echo
|
174
|
+
# @param [Boolean] echo
|
165
175
|
# whether to echo chars back or not, defaults to false
|
166
|
-
# @option
|
167
|
-
# whenther raw mode enabled, defaults to true
|
176
|
+
# @option [Boolean] raw
|
177
|
+
# whenther raw mode is enabled, defaults to true
|
178
|
+
# @option [Boolean] nonblock
|
179
|
+
# whether to wait for input or not, defaults to false
|
168
180
|
#
|
169
181
|
# @return [String]
|
170
182
|
#
|
171
183
|
# @api public
|
172
|
-
def read_keypress(
|
173
|
-
|
174
|
-
|
175
|
-
|
184
|
+
def read_keypress(echo: false, raw: true, nonblock: false)
|
185
|
+
codes = unbufferred do
|
186
|
+
get_codes(echo: echo, raw: raw, nonblock: nonblock)
|
187
|
+
end
|
188
|
+
char = codes ? codes.pack("U*") : nil
|
176
189
|
|
177
190
|
trigger_key_event(char) if char
|
178
191
|
char
|
@@ -181,19 +194,24 @@ module TTY
|
|
181
194
|
|
182
195
|
# Get input code points
|
183
196
|
#
|
184
|
-
# @param [
|
197
|
+
# @param [Boolean] echo
|
198
|
+
# whether to echo chars back or not, defaults to false
|
199
|
+
# @option [Boolean] raw
|
200
|
+
# whenther raw mode is enabled, defaults to true
|
201
|
+
# @option [Boolean] nonblock
|
202
|
+
# whether to wait for input or not, defaults to false
|
185
203
|
# @param [Array[Integer]] codes
|
204
|
+
# the currently read char code points
|
186
205
|
#
|
187
206
|
# @return [Array[Integer]]
|
188
207
|
#
|
189
208
|
# @api private
|
190
|
-
def get_codes(
|
191
|
-
|
192
|
-
char = console.get_char(opts)
|
209
|
+
def get_codes(echo: true, raw: false, nonblock: false, codes: [])
|
210
|
+
char = console.get_char(echo: echo, raw: raw, nonblock: nonblock)
|
193
211
|
handle_interrupt if console.keys[char] == :ctrl_c
|
194
212
|
return if char.nil?
|
195
|
-
codes << char.ord
|
196
213
|
|
214
|
+
codes << char.ord
|
197
215
|
condition = proc { |escape|
|
198
216
|
(codes - escape).empty? ||
|
199
217
|
(escape - codes).empty? &&
|
@@ -201,7 +219,8 @@ module TTY
|
|
201
219
|
}
|
202
220
|
|
203
221
|
while console.escape_codes.any?(&condition)
|
204
|
-
char_codes = get_codes(
|
222
|
+
char_codes = get_codes(echo: echo, raw: raw,
|
223
|
+
nonblock: true, codes: codes)
|
205
224
|
break if char_codes.nil?
|
206
225
|
end
|
207
226
|
|
@@ -214,49 +233,51 @@ module TTY
|
|
214
233
|
#
|
215
234
|
# @param [String] prompt
|
216
235
|
# the prompt to display before input
|
217
|
-
#
|
218
236
|
# @param [String] value
|
219
237
|
# the value to pre-populate line with
|
220
|
-
#
|
221
238
|
# @param [Boolean] echo
|
222
|
-
#
|
239
|
+
# whether to echo chars back or not, defaults to false
|
240
|
+
# @option [Boolean] raw
|
241
|
+
# whenther raw mode is enabled, defaults to true
|
242
|
+
# @option [Boolean] nonblock
|
243
|
+
# whether to wait for input or not, defaults to false
|
223
244
|
#
|
224
245
|
# @return [String]
|
225
246
|
#
|
226
247
|
# @api public
|
227
|
-
def read_line(prompt = "",
|
228
|
-
opts = { echo: true, raw: true }.merge(options)
|
229
|
-
value = options.fetch(:value, "")
|
248
|
+
def read_line(prompt = "", value: "", echo: true, raw: true, nonblock: false)
|
230
249
|
line = Line.new(value, prompt: prompt)
|
231
250
|
screen_width = TTY::Screen.width
|
251
|
+
buffer = ""
|
232
252
|
|
233
253
|
output.print(line)
|
234
254
|
|
235
|
-
while (codes = get_codes(
|
255
|
+
while (codes = get_codes(echo: echo, raw: raw, nonblock: nonblock)) &&
|
256
|
+
(code = codes[0])
|
236
257
|
char = codes.pack("U*")
|
237
258
|
|
238
|
-
if
|
259
|
+
if EXIT_KEYS.include?(console.keys[char])
|
239
260
|
trigger_key_event(char, line: line.to_s)
|
240
261
|
break
|
241
262
|
end
|
242
263
|
|
243
|
-
if
|
264
|
+
if raw && echo
|
244
265
|
clear_display(line, screen_width)
|
245
266
|
end
|
246
267
|
|
247
|
-
if console.keys[char] == :backspace ||
|
268
|
+
if console.keys[char] == :backspace || code == BACKSPACE
|
248
269
|
if !line.start?
|
249
270
|
line.left
|
250
271
|
line.delete
|
251
272
|
end
|
252
|
-
elsif console.keys[char] == :delete ||
|
273
|
+
elsif console.keys[char] == :delete || code == DELETE
|
253
274
|
line.delete
|
254
275
|
elsif console.keys[char].to_s =~ /ctrl_/
|
255
276
|
# skip
|
256
277
|
elsif console.keys[char] == :up
|
257
278
|
line.replace(history_previous) if history_previous?
|
258
279
|
elsif console.keys[char] == :down
|
259
|
-
line.replace(history_next? ? history_next :
|
280
|
+
line.replace(history_next? ? history_next : buffer) if track_history?
|
260
281
|
elsif console.keys[char] == :left
|
261
282
|
line.left
|
262
283
|
elsif console.keys[char] == :right
|
@@ -266,15 +287,16 @@ module TTY
|
|
266
287
|
elsif console.keys[char] == :end
|
267
288
|
line.move_to_end
|
268
289
|
else
|
269
|
-
if
|
290
|
+
if raw && code == CARRIAGE_RETURN
|
270
291
|
char = "\n"
|
271
292
|
line.move_to_end
|
272
293
|
end
|
273
294
|
line.insert(char)
|
295
|
+
buffer = line.text
|
274
296
|
end
|
275
297
|
|
276
|
-
if (console.keys[char] == :backspace ||
|
277
|
-
if
|
298
|
+
if (console.keys[char] == :backspace || code == BACKSPACE) && echo
|
299
|
+
if raw
|
278
300
|
output.print("\e[1X") unless line.start?
|
279
301
|
else
|
280
302
|
output.print(?\s + (line.start? ? "" : ?\b))
|
@@ -284,7 +306,7 @@ module TTY
|
|
284
306
|
# trigger before line is printed to allow for line changes
|
285
307
|
trigger_key_event(char, line: line.to_s)
|
286
308
|
|
287
|
-
if
|
309
|
+
if raw && echo
|
288
310
|
output.print(line.to_s)
|
289
311
|
if char == "\n"
|
290
312
|
line.move_to_start
|
@@ -294,13 +316,16 @@ module TTY
|
|
294
316
|
end
|
295
317
|
|
296
318
|
if [CARRIAGE_RETURN, NEWLINE].include?(code)
|
297
|
-
|
319
|
+
buffer = ""
|
320
|
+
output.puts unless echo
|
298
321
|
break
|
299
322
|
end
|
300
323
|
end
|
301
|
-
|
324
|
+
|
325
|
+
if track_history? && echo
|
302
326
|
add_to_history(line.text.rstrip)
|
303
327
|
end
|
328
|
+
|
304
329
|
line.text
|
305
330
|
end
|
306
331
|
|
@@ -351,19 +376,33 @@ module TTY
|
|
351
376
|
#
|
352
377
|
# @param [String] prompt
|
353
378
|
# the prompt displayed before the input
|
379
|
+
# @param [String] value
|
380
|
+
# the value to pre-populate line with
|
381
|
+
# @param [Boolean] echo
|
382
|
+
# whether to echo chars back or not, defaults to false
|
383
|
+
# @option [Boolean] raw
|
384
|
+
# whenther raw mode is enabled, defaults to true
|
385
|
+
# @option [Boolean] nonblock
|
386
|
+
# whether to wait for input or not, defaults to false
|
354
387
|
#
|
355
388
|
# @yield [String] line
|
356
389
|
#
|
357
390
|
# @return [Array[String]]
|
358
391
|
#
|
359
392
|
# @api public
|
360
|
-
def read_multiline(
|
393
|
+
def read_multiline(prompt = "", value: "", echo: true, raw: true,
|
394
|
+
nonblock: false)
|
361
395
|
@stop = false
|
362
396
|
lines = []
|
397
|
+
empty_str = ""
|
398
|
+
|
363
399
|
loop do
|
364
|
-
line = read_line(
|
365
|
-
|
400
|
+
line = read_line(prompt, value: value, echo: echo, raw: raw,
|
401
|
+
nonblock: nonblock)
|
402
|
+
value = empty_str unless value.empty? # reset
|
403
|
+
break if !line || line == empty_str
|
366
404
|
next if line !~ /\S/ && !@stop
|
405
|
+
|
367
406
|
if block_given?
|
368
407
|
yield(line) unless line.to_s.empty?
|
369
408
|
else
|
@@ -371,6 +410,7 @@ module TTY
|
|
371
410
|
end
|
372
411
|
break if @stop
|
373
412
|
end
|
413
|
+
|
374
414
|
lines
|
375
415
|
end
|
376
416
|
alias read_lines read_multiline
|
@@ -449,7 +489,7 @@ module TTY
|
|
449
489
|
when Proc
|
450
490
|
@interrupt.call
|
451
491
|
when :noop
|
452
|
-
|
492
|
+
# Noop
|
453
493
|
else
|
454
494
|
raise InputInterrupt
|
455
495
|
end
|
data/lib/tty/reader/console.rb
CHANGED
@@ -36,17 +36,20 @@ module TTY
|
|
36
36
|
|
37
37
|
# Get a character from console with echo
|
38
38
|
#
|
39
|
-
# @param [
|
40
|
-
#
|
41
|
-
#
|
39
|
+
# @param [Boolean] echo
|
40
|
+
# whether to echo input back or not, defaults to true
|
41
|
+
# @param [Boolean] raw
|
42
|
+
# whether to use raw mode or not, defaults to false
|
43
|
+
# @param [Boolean] nonblock
|
44
|
+
# whether to wait for input or not, defaults to false
|
42
45
|
#
|
43
46
|
# @return [String]
|
44
47
|
#
|
45
48
|
# @api private
|
46
|
-
def get_char(
|
47
|
-
mode.raw(
|
48
|
-
mode.echo(
|
49
|
-
if
|
49
|
+
def get_char(echo: true, raw: false, nonblock: false)
|
50
|
+
mode.raw(raw) do
|
51
|
+
mode.echo(echo) do
|
52
|
+
if nonblock
|
50
53
|
input.wait_readable(TIMEOUT) ? input.getc : nil
|
51
54
|
else
|
52
55
|
input.getc
|
data/lib/tty/reader/history.rb
CHANGED
@@ -15,49 +15,72 @@ module TTY
|
|
15
15
|
# Default maximum size
|
16
16
|
DEFAULT_SIZE = 32 << 4
|
17
17
|
|
18
|
+
# Default exclude
|
19
|
+
DEFAULT_EXCLUDE = ->(line) { line.chomp == "" }
|
20
|
+
|
18
21
|
def_delegators :@history, :size, :length, :to_s, :inspect
|
19
22
|
|
20
23
|
# Set and retrieve the maximum size of the buffer
|
21
24
|
attr_accessor :max_size
|
22
25
|
|
26
|
+
# The current index
|
27
|
+
#
|
28
|
+
# @return [Integer]
|
29
|
+
#
|
30
|
+
# @api private
|
23
31
|
attr_reader :index
|
24
32
|
|
33
|
+
# Decides whether or not to allow cycling through stored lines.
|
34
|
+
#
|
35
|
+
# @return [Boolean]
|
36
|
+
#
|
37
|
+
# @api public
|
25
38
|
attr_accessor :cycle
|
26
39
|
|
40
|
+
# Decides wether or not duplicate lines are stored.
|
41
|
+
#
|
42
|
+
# @return [Boolean]
|
43
|
+
#
|
44
|
+
# @api public
|
27
45
|
attr_accessor :duplicates
|
28
46
|
|
47
|
+
# Dictates which lines are stored.
|
48
|
+
#
|
49
|
+
# @return [Proc]
|
50
|
+
#
|
51
|
+
# @public
|
29
52
|
attr_accessor :exclude
|
30
53
|
|
31
54
|
# Create a History buffer
|
32
55
|
#
|
33
|
-
# param [Integer] max_size
|
56
|
+
# @param [Integer] max_size
|
34
57
|
# the maximum size for history buffer
|
35
|
-
#
|
36
|
-
# param [Hash[Symbol]] options
|
37
|
-
# @option options [Boolean] :cycle
|
58
|
+
# @param [Boolean] cycle
|
38
59
|
# whether or not the history should cycle, false by default
|
39
|
-
# @
|
60
|
+
# @param [Boolean] duplicates
|
40
61
|
# whether or not to store duplicates, true by default
|
41
|
-
# @
|
62
|
+
# @param [Boolean] exclude
|
42
63
|
# a Proc to exclude items from storing in history
|
43
64
|
#
|
44
65
|
# @api public
|
45
|
-
def initialize(max_size = DEFAULT_SIZE,
|
66
|
+
def initialize(max_size = DEFAULT_SIZE, duplicates: true, cycle: false,
|
67
|
+
exclude: DEFAULT_EXCLUDE)
|
46
68
|
@max_size = max_size
|
47
69
|
@index = nil
|
48
70
|
@history = []
|
49
|
-
@duplicates =
|
50
|
-
@exclude =
|
51
|
-
@cycle =
|
71
|
+
@duplicates = duplicates
|
72
|
+
@exclude = exclude
|
73
|
+
@cycle = cycle
|
74
|
+
|
52
75
|
yield self if block_given?
|
53
76
|
end
|
54
77
|
|
55
78
|
# Iterates over history lines
|
56
79
|
#
|
57
80
|
# @api public
|
58
|
-
def each
|
81
|
+
def each(&block)
|
59
82
|
if block_given?
|
60
|
-
@history.each
|
83
|
+
@history.each(&block)
|
61
84
|
else
|
62
85
|
@history.to_enum
|
63
86
|
end
|
@@ -85,6 +108,7 @@ module TTY
|
|
85
108
|
# @api public
|
86
109
|
def next
|
87
110
|
return if size.zero?
|
111
|
+
|
88
112
|
if @index == size - 1
|
89
113
|
@index = 0 if @cycle
|
90
114
|
else
|
@@ -99,6 +123,7 @@ module TTY
|
|
99
123
|
# Move the pointer to the previous line in the history
|
100
124
|
def previous
|
101
125
|
return if size.zero?
|
126
|
+
|
102
127
|
if @index.zero?
|
103
128
|
@index = size - 1 if @cycle
|
104
129
|
else
|
data/lib/tty/reader/version.rb
CHANGED
@@ -32,26 +32,27 @@ module TTY
|
|
32
32
|
|
33
33
|
# Get a character from console blocking for input
|
34
34
|
#
|
35
|
-
# @param [
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
35
|
+
# @param [Boolean] echo
|
36
|
+
# whether to echo input back or not, defaults to true
|
37
|
+
# @param [Boolean] raw
|
38
|
+
# whether to use raw mode or not, defaults to false
|
39
|
+
# @param [Boolean] nonblock
|
40
|
+
# whether to wait for input or not, defaults to false
|
40
41
|
#
|
41
42
|
# @return [String]
|
42
43
|
#
|
43
44
|
# @api private
|
44
|
-
def get_char(
|
45
|
-
if
|
46
|
-
if
|
45
|
+
def get_char(echo: true, raw: false, nonblock: false)
|
46
|
+
if raw && echo
|
47
|
+
if nonblock
|
47
48
|
get_char_echo_non_blocking
|
48
49
|
else
|
49
50
|
get_char_echo_blocking
|
50
51
|
end
|
51
|
-
elsif
|
52
|
-
|
53
|
-
elsif !
|
54
|
-
|
52
|
+
elsif raw && !echo
|
53
|
+
nonblock ? get_char_non_blocking : get_char_blocking
|
54
|
+
elsif !raw && !echo
|
55
|
+
nonblock ? get_char_non_blocking : get_char_blocking
|
55
56
|
else
|
56
57
|
@input.getc
|
57
58
|
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.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tty-screen
|
@@ -70,14 +70,14 @@ dependencies:
|
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '3.0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '3.0'
|
83
83
|
description: A set of methods for processing keyboard input in character, line and
|