You Can Read Input by Character or Line.
TTY::Reader
A pure Crimson library that provides a set of methods for processing keyboard input in character, line and multiline modes. Information technology 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.
TTY::Reader provides independent reader component for TTY toolkit.
Compatibility
The tty-reader is non compatible with the GNU Readline and doesn't aim to be. It originated from tty-prompt projection to provide flexibility, independence from underlying operating organisation and Ruby-red like API interface for creating different prompts.
TTY::Reader forges its ain path to provide features necessary for building line editing in terminal applications!
Features
- Pure Red
- Reading single keypress
- Line editing
- Reading multiline input
- Power to register for keystroke events
- Track input history
- No global land
- Works on Linux, Os X, FreeBSD and Windows
- Supports Ruby versions
>= two.0.0& JRuby
Installation
Add this line to your application's Gemfile:
And then execute:
Or install it yourself every bit:
- 1. Usage
- ii. API
- two.1 read_keypress
- two.2 read_line
- two.iii read_multiline
- two.4 on
- 2.5 subscribe
- ii.6 unsubscribe
- ii.seven trigger
- 2.8 supported events
- three. Configuration
- three.1 :interrupt
- 3.2 :track_history
- 3.3 :history_cycle
- 3.four :history_duplicates
- three.v :history_exclude
- 3.6 :history_size
Usage
In but a few lines you tin recreate IRB prompt.
Initialize the reader:
Then register to listen for key events, in this case listen for Ctrl-X or Esc keys to exit:
reader . on ( :keyctrl_x , :keyescape ) practise puts "Exiting..." get out end Finally, go along asking user for line input with a => equally a prompt:
loop practice reader . read_line ( "=> " ) end API
2.1 read_keypress
To read a single key stroke from the user use read_char or read_keypress:
reader . read_char reader . read_keypress reader . read_keypress ( nonblock: true ) 2.2 read_line
By default read_line works in raw mode which means it behaves similar a line editor that allows you to edit each grapheme, respond to command characters such as Command-A to Control-B or navigate through history.
For instance, to read a single line terminated by a new line graphic symbol use read_line similar so:
If you wish for the keystrokes to exist interpreted by the terminal instead, use so chosen cooked way by providing the :raw option set to simulated:
reader . read_line ( raw: imitation ) Any not-interpreted characters received are written back to terminal, yet you tin can stop this by using :echo option set to false:
reader . read_line ( echo: false ) Y'all can too provide a line prefix displayed earlier input by passing information technology as a first argument:
reader . read_line ( ">> " ) # >> To pre-populate the line content for editing use :value option:
reader . read_line ( "> " , value: "edit me" ) # > edit me 2.three read_multiline
By default read_multiline works in raw mode which means it behaves like a multiline editor that allows you to edit each character, reply to control characters such as Control-A to Command-B or navigate through history.
For example, to read more one line terminated by Ctrl+d or Ctrl+z utilise read_multiline:
reader . read_multiline # => [ "line1", "line2", ... ] If you wish for the keystrokes to be interpreted past the final instead, use so called cooked mode by providing the :raw option set up to false:
reader . read_line ( raw: false ) You can also provide a line prefix displayed before input by passing a string every bit a first argument:
reader . read_multiline ( ">> " ) 2.4 on
You can register to heed on a key pressed events. This can be washed past calling on with a consequence name(s):
reader . on ( :keypress ) { |event| .... } or listen for multiple events:
reader . on ( :keyctrl_x , :keyescape ) { |consequence| ... } The KeyEvent object is yielded to a block whenever a particular key issue fires. The event responds to:
-
fundamental- key pressed -
value- value of the key pressed -
line- the content of the currently edited line, empty otherwise
The value returns the actual key pressed and the line the content for the currently edited line or is empty.
The key is an object that responds to following messages:
-
proper name- the name of the event such equally :upwards, :down, letter of the alphabet or digit -
meta- true if outcome is not-standard key associated -
shift- truthful if shift has been pressed with the key -
ctrl- true if ctrl has been pressed with the key
For example, to add mind to vim like navigation keys, one would practice the following:
reader . on ( :keypress ) do |event| if upshot . value == "j" ... terminate if event . value == "k" ... end end You tin can subscribe to more one issue:
reader . on ( :keypress ) { |issue| ... } . on ( :keydown ) { |event| ... } 2.five subscribe
Y'all can subscribe any object to heed for the emitted key events using the subscribe message. The listener would need to implement a method for every event it wishes to receive.
For case, if a MyListener class wishes to only listen for keypress result:
class MyListener def keypress ( event ) ... end cease And so subscribing is done:
reader . subscribe ( MyListener . new ) Alternatively, subscribe allows yous to heed to events but for the duration of block execution like then:
reader . subscribe ( MyListener ) do ... end ii.6 unsubscribe
You lot can unsubscribe any object from listening to the key events using the unsubscribe message:
reader . unsubscribe ( my_listener ) two.seven trigger
The signature for triggering primal events is trigger(event, args...). The offset argument is a cardinal event name followed past any number of bodily values related to the event being triggered.
For example, to trigger :keydown event practice:
To add vim bindings for line editing yous could discern betwixt alphanumeric inputs like and so:
reader . on ( :keypress ) practise |event| if event . value == "j" reader . trigger ( :keydown ) end if evevnt . value == "thou" reader . trigger ( :keyup ) end end 2.8 supported events
The available primal events for character input are:
-
:keypress -
:keyenter -
:keyreturn -
:keytab -
:keybackspace -
:keyspace -
:keyescape -
:keydelete -
:keyalpha -
:keynum
The navigation related key events are:
-
:keydown -
:keyup -
:keyleft -
:keyright -
:keyhome -
:keyend -
:keyclear
The specific ctrl key events:
-
:keyctrl_a -
:keyctrl_b - ...
-
:keyctrl_z
The central events for functional keys f* are:
-
:keyf1 -
:keyf2 - ...
-
:keyf24
3. Configuration
iii.1. :interrupt
By default InputInterrupt error will exist raised when the user hits the interrupt key(Control-C). Still, you can customise this behaviour past passing the :interrupt option. The bachelor options are:
-
:signal- sends interrupt signal -
:get out- exists with status code -
:noop- skips handler - custom proc
For example, to send interrupt indicate do:
reader = TTY::Reader . new ( interrupt: :signal ) 3.2. :track_history
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 adjacent lines when user presses up/down arrows respectively. However, if yous wish to disable this behaviour use :track_history option like so:
reader = TTY::Reader . new ( track_history: false ) 3.3. :history_cycle
This option determines whether the history buffer allows for space navigation. By default information technology is fix to faux. You can modify this:
reader = TTY::Reader . new ( history_cycle: true ) iii.4. :history_duplicates
This option controls whether duplicate lines are stored in history. By default set up to simulated. Yous can change this:
reader = TTY::Reader . new ( history_duplicates: truthful ) 3.5. :history_exclude
This option allows you lot to exclude lines from existence stored in history. It accepts a Proc with a line as a first argument. By default it is fix to exclude empty lines. To change this:
reader = TTY::Reader . new ( history_exclude: -> ( line ) { ... } ) 3.6. :history_size
By default, the history buffer can store upwards to 512 lines. This tin be changed with the :history_size configuration:
reader = TTY::Reader . new ( history_size: 2048 ) Evolution
After checking out the repo, run bin/setup to install dependencies. And then, run rake spec to run the tests. You tin can too run bin/console for an interactive prompt that will let you to experiment.
Contributing
Problems reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/tty-reader. This project is intended to exist a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
- Clone the projection on GitHub
- Create a feature branch
- Submit a Pull Asking
Important notes:
- All new features must include examination coverage. At a bare minimum, unit tests are required. It is preferred if you include acceptance tests as well.
- The tests must be be idempotent. Any test run should produce the same result when run over and over.
- All new features must include source lawmaking & readme documentation Any new method you lot add should include yarddoc style documentation with clearly specified parameter and return types.
License
The jewel is available equally open source nether the terms of the MIT License.
Lawmaking of Conduct
Anybody interacting in the TTY::Reader project's codebases, event trackers, chat rooms and mailing lists is expected to follow the lawmaking of conduct.
Copyright
Copyright (c) 2017 Piotr Murach. See LICENSE for further details.
Source: https://github.com/piotrmurach/tty-reader
Post a Comment for "You Can Read Input by Character or Line."