tty-reader 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4450cd173fbc5dece09c32d0ad799bb5fcccff3a
4
- data.tar.gz: e744eaefca8e5b03f79b41d502fe71a2ba8b3166
3
+ metadata.gz: f1b83301002055869c17bb4ecb0571be89b2d8e0
4
+ data.tar.gz: 39bd25b1b47c2542c000a407a2839bd4cba12c31
5
5
  SHA512:
6
- metadata.gz: b113279156eb75f4f2c7079abe5c225993c4f0b24bd33fb07dd45366e316bf9a9356ea23b0f96cf122e36502fa85161d8ccc33f7a4e8ef2dae57faf184f4f77a
7
- data.tar.gz: 21fd68ce3809c21a88dd24d18ec25348e4111fc41a7828c6c2bb3ccb6279f7fed3477c1261d9d65e3911f8d6c5656f92f908fee5ac9d1ab44609100feb9c9a5c
6
+ metadata.gz: 08c4198829dcc5a4f95c865c4dfcb2c4be9711885a3d071c6f1d9f917e8dc20083d558dde98ffc38af0d7e6ce6de9f4fbfeecb1158109f2905adb047aa6970f1
7
+ data.tar.gz: 3899ba4f5461099024379df0058deb177dbf1a45d6fb250970f3a639adf792f9563773adeae1b240f2feb41241d6ec45b4a012c15f4b1c234ad6bf582f7c0ac4
data/.travis.yml CHANGED
@@ -2,17 +2,17 @@
2
2
  language: ruby
3
3
  sudo: false
4
4
  cache: bundler
5
+ before_install: "gem update bundler"
5
6
  bundler_args: --without tools
6
7
  script: "bundle exec rake ci"
7
8
  rvm:
8
- - 1.9.3
9
9
  - 2.0.0
10
10
  - 2.1.10
11
- - 2.2.6
12
- - 2.3.3
13
- - 2.4.1
11
+ - 2.2.9
12
+ - 2.3.6
13
+ - 2.4.3
14
14
  - ruby-head
15
- - jruby-9000
15
+ - jruby-9.1.1.0
16
16
  - jruby-head
17
17
  matrix:
18
18
  allow_failures:
data/CHANGELOG.md CHANGED
@@ -1,7 +1,28 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.2.0] - 2018-01-01
4
+
5
+ ### Added
6
+ * Add home & end keys support in #read_line
7
+ * Add tty-screen & tty-cursor dependencies
8
+
9
+ ### Changed
10
+ * Change Codes to Keys and inverse keys lookup to allow for different system keys matching same name.
11
+ * Change Reader#initialize to only accept options and make input and output options as well.
12
+ * Change #read_line to print newline character in noecho mode
13
+ * Change Reader::Line to include prompt prefix
14
+ * Change Reader#initialize to only accept options in place of positional arguments
15
+ * Change Reader to expose history options
16
+
17
+ ### Fixed
18
+ * Fix issues with recognising :home & :end keys on different terminals
19
+ * Fix #read_line to work with strings spanning multiple screen widths and allow copy-pasting a long string without repeating prompt
20
+ * Fix backspace keystroke in cooked mode
21
+ * Fix history to only save lines in echo mode
22
+
3
23
  ## [v0.1.0] - 2017-08-30
4
24
 
5
25
  * Initial implementation and release
6
26
 
7
- [v0.1.0]: https://github.com/peter-murach/tty-reader/compare/v0.1.0
27
+ [v0.2.0]: https://github.com/piotrmurach/tty-reader/compare/v0.1.0...v0.2.0
28
+ [v0.1.0]: https://github.com/piotrmurach/tty-reader/compare/v0.1.0
data/Gemfile CHANGED
@@ -5,10 +5,9 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
5
5
  gemspec
6
6
 
7
7
  group :test do
