Crate liso

source ·
Expand description

Liso (LEE-soh) is an acronym for Line Input with Simultaneous Output. It is a library for a particular kind of text-based Rust application; one where the user is expected to give command input at a prompt, but output can occur at any time. It provides simple line editing, and prevents input from clashing with output. It can be used asynchronously (with tokio) or synchronously (without).

§Usage

Create an InputOutput object with InputOutput::new(). Liso will automatically configure itself based on how your program is being used.

Your InputOutput instance can be used to send output or receive input. Call clone_output to create an OutputOnly instance, which can only be used to send output. You can call clone_output as many times as you like, as well as cloning the OutputOnlys directly. An unlimited number of threads or tasks can send output through Liso, but only one thread/task can receive user input: whichever one currently holds the InputOutput instance.

If the global feature is enabled, which it is by default, then you don’t have to create OutputOnly instances and keep them around in order to send output. See the “Global” section for more information.

Liso can work with Strings and &strs directly. If you want to add style or color, create a Line, either manually or using the convenient liso! macro. Send output to the user by calling println() or wrapln(), whichever you prefer. Any styling and color information is reset after the line is output, so you don’t have to worry about dangling attributes.

Liso supports a prompt line, which is presented ahead of the user input. Use prompt() to set it. Styling and color information is not reset between the prompt and the current input text, so you can style/color the input text by having the desired styles/colors active at the end of the prompt line.

Liso supports an optional status line, which “hangs out” above the input text. Use status() to set it. Printed text appears above the status line, the prompt and any in-progress input appears below it. Use this to present contextual or frequently-changing information.

Liso supports “notices”, temporary messages that appear in place of the prompt and input for a limited time. Use notice() to display one. The notice will disappear when the allotted time elapses, when the user presses any key, or when another notice is displayed, whichever happens first. You should only use this in direct response to user input; in fact, the only legitimate use may be to complain about an unknown control character. (See Response for an example of this use.)

§Global

If the global feature is enabled (which it is by default), you can call output() to get a valid OutputOnly instance any time that an InputOutput instance is alive. This will panic if there is not an InputOutput instance alive, so you’ll still have to have one.

With global enabled, you can also use the println! or wrapln! macros to perform output directly and conveniently. println!(...) is equivalent to output().println!(liso!(...)).

Using the output() function, or the println!/wrapln! macros, is noticeably less efficient than creating an OutputOnly instance ahead of time, whether by calling clone_output() or by calling output() and caching the result. But, it’s probably okay as long as you’re not hoping to do it hundreds of thousands of times per second.

§History

If the history feature is enabled (which it is by default), Liso supports a rudimentary command history. It provides a conservative default that isn’t backed by any file. Try:

io.swap_history(liso::History::from_file(some_path).unwrap());

to make it backed by a file, and see History for more information.

§Completion

If the completion feature is enabled (which it is by default), Liso supports tab completion. Implement Completor, then use set_completor to make your new completor active. See the linked documentation for more information.

§Pipe mode

If either stdin or stdout is not a tty, or the TERM environment variable is set to either dumb or pipe, Liso enters “pipe mode”. In this mode, status lines, notices, and prompts are not outputted, style information is discarded, and every line of input is passed directly to your program without any processing of control characters or escape sequences. This means that a program using Liso will behave nicely when used in a pipeline, or with a relatively unsophisticated terminal.

TERM=dumb is respected out of backwards compatibility with old UNIXes and real terminals that identify this way. TERM=pipe is present as an alternative for those who would rather not perpetuate an ableist slur, but is not compatible with other UNIX utilities and conventions. On UNIX. you can activate “pipe mode” without running afoul of any of this by piping the output of the Liso-enabled program to cat, as in my_liso_program | cat.

Macros§

  • Constructs a Line from pieces. More convenient than creating a Line and calling its methods.
  • Add some pieces to a Line. More convenient than calling its methods.
  • If the global feature is enabled (which it is by default), you can use println!(...) as convenient shorthand for output().println(liso!(...)). This is less efficient than creating an OutputOnly with clone_output() and keeping it around, but it is more convenient. You will have to explicitly use liso::println;, or call it by its full path (liso::println!) or Rust may be uncertain whether you meant to use this or std::println!. Panics if there is no InputOutput instance alive.
  • If the global and wrap features are enabled (which they are by default), you can use wrapln!(...) as convenient shorthand for output().println(liso!(...)). This is less efficient than creating an OutputOnly with clone_output() and keeping it around, but it is more convenient. Panics if there is no InputOutput instance alive.

Structs§

  • This keeps track of the most recent command lines entered.
  • Receives input from, and sends output to, the terminal. You can send output from any number of threads (see Output::clone_output), but only one thread at a time may have ownership of the overlying InputOutput type and therefore the ability to receive input.
  • This is a line of text, with optional styling information, ready for display. The liso! macro is extremely convenient for building these. You can also pass a String, &str, or Cow<str> to most Liso functions that accept a Line.
  • A single character from a Line, along with the byte index it begins at, and the Style and Colors it would be displayed with. This is yielded by LineCharIterator, which is returned by Line::chars().
  • Allows you to iterate over the characters in a Line, one at a time, along with their Style and Color information. This is returned by Line::chars().
  • This struct contains all the methods that the OutputOnly and InputOutput structs have in common. Any method of this struct may be called on either of the other structs.
  • Sends output to the terminal. You can have more than one of these, shared freely among threads and tasks. Give one to every thread, task, or object that needs to produce output.
  • Styles we support outputting.

Enums§

  • Colors we support outputting. For compatibility, we only support the 3-bit ANSI colors.
  • Input received from the user, or a special condition. Returned by any of the following InputOutput methods:

Traits§

  • Something that may know how to respond to a completion request, i.e. a tab press.

Functions§

  • If the global feature is enabled (which it is by default), and there is an InputOutput alive somewhere, you can call output() to get an OutputOnly struct that you can use to perform output on it. This is less efficient than creating an OutputOnly directly with clone_output() and keeping it around, but it is more convenient.