rustyline icon indicating copy to clipboard operation
rustyline copied to clipboard

Clap integration

Open SoniEx2 opened this issue 3 years ago • 9 comments

This may be a bad suggestion but would it be possible to have built-in clap integration?

Tools like sftp, gdb, etc provide their own shell-like interface, usually built around readline. Something like rustyline+clap could provide an integrated solution for it.

SoniEx2 avatar Nov 04 '21 00:11 SoniEx2

Tools parse their command line arguments with getopt-like library A and may, if interactive mode is activated, read others command with readline-like library B. But I don't see why A and B should be related !

gwenn avatar Nov 04 '21 18:11 gwenn

Well if there were something like brigadier for Rust, it'd be really convenient to use that for readline-like command parsing. Because it's declarative: you give it the commands, and it figures out autocompletion and stuff on its own. That's the main thing here really.

Arguably using clap subcommands to build a readline-like interface is a bit of a hackjob, but, again it's not like there's a "brigadier for Rust" one could use instead. So, tradeoffs.

SoniEx2 avatar Nov 04 '21 18:11 SoniEx2

I don't see in brigadier sources any interaction with stdin !

gwenn avatar Nov 04 '21 18:11 gwenn

Well yes brigadier isn't meant for use with stdin. It's a generic command parser mostly for Minecraft, so it has to not care about the input frontend.

SoniEx2 avatar Nov 04 '21 18:11 SoniEx2

There seems to be a crate that has tried this: https://crates.io/crates/slaps, though it is using old methods.

Techno-Fox avatar Jan 11 '23 19:01 Techno-Fox

All in all clap integration would be great for adding subcommands, and arguments for those subcommands in a nice and manageable manner.

Techno-Fox avatar Jan 11 '23 19:01 Techno-Fox

I agree that clap integration would be really useful. Parsing input lines is simple enough, but generating a helper for completion support is quite boilerplate-heavy. I think it can be done in a separate crate, but, for better discoverability and to keep with rustyline changes, it would be nice for it to be developed under the rustyline umbrella.

newpavlov avatar May 04 '23 11:05 newpavlov

+1, not that my vote counts. It would be great to have some way to implement rustyline::completion::Completer for a clap::CommandFactory or whatnot. I did find this, but it doesn't look like it handles flags and it also only supports CLAPv3.

darconeous avatar Jun 23 '23 21:06 darconeous

For just parsing it seems to work nice (using shlex for tokenizing).

use clap::CommandFactory;
use clap::FromArgMatches;
use clap::Parser;
use clap::Error

#[derive(Debug, PartialEq, Eq, Parser)]
enum Command {
    /// Quit the REPL
    Quit,
    /// Undo statements
    Undo {
        /// Number of statements to undo
        n: Option<usize>,
    },
    /// Clear the repl history
    Clear,
}

impl Command {
    fn parse(input: &str) -> Result<Self, Error> {
        let args = ["".to_string()].into_iter().chain(shlex::Shlex::new(input));
        let matches = Command::command()
            .override_usage("> [COMMAND]")
            .disable_help_flag(true)
            .try_get_matches_from(args)?;
        Command::from_arg_matches(&matches)
    }
}

I'm not sure why the colors are not showing though. I'll have to dig deeper into their docs.

segeljakt avatar Jun 29 '23 08:06 segeljakt