tty-reader 0.1.0 → 0.2.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
  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