{"id":17928869,"url":"https://github.com/hkalbasi/clap-repl","last_synced_at":"2025-09-09T16:48:21.664Z","repository":{"id":182976543,"uuid":"657054594","full_name":"HKalbasi/clap-repl","owner":"HKalbasi","description":"Build nice REPLs using clap and reedline with zero effort","archived":false,"fork":false,"pushed_at":"2025-03-14T13:37:04.000Z","size":45,"stargazers_count":60,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-29T11:06:39.520Z","etag":null,"topics":["clap-rs","command-line","repl","rust"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/clap-repl","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HKalbasi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE_APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-22T08:07:42.000Z","updated_at":"2025-03-28T05:40:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"ec9f3d21-f895-4971-8754-277959b7707b","html_url":"https://github.com/HKalbasi/clap-repl","commit_stats":null,"previous_names":["hkalbasi/clap-repl"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HKalbasi%2Fclap-repl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HKalbasi%2Fclap-repl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HKalbasi%2Fclap-repl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HKalbasi%2Fclap-repl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HKalbasi","download_url":"https://codeload.github.com/HKalbasi/clap-repl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247332560,"owners_count":20921853,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clap-rs","command-line","repl","rust"],"created_at":"2024-10-28T21:05:45.379Z","updated_at":"2025-04-05T12:03:39.795Z","avatar_url":"https://github.com/HKalbasi.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# clap-repl\n\n[![Rust](https://github.com/HKalbasi/clap-repl/actions/workflows/rust.yml/badge.svg)](https://github.com/HKalbasi/clap-repl/actions/workflows/rust.yml)\n[![crates.io](https://img.shields.io/crates/v/clap-repl.svg)](https://crates.io/crates/clap-repl)\n\nOne of the typical user interfaces for prompting commands is the repl (read eval print loop). One of the best ways of representing commands in a repl\nis using space separated arguments, which is what terminal shells do. And the way to parse such commands in Rust is the `clap` crate. This crate uses\n`clap` and `reedline` to provide such user interface in a way that you only focus on your app logic.\n\n## Features\n\nThanks to `clap` and `reedline` this crate handles:\n* Parsing the space separated commands into your data structure.\n* Help flag for each command.\n* Verifying the command is valid, generating useful errors and suggestions otherwise.\n* Auto complete and hint for the commands.\n\n## Example\n\n```Rust\nuse std::path::PathBuf;\n\nuse clap::{Parser, ValueEnum};\nuse clap_repl::reedline::{\n    DefaultPrompt, DefaultPromptSegment, FileBackedHistory, Reedline, Signal,\n};\nuse clap_repl::ClapEditor;\n\n#[derive(Debug, Parser)]\n#[command(name = \"\")] // This name will show up in clap's error messages, so it is important to set it to \"\".\nenum SampleCommand {\n    Download {\n        path: PathBuf,\n        /// Check the integrity of the downloaded object\n        ///\n        /// Uses SHA256\n        #[arg(long)]\n        check_sha: bool,\n    },\n    /// A command to upload things.\n    Upload,\n    /// Login into the system.\n    Login {\n        /// Optional. You will be prompted if you don't provide it.\n        #[arg(short, long)]\n        username: Option\u003cString\u003e,\n        #[arg(short, long, value_enum, default_value_t = Mode::Secure)]\n        mode: Mode,\n    },\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]\nenum Mode {\n    /// Encrypt the password\n    Secure,\n    /// Send the password plain\n    ///\n    /// This paragraph is ignored because there is no long help text for possible values in clap.\n    Insecure,\n}\n\nfn main() {\n    let prompt = DefaultPrompt {\n        left_prompt: DefaultPromptSegment::Basic(\"simple-example\".to_owned()),\n        ..DefaultPrompt::default()\n    };\n    let rl = ClapEditor::\u003cSampleCommand\u003e::builder()\n        .with_prompt(Box::new(prompt))\n        .with_editor_hook(|reed| {\n            // Do custom things with `Reedline` instance here\n            reed.with_history(Box::new(\n                FileBackedHistory::with_file(10000, \"/tmp/clap-repl-simple-example-history\".into())\n                    .unwrap(),\n            ))\n        })\n        .build();\n    rl.repl(|command| {\n        match command {\n            SampleCommand::Download { path, check_sha } =\u003e {\n                println!(\"Downloaded {path:?} with checking = {check_sha}\");\n            }\n            SampleCommand::Upload =\u003e {\n                println!(\"Uploaded\");\n            }\n            SampleCommand::Login { username, mode } =\u003e {\n                // You can use another `reedline::Reedline` inside the loop.\n                let mut rl = Reedline::create();\n                let username = username\n                    .unwrap_or_else(|| read_line_with_reedline(\u0026mut rl, \"What is your username? \"));\n                let password = read_line_with_reedline(\u0026mut rl, \"What is your password? \");\n                println!(\"Logged in with {username} and {password} in mode {mode:?}\");\n            }\n        }\n    });\n}\n\nfn read_line_with_reedline(rl: \u0026mut Reedline, prompt: \u0026str) -\u003e String {\n    let Signal::Success(x) = rl\n        .read_line(\u0026DefaultPrompt::new(\n            DefaultPromptSegment::Basic(prompt.to_owned()),\n            DefaultPromptSegment::Empty,\n        ))\n        .unwrap()\n    else {\n        panic!();\n    };\n    x\n}\n```\n![Screenshot from 2023-06-22 11-32-58](https://github.com/HKalbasi/clap-repl/assets/45197576/2c1b2ceb-e562-4536-8b42-4025d5a9674a)\n![Screenshot from 2023-06-22 11-35-33](https://github.com/HKalbasi/clap-repl/assets/45197576/bec9110e-a399-41e4-8f63-1c8592338625)\n![image](https://github.com/HKalbasi/clap-repl/assets/45197576/a5eb04c0-fafc-479e-ba1a-dd5757f585be)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhkalbasi%2Fclap-repl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhkalbasi%2Fclap-repl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhkalbasi%2Fclap-repl/lists"}