Input line retrieval using libreadline's "Alternate Interface".


Keywords
console, readline, terminal, gui, input, rust, rust-bindings, rust-library
License
CNRI-Python-GPL-Compatible

Documentation

pipeline coverage crates.io Docs rustc

rline

rline is a crate providing a convenient wrapper around libreadline's "Alternate Interface". It provides the goodness of libreadline (its ubiquity, powerful support for inputting text, as well as configurability) while leaving the actual character input in the hands of a user (or developer).

This can be a powerful tool for terminal based (but not necessarily command line based) applications that want to handle input on their own terms and only harness libreadline for a subset of their text input needs. But even graphical applications, which typically are not using file stream based input (or a terminal for that matter) at all, are enabled to use libreadline for providing an input experience as usually only known on the command line.

Usage

Integration of the crate into an application or library generally contains the following parts:

// Create a "context" for interacting with libreadline. Contexts are
// isolated from each other, such that you can keep input state and
// history around on a per-object basis (for example, per text input
// field).
let mut rl = rline::Readline::new();

// ...

// Feed data to libreadline and check what the result is. Globally
// configured settings (e.g., via /etc/inputrc) are honored. The result
// is either a completed line or `None`, if editing is still in
// progress.
if let Some(line) = rl.feed(&raw_input) {
  // We got a completed line. Work with to it.
  my_process(&line);
} else {
  // Editing is still in progress. Depending on the use-case we may want
  // to look at the current line input so far as well as the cursor
  // position, for example, to update the screen accordingly.
  rl.peek(|line_so_far, cursor| {
    my_display(&line_so_far, cursor)
  });
};

// ...

// If the user supplied text out-of-band, e.g., by pasting it via a
// cursor based input device, the libreadline state can be adjusted
// accordingly:
let new_line = CStr::from_bytes_with_nul(b"copied-and-pasted\0").unwrap();
let new_cursor = 6;
let clear_undo = true;
rl.reset(new_line, new_cursor, clear_undo);

Please note that rline requires libreadline to be available on the system. It does not support alternative line-editing implementations such as libedit.

Examples

A ready-to-compile example showing the usage of the crate to get line-editing support for a command line based applications is available.

The notnow program is (optionally) using the rline crate for the input of text in its terminal based UI. Another example integration can be found there.