Skip to content Skip to sidebar Skip to footer

You Can Read Input by Character or Line.

TTY Toolkit logo

TTY::Reader Gitter

Gem Version Actions CI Build status Maintainability Coverage Status Inline docs

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.

  1. Clone the projection on GitHub
  2. Create a feature branch
  3. 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.

grayagerce.blogspot.com

Source: https://github.com/piotrmurach/tty-reader

Post a Comment for "You Can Read Input by Character or Line."