8
- gem 'benchmark-ips', '~> 2.0.0'
9
- gem 'simplecov', '~> 0.10.0'
10
- gem 'coveralls', '~> 0.8.2'
11
- gem 'term-ansicolor', '=1.3.2'
8
+ gem 'benchmark-ips', '~> 2.7.2'
9
+ gem 'simplecov', '~> 0.14.1'
10
+ gem 'coveralls', '~> 0.8.21'
12
11
  end
13
12
 
14
13
  group :tools do
@@ -16,6 +15,6 @@ group :tools do
16
15
  end
17
16
 
18
17
  group :metrics do
19
- gem 'yard', '~> 0.8.7'
18
+ gem 'yard', '~> 0.9.12'
20
19
  gem 'yardstick', '~> 0.9.9'
21
20
  end
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Gem Version](https://badge.fury.io/rb/tty-reader.svg)][gem]
4
4
  [![Build Status](https://secure.travis-ci.org/piotrmurach/tty-reader.svg?branch=master)][travis]
5
5
  [![Build status](https://ci.appveyor.com/api/projects/status/cj4owy2vlty2q1ko?svg=true)][appveyor]
6
- [![Code Climate](https://codeclimate.com/github/piotrmurach/tty-reader/badges/gpa.svg)][codeclimate]
6
+ [![Maintainability](https://api.codeclimate.com/v1/badges/2f68d5e8ecc271bda820/maintainability)][codeclimate]
7
7
  [![Coverage Status](https://coveralls.io/repos/github/piotrmurach/tty-reader/badge.svg)][coverage]
8
8
  [![Inline docs](http://inch-ci.org/github/piotrmurach/tty-reader.svg?branch=master)][inchpages]
9
9
 
@@ -11,7 +11,7 @@
11
11
  [gem]: http://badge.fury.io/rb/tty-reader
12
12
  [travis]: http://travis-ci.org/piotrmurach/tty-reader
13
13
  [appveyor]: https://ci.appveyor.com/project/piotrmurach/tty-reader
14
- [codeclimate]: https://codeclimate.com/github/piotrmurach/tty-reader
14
+ [codeclimate]: https://codeclimate.com/github/piotrmurach/tty-reader/maintainability
15
15
  [coverage]: https://coveralls.io/github/piotrmurach/tty-reader
16
16
  [inchpages]: http://inch-ci.org/github/piotrmurach/tty-reader
17
17
 
@@ -19,13 +19,23 @@
19
19
 
20
20
  **TTY::Reader** provides independent reader component for [TTY](https://github.com/piotrmurach/tty) toolkit.
21
21
 
22
+ ## Compatibility
23
+
24
+ The `tty-reader` is not compatible with the GNU Readline and doesn't aim to be. It originated from [tty-prompt](https://github.com/piotrmurach/tty-prompt) project to provide flexibility, independence from underlying operating system and Ruby like API interface for creating different prompts.
25
+
26
+ `TTY::Reader` forges its own path to provide features necessary for building line editing in terminal applications!
27
+
22
28
  ## Features
23
29
 
24
- * Reading single keypress
30
+ * Pure Ruby
25
31
  * Line editing
26
- * Multiline input
32
+ * Reading single keypress
33
+ * Reading multiline input
27
34
  * History management
28
- * Ability to register for key events
35
+ * Ability to register for keystroke events
36
+ * No global state
37
+ * Works on Linux, OS X, FreeBSD and Windows
38
+ * Supports Ruby versions `>= 2.0.0` & JRuby
29
39
 
30
40
  ## Installation
31
41
 
@@ -48,10 +58,16 @@ Or install it yourself as:
48
58
  * [2.1 read_keypress](#21-read_keypress)
49
59
  * [2.2 read_line](#22-read_line)
50
60
  * [2.3 read_multiline](#23-read_multiline)
51
- * [2.4 events](#24-events)
61
+ * [2.4 on](#24-on)
62
+ * [2.5 subscribe](#25-subscribe)
63
+ * [2.6 trigger](#26-trigger)
64
+ * [2.7 supported events](#27-supported-events)
52
65
  * [3. Configuration](#3-configuration)
53
66
  * [3.1 :interrupt](#31-interrupt)
54
- * [3.2 :track_history](#31-track_history)
67
+ * [3.2 :track_history](#32-track_history)
68
+ * [3.3 :history_cycle](#33-history_cycle)
69
+ * [3.4 :history_duplicates](#34-history_duplicates)
70
+ * [3.5 :history_exclude](#35-history_exclude)
55
71
 
56
72
  ## Usage
57
73
 
@@ -70,24 +86,59 @@ reader.read_char
70
86
  reader.read_keypress
71
87
  ```
72
88
 
73
- ## 2.2 read_line
89
+ ### 2.2 read_line
90
+
91
+ By default `read_line` works in `raw mode` which means it behaves like a line editor that allows you to edit each character, respond to `control characters` such as `Control-A` to `Control-B` or navigate through history.
74
92
 
75
- To read a single line terminated by new line character use `read_line` like so:
93
+ For example, to read a single line terminated by a new line character use `read_line` like so:
76
94
 
77
95
  ```ruby
78
96
  reader.read_line
79
97
  ```
80
98
 
81
- ## 2.3 read_multiline
99
+ If you wish for the keystrokes to be interpreted by the terminal instead, use so called `cooked` mode by providing the `:raw` option set to `false`:
100
+
101
+ ```ruby
102
+ reader.read_line(raw: false)
103
+ ```
104
+
105
+ Any non-interpreted characters received are written back to terminal, however you can stop this by using `:echo` option set to `false`:
106
+
107
+ ```ruby
108
+ reader.read_line(echo: false)
109
+ ```
110
+
111
+ You can also provide a line prefix displayed before input by passing it as a first aargument:
112
+
113
+ ```ruby
114
+ reader.read_line(">> ")
115
+ # >> input goes here ...
116
+ ```
117
+
118
+ ### 2.3 read_multiline
82
119
 
83
- To read more than one line terminated by `Ctrl+d` or `Ctrl+z` use `read_multiline`:
120
+ By default `read_multiline` works in `raw mode` which means it behaves like a multiline editor that allows you to edit each character, respond to `control characters` such as `Control-A` to `Control-B` or navigate through history.
121
+
122
+ For example, to read more than one line terminated by `Ctrl+d` or `Ctrl+z` use `read_multiline`:
84
123
 
85
124
  ```ruby
86
125
  reader.read_multiline
87
126
  # => [ "line1", "line2", ... ]
88
127
  ```
89
128
 
90
- ## 2.4 events
129
+ If you wish for the keystrokes to be interpreted by the terminal instead, use so called `cooked` mode by providing the `:raw` option set to `false`:
130
+
131
+ ```ruby
132
+ reader.read_line(raw: false)
133
+ ```
134
+
135
+ You can also provide a linke prefix displayed before input by passing a string as a first argument:
136
+
137
+ ```ruby
138
+ reader.read_multiline(">> ")
139
+ ```
140
+
141
+ ### 2.4 on
91
142
 
92
143
  You can register to listen on a key pressed events. This can be done by calling `on` with a event name:
93
144
 
@@ -123,25 +174,92 @@ prompt.on(:keypress) { |key| ... }
123
174
  .on(:keydown) { |key| ... }
124
175
  ```
125
176
 
126
- The available events are:
177
+ ### 2.5 subscribe
178
+
179
+ You can subscribe any object to listen for the emitted [key events](#27-supported-events) using the `subscribe` message. The listener would need to implement a method for every event it wishes to receive.
180
+
181
+ For example, if a `Context` class wishes to only listen for `keypress` event:
182
+
183
+ ```ruby
184
+ class Context
185
+ def keypress(event)
186
+ ...
187
+ end
188
+ end
189
+ ```
190
+
191
+ Then subcribing is done:
192
+
193
+ ```ruby
194
+ context = Context.new
195
+ reader.subscribe(context)
196
+ ```
197
+
198
+ ### 2.6 trigger
199
+
200
+ The signature for triggering key events is `trigger(event, args...)`. The first argument is a [key event name](#27-supported-events) followed by any number of actual values related to the event being triggered.
201
+
202
+ For example, to trigger `:keydown` event do:
203
+
204
+ ```ruby
205
+ reader.trigger(:keydown)
206
+ ```
207
+
208
+ To add vim bindings for line editing you could discern between alphanumeric inputs like so:
209
+
210
+ ```ruby
211
+ reader.on(:keypress) do |event|
212
+ if event.value == 'j'
213
+ reader.trigger(:keydown)
214
+ end
215
+ if evevnt.value == 'k'
216
+ reader.trigger(:keup)
217
+ end
218
+ end
219
+ ```
220
+
221
+ ### 2.7 supported events
222
+
223
+ The available key events for character input are:
127
224
 
128
225
  * `:keypress`
129
- * `:keydown`
130
- * `:keyup`
131
- * `:keyleft`
132
- * `:keyright`
133
- * `:keynum`
134
- * `:keytab`
135
226
  * `:keyenter`
136
227
  * `:keyreturn`
228
+ * `:keytab`
229
+ * `:keybackspace`
137
230
  * `:keyspace`
138
231
  * `:keyescape`
139
232
  * `:keydelete`
140
- * `:keybackspace`
233
+ * `:keyalpha`
234
+ * `:keynum`
235
+
236
+ The navigation relted key events are:
237
+
238
+ * `:keydown`
239
+ * `:keyup`
240
+ * `:keyleft`
241
+ * `:keyright`
242
+ * `:keyhome`
243
+ * `:keyend`
244
+ * `:keyclear`
245
+
246
+ The specific `ctrl` key events:
247
+
248
+ * `:keyctrl_a`
249
+ * `:keyctrl_b`
250
+ * ...
251
+ * `:keyctrl_z`
252
+
253
+ The key events for functional keys `f*` are:
254
+
255
+ * `:keyf1`
256
+ * `:keyf2`
257
+ * ...
258
+ * `:keyf24`
141
259
 
142
260
  ## 3. Configuration
143
261
 
144
- ### 3.1. :interrupt
262
+ ### 3.1. `:interrupt`
145
263
 
146
264
  By default `InputInterrupt` error will be raised when the user hits the interrupt key(Control-C). However, you can customise this behaviour by passing the `:interrupt` option. The available options are:
147
265
 
@@ -156,7 +274,7 @@ For example, to send interrupt signal do:
156
274
  reader = TTY::Reader.new(interrupt: :signal)
157
275
  ```
158
276
 
159
- ### 3.2. :track_history
277
+ ### 3.2. `:track_history`
160
278
 
161
279
  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:
162
280
 
@@ -164,15 +282,46 @@ The `read_line` and `read_multiline` provide history buffer that tracks all the
164
282
  reader = TTY::Reader.new(track_history: false)
165
283
  ```
166
284
 
285
+ ### 3.3. `:history_cycle`
286
+
287
+ This option determines whether the history buffer allows for infinite navigation. By default it is set to `false`. You can change this:
288
+
289
+ ```ruby
290
+ reader = TTY::Reader.new(history_cycle: true)
291
+ ```
292
+
293
+ ### 3.4. `:history_duplicates`
294
+
295
+ This option controls whether duplicate lines are stored in history. By default set to `true`. You can change this:
296
+
297
+ ```ruby
298
+ reader = TTY::Reader.new(history_duplicates: false)
299
+ ```
300
+
301
+ ### 3.5. `:history_exclude`
302
+
303
+ 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:
304
+
305
+ ```ruby
306
+ reader = TTY::Reader.new(history_exclude: ->(line) { ... })
307
+ ```
308
+
167
309
  ## Development
168
310
 
169
311
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
170
312
 
171
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
172
-
173
313
  ## Contributing
174
314
 
175
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/tty-reader. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
315
+ Bug reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/tty-reader. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
316
+
317
+ 1. Clone the project on GitHub
318
+ 2. Create a feature branch
319
+ 3. Submit a Pull Request
320
+
321
+ Important notes:
322
+ - **All new features must include test coverage.** At a bare minimum, unit tests are required. It is preferred if you include acceptance tests as well.
323
+ - **The tests must be be idempotent.** Any test run should produce the same result when run over and over.
324
+ - **All new features must include source code & readme documentation** Any new method you add should include yarddoc style documentation with clearly specified parameter and return types.
176
325
 
177
326
  ## License
178
327
 
@@ -180,8 +329,8 @@ The gem is available as open source under the terms of the [MIT License](http://
180
329
 
181
330
  ## Code of Conduct
182
331
 
183
- Everyone interacting in the Tty::Reader project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/piotrmurach/tty-reader/blob/master/CODE_OF_CONDUCT.md).
332
+ Everyone interacting in the TTY::Reader project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/piotrmurach/tty-reader/blob/master/CODE_OF_CONDUCT.md).
184
333
 
185
334
  ## Copyright
186
335
 
187
- Copyright (c) 2017 Piotr Murach. See LICENSE for further details.
336
+ Copyright (c) 2017-2018 Piotr Murach. See LICENSE for further details.
data/appveyor.yml CHANGED
@@ -9,7 +9,6 @@ test_script:
9
9
  - bundle exec rake ci
10
10
  environment:
11
11
  matrix:
12
- - ruby_version: "193"
13
12
  - ruby_version: "200"
14
13
  - ruby_version: "200-x64"
15
14
  - ruby_version: "21"
@@ -20,6 +19,3 @@ environment:
20
19
  - ruby_version: "23-x64"
21
20
  - ruby_version: "24"
22
21
  - ruby_version: "24-x64"
23
- matrix:
24
- allow_failures:
25
- - ruby_version: "193"
@@ -0,0 +1,34 @@
1
+ require 'benchmark/ips'
2
+ require 'tty-reader'
3
+
4
+ input = StringIO.new("a")
5
+ output = StringIO.new
6
+ $stdin = input
7
+ reader = TTY::Reader.new(input, output)
8
+
9
+ Benchmark.ips do |x|
10
+ x.report('getc') do
11
+ input.rewind
12
+ $stdin.getc
13
+ end
14
+
15
+ x.report('read_char') do
16
+ input.rewind
17
+ reader.read_char
18
+ end
19
+
20
+ x.compare!
21
+ end
22
+
23
+ # v0.1.0
24
+ #
25
+ # Calculating -------------------------------------
26
+ # getc 52462 i/100ms
27
+ # read_char 751 i/100ms
28
+ # -------------------------------------------------
29
+ # getc 2484819.4 (±4.1%) i/s - 12433494 in 5.013438s
30
+ # read_char 7736.4 (±2.9%) i/s - 39052 in 5.052628s
31
+ #
32
+ # Comparison:
33
+ # getc: 2484819.4 i/s
34
+ # read_char: 7736.4 i/s - 321.19x slower
@@ -0,0 +1,34 @@
1
+ require 'benchmark/ips'
2
+ require 'tty-reader'
3
+
4
+ input = StringIO.new("abc\n")
5
+ output = StringIO.new
6
+ $stdin = input
7
+ reader = TTY::Reader.new(input, output)
8
+
9
+ Benchmark.ips do |x|
10
+ x.report('gets') do
11
+ input.rewind
12
+ $stdin.gets
13
+ end
14
+
15
+ x.report('read_line') do
16
+ input.rewind
17
+ reader.read_line
18
+ end
19
+
20
+ x.compare!
21
+ end
22
+
23
+ # v0.1.0
24
+ #
25
+ # Calculating -------------------------------------
26
+ # gets 51729 i/100ms
27
+ # read_line 164 i/100ms
28
+ # -------------------------------------------------
29
+ # gets 1955255.2 (±3.7%) i/s - 9776781 in 5.008004s
30
+ # read_line 1215.1 (±33.1%) i/s - 5248 in 5.066569s
31
+ #
32
+ # Comparison:
33
+ # gets: 1955255.2 i/s
34
+ # read_line: 1215.1 i/s - 1609.19x slower