Giter VIP home page Giter VIP logo

liner's People

Contributors

cmdln avatar dcampbell24 avatar gsquire avatar iamcodemaker avatar ids1024 avatar jackpot51 avatar mmstick avatar movingtomars avatar msehnout avatar mssun avatar pengowen123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

liner's Issues

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.

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.

Change how events are passed to the user of liner?

Right now, we pass closures to the Context/Editor to process Events.

Would something like this be better?

pub trait EventHandler {
    fn handle_before_key_press(&mut self, key: Key) {}
    fn handle_after_key_press(&mut self, key: Key) {}
    ...
}

Bytes Iterator for Buffer

If you wouldn't mind, I'd like to see a bytes() iterator for the Buffer structure. Perhaps even a to_string() and as_bytes() method too. Basically, when writing data to an output, it needs to be in a raw &[u8] format.

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?

"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

incorrect cursor handling at the end of lines

liner doesn't move the cursor to the next line when the end of a line is reached. Instead it stays on the current line for an extra character, then moves to the second character of the next line. This can be seen while typing at the end of a line, or while moving character by character across line boundaries with the arrow keys.

Removing indentation w\ specific keywords

It would be nice if liner could automatically unindent by a specified number of characters when specific keywords are found, such as else and end, in order to replicate the nice feature found in Fish.

kill by path-fragment

in fish, ctrl+w doesn't kill the entire word (string of non-whitespace), it kills up to the closest slash. requesting this feature.

Event handling causing odd display issues

I have this

pub fn read_enumerated(message: &str, choices: &[&str], default_idx: usize) -> Result<String> {
    let mut ctx = Context::new();
    let mut idx: usize = default_idx;
    let buff = choices[idx].to_owned();
    let hints: HashMap<char, usize> = choices.iter()
        .enumerate()
        .map(|(idx, choice)| (choice.chars().next().unwrap(), idx))
        .into_iter()
        .collect();
    ctx.read_line_with_init_buffer(format!("{} (TAB or arrows to select {:?}): ",
                                            message,
                                            choices),
                                    &mut |Event { editor, kind }| {
            if let EventKind::AfterKey(key) = kind {
                match key {
                    // hitting enter should still work as expected
                    Key::Char('\n') => return,
                    // change to the next choice, wrap around to the 1st choice
                    Key::Left | Key::Down | Key::Char('\t') => {
                        idx = if idx == 0 { choices.len() - 1 } else { idx - 1 }
                    }
                    // change to the previous choice, wrap around to the last choice
                    Key::Right | Key::Up => {
                        idx = if idx + 1 == choices.len() { 0 } else { idx + 1 }
                    }
                    // change to the choice matching the initial char
                    Key::Char(key) => {
                        if hints.contains_key(&key) {
                            idx = hints[&key];
                        }
                    }
                    // anything other than tab, arrows or hints should do nothing
                    _ => {},
                }
                let new_choice: Vec<char> = choices[idx].chars().collect();
                editor.move_cursor_to_end_of_line().unwrap();
                editor.delete_all_before_cursor().unwrap();
                editor.insert_chars_after_cursor(&new_choice).unwrap();
            }
        },
                                    buff)?;
    Ok(choices[idx].to_owned())
}

When I use it with 0.4.1, though, instead of re-drawing the line in place, is like some extraneous new lines are being introduced. I am trying to track this down, if I can figure it out, I will submit a PR. I thought you might have an idea or at least be able to reproduce using my code.

Name change

Because there's a Go library also named liner, I feel that this library should have a name change.

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.

access previous argument

in bash, <Esc>., and <Alt>. insert the last argument of the previous command; multiple presses go further into the history. requesting this feature.

Configurable Auto-completion Methods

I've been asked if we could implement the ability to customize tab auto-completions to not just complete an entire command all at once when tabbed, but to also allow completing by words, one word per tab.

Multi-word completions

I've a question regarding the usage of liner within the Ion shell.

I've wired the context history to the completer here, but tab completions won't function after the first word is typed. Is there a way to go about having the completer work with multiple words typed in the terminal?

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

Make keybindings remappable

Right now, the keybindings are hardcoded in. They should be remappable. This should be sorted out at the same time as #6 ideally.

Password mode

I would like to use liner to capture usernames, followed by passwords. Currently the change required would be to not echo characters as they are received, or perhaps to use a mask char.

A mask char may be easier to implement, as it would not invalidate any of the editing interfaces

Tilde expansion

Something else I've noticed with completions in the Ion shell is that if your attempt to cd to a directory starting with the ~ character. Is there a way tto either supply the expanded form to liner or have liner expand it?

Support colour

Could be nice for things like Ion syntax highlighting.

Would need some changes to Buffer.

OOM Error w/ History File

Something's running out of control and causing serious issues ( https://github.com/redox-os/ion/issues/415 ) when the history file is somewhat large (~1000 lines). Might possibly be an issue in the recent history file commit that wasn't detected by the tests? I'm not sure yet. History file continually gets larger and larger until an OOM error occurs.

I will be investigating this.

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" }

distinct completions for dir and dir/

if i implicit cd to both ~/dir and ~/dir/, when i press ~/di<Tab> i see both of those completions presented; i would expect ~/dir/ to be completed automatically.

edit: this is in ion shell

Backslash handling

read_line never exits when the last char on the line is a backslash. It would be useful to at least be able to overwrite the handle_newline, or better even, to be able to specify when to end a line.

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.

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`

"Contributing" page

It'd be nice to have some "contributing" page with TODO list or something similar.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.