A readline-like library in Rust.

Related tags

Command-line liner
Overview

liner

A Rust library offering readline-like functionality.

CONTRIBUTING.md

crates.io Build Status Docs

Featues

  • Autosuggestions
  • Emacs and Vi keybindings
  • Multi-line editing
  • History
  • (Incomplete) basic and filename completions
  • Reverse search
  • Remappable keybindings

Basic Usage

In Cargo.toml:

[dependencies]
liner = "0.4.3"
...

In src/main.rs:

extern crate liner;

use liner::Context;

fn main() {
    let mut con = Context::new();

    loop {
        let res = con.read_line("[prompt]$ ", &mut |_| {}).unwrap();

        if res.is_empty() {
            break;
        }

        con.history.push(res.into());
    }
}

See src/main.rs for a more sophisticated example.

License

MIT licensed. See the LICENSE file.

Comments
  • fish-like autosuggestions

    fish-like autosuggestions

    Fish has this nice feature of suggesting commands from history without pressing Ctrl+R every time: https://fishshell.com/docs/current/tutorial.html#tut_autosuggestions

    Would you like to have something like this implemented in liner?

    enhancement 
    opened by msehnout 13
  • Fix an issue when terminal size is zero

    Fix an issue when terminal size is zero

    When terminal size is zero (w = 0), the code will crash.

     thread 'main' panicked at 'attempt to calculate the remainder with a divisor of zero'
    

    Following code will use w for calculation with a divisor of w which is zero.

    • https://github.com/MovingtoMars/liner/blob/master/src/editor.rs#L637
    • https://github.com/MovingtoMars/liner/blob/master/src/editor.rs#L687
    opened by mssun 7
  • support undo/redo with truncate

    support undo/redo with truncate

    Prior to this patch, typing some text, moving to the start of the line, then deleting until the end of the line and attempting to undo will cause a panic. This is because the truncate() operation did not update the undo list. This has been corrected.

    opened by iamcodemaker 7
  • persistent history storage

    persistent history storage

    There is currently no way to store a history and load it from a file.

    possible sources of inspiration: ion from redox readline written in Go

    If this is a desired feature in this project, I will work on it.

    opened by msehnout 7
  • Initial buffer

    Initial buffer

    I have a cli I am writing that saves some data to file based on an initial run. Re-running loads that file, it would be nice to present the saved values for editing. Other than re-implementing some internal functions of Context, I cannot see a way to do this really. If I could pass my own buffer into an additional read_line method, that would very nicely do it. I'll see if I can come up with a quick PR that demonstrates what I mean.

    opened by cmdln 5
  • v0.4.4: compilation warning

    v0.4.4: compilation warning

    Using rustc 1.37.0 (eae3437df 2019-08-13), compiling liner v0.4.4 leads to this message:

    warning[E0503]: cannot use `self.key_bindings` because it was mutably borrowed
      --> /home/ngirard/.cargo/registry/src/github.com-1ecc6299db9ec823/liner-0.4.4/src/context.rs:98:17
       |
    96 |             let ed = try!(Editor::new_with_init_buffer(stdout, prompt, self, buffer));
       |                                                                        ---- borrow of `*self` occurs here
    97 |             match self.key_bindings {
    98 |                 KeyBindings::Emacs => Self::handle_keys(keymap::Emacs::new(ed), handler),
       |                 ^^^^^^^^^^^^^^^^^^ use of borrowed `*self`
    99 |                 KeyBindings::Vi => Self::handle_keys(keymap::Vi::new(ed), handler),
       |                                                                      -- borrow later used here
       |
       = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
       = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
       = note: for more information, try `rustc --explain E0729`
    
    
    opened by ngirard 4
  • "Ctrl+["=Leave insert mode in vi

    I came from the redox-os project which uses liner in ion, and I tried to run set -o vi and found this. Im working on this thing, I forked it and I think I fixed it: :crossed_fingers: . You probably should check my work because I have no idea how this project works.

    My fork is here: https://github.com/liamnaddell/liner

    Should I pr?

    I also "added" two more tests that use ctrl+[ instead of Esc

    opened by liamnaddell 4
  • Issue with larger commands

    Issue with larger commands

    I've noticed for a while now that liner has a bug where if a command exceeds a certain number of characters, it begins shifting the current line upwards by one line each time a key is entered until it is at the top of the terminal.

    opened by mmstick 4
  • Editor clears ALL text after it, not just the current line

    Editor clears ALL text after it, not just the current line

    This is not good for my use case, where I need to have an editor alongside some static text. (E.g. for editing a field)

    Could this be changed to clear::CurrentLine or clear::UntilNewline?

    If so, I'll open a PR.

    opened by anirudhb 3
  • Wraparound when exceeding history (max_file_size) does not work as expected

    Wraparound when exceeding history (max_file_size) does not work as expected

    Maybe this is meant this way, but if the history-file has exactly max_file_size lines and another is pushed, the file is cleared completely and the newly pushed is its only entry. The in memory-history works as expected (drops the oldest, but keeps the rest).

    How to reproduce (quick and dirty):

    $ touch test
    $ for x in $(seq 1000); do echo $x >> test; done
    $ cat test
    

    This gives 1000 entries.

    Compile and run:

    extern crate liner;
    use liner::Context;
    
    fn main() {
        let mut con = Context::new();
        con.history.set_file_name(Some("test".to_string()));
        con.history.load_history();
        let command = "blabla";
        con.history.push(command.into());
        con.history.commit_history();
    }
    

    and then

    $ cat test
    

    again. Result only "blabla" will be in the history-file.

    bug 
    opened by zwieberl 3
  • Multiline Editing

    Multiline Editing

    So I currently have a limited form of multiline comments / commands in the Ion shell which works great for scripts, but for the REPL there is no means of going back and editing previous lines that have been entered, but not yet submitted for completion. Does liner currently support this feature in some way?

    enhancement 
    opened by mmstick 3
  • ability to not process keys

    ability to not process keys

    deny processing of inputs by boolean result, basically:

    use liner::{Event, Context};
    use termion::event::Key;
    
    fn main() {
        let mut line = Context::new();
    
        line.read_line("$ ", &mut |Event {editor, kind}| -> bool {
            match kind {
                EventKind::BeforeKey(Key::Char(c)) => !c.is_whitespace(),
                _ => true
            }
        });
    }
    

    output:

    ./target/release/liner-test
    $ 
    # <SPACE> <SPACE> <SPACE> <SPACE>
    $ 
    # <SPACE> <SPACE> <SPACE> a <SPACE> b <SPACE> c <SPACE>
    $ abc
    

    i accomplished this currently, and terribly with Editor::undo.

    opened by ghost 1
  • Redirection of stdin results in panic on unrwrap()

    Redirection of stdin results in panic on unrwrap()

    For example echo foo | ./target/debug/liner_test gives:

    thread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 25, kind: Other, message: "Inappropriate ioctl for device" }', libcore/result.rs:916:5

    The problematic unwrap is at src/context.rs:95, which calls let stdout = stdout().into_raw_mode().unwrap();

    This issue also causes redox-os/ion to panic with a redirected stdin. See also: https://github.com/ticki/termion/issues/39

    opened by OdysseusGE 1
  • Add windows support

    Add windows support

    I'm assuming that the main reason that there currently is no windows support for liner is that the termion dependency has no windows support either.

    However, there is an open issue here to add that functionality. Once that is merged, It would be great if windows support could be added here as well.

    I have a liner fork here that uses a termion fork in order to add this support. I haven't turned it into a PR because I think some more work may be necessary. For example, it seems to work fine on the windows CMD shell, but starting my application using the git Bash shell results in an infinite list of:

    [Err] Error { repr: Custom(Custom { kind: Other, error: StringError("Unable to get the terminal size.") }) }
    

    However, it can easily be tested in a project using liner by using my github fork as a dependency:

    liner = { git = "https://github.com/jjpe/liner", branch = "windows" }
    
    opened by JoeyAcc 0
Owner
Liam
Liam
A readline replacement written in Rust

A readline replacement written in Rust Basic example // Create a default reedline object to handle user input use reedline::{DefaultPrompt, Reedline,

JT 292 Jan 9, 2023
A minimal readline with multiline and async support

RustyLine Async A minimal readline with multiline and async support. Inspired by rustyline , async-readline & termion-async-input.

Zyansheep 16 Dec 15, 2022
A bit like tee, a bit like script, but all with a fake tty. Lets you remote control and watch a process

teetty teetty is a wrapper binary to execute a command in a pty while providing remote control facilities. This allows logging the stdout of a process

Armin Ronacher 259 Jan 3, 2023
Low-level Rust library for implementing terminal command line interface, like in embedded systems.

Terminal CLI Need to build an interactive command prompt, with commands, properties and with full autocomplete? This is for you. Example, output only

HashMismatch 47 Nov 25, 2022
Rust library for regular expressions using "fancy" features like look-around and backreferences

fancy-regex A Rust library for compiling and matching regular expressions. It uses a hybrid regex implementation designed to support a relatively rich

fancy-regex 302 Jan 3, 2023
A library that creates a terminal-like window with feature-packed drawing of text and easy input handling. MIRROR.

BearLibTerminal provides a pseudoterminal window with a grid of character cells and a simple yet powerful API for flexible textual output and uncompli

Tommy Ettinger 43 Oct 31, 2022
du + rust = dust. Like du but more intuitive.

Dust du + rust = dust. Like du but more intuitive. Why Because I want an easy way to see where my disk is being used. Demo Install Cargo cargo install

andy.boot 5.4k Jan 4, 2023
joshuto: ranger-like terminal file manager written in Rust.

joshuto: ranger-like terminal file manager written in Rust.

Jeff Zhao 1.1k Dec 30, 2022
An open source, programmed in rust, privacy focused tool for reading programming resources (like stackoverflow) fast, efficient and asynchronous from the terminal.

Falion An open source, programmed in rust, privacy focused tool for reading programming resources (like StackOverFlow) fast, efficient and asynchronou

Obscurely 17 Dec 20, 2022
Write Cross-platform application with React-like decralative UI framework and scalable ECS architecture all in Rust.

bevy_dioxus Dioxus Plugin for Bevy Write Cross-platform application with React-like decralative UI framework and scalable ECS architecture all in Rust

Junichi Sugiura 269 Dec 29, 2022
A blazing fast and easy to use TRPC-like server for Rust.

rspc ?? Work in progress ?? A blazing fast and easy to use TRPC-like server for Rust. Website Example You define a trpc router and attach resolvers to

Oscar Beaumont 344 Dec 31, 2022
Like Lua, but in Rust, and different

AirScript It's like Lua, but in Rust, and different. Introduction AirScript is a dynamically typed, interpreted language inspired by Lua and written i

David Delassus 5 Jun 28, 2022
Fuzzy Index for Python, written in Rust. Works like error-tolerant dict, keyed by a human input.

FuzzDex FuzzDex is a fast Python library, written in Rust. It implements an in-memory fuzzy index that works like an error-tolerant dictionary keyed b

Tomasz bla Fortuna 8 Dec 15, 2022
Safe Unix shell-like parameter expansion/variable substitution via cross-platform CLI or Rust API

Safe Unix shell-like parameter expansion/variable substitution for those who need a more powerful alternative to envsubst but don't want to resort to

Isak Wertwein 4 Oct 4, 2022
GREP like cli tool written in rust.

Show [ grep,tail,cat ] like cli tool written in rust. Only one release as of now which does very basic function,code has been refactored where other f

Siri 4 Jul 24, 2023
Rust Server Components. JSX-like syntax and async out of the box.

RSCx - Rust Server Components RSCx is a server-side HTML rendering engine library with a neat developer experience and great performance. Features: al

Antonio Pitasi 21 Sep 19, 2023
hackernews_tui is a Terminal UI to browse Hacker News with vim-like key bindings.

hackernews_tui is written in Rust with the help of Cursive TUI library. It uses HN Algolia search APIs to get Hacker News data.

Thang Pham 364 Dec 28, 2022
A CLI utility installed as "ansi" to quickly get ANSI escape sequences. Supports the most basic ones, like colors and styles as bold or italic.

'ansi' - a CLI utility to quickly get ANSI escape codes This Rust project called ansi-escape-sequences-cli provides an executable called ansi which ca

Philipp Schuster 5 Jul 28, 2022
A prolog like syntax for egg

egglog Using the egg library with a file format and semantics similar to datalog. Explanatory blog posts: https://www.philipzucker.com/egglog-checkpoi

Philip Zucker 40 Dec 1, 2022