summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2023-03-17 11:29:16 +0200
committerJustin Wernick <justin@worthe-it.co.za>2023-03-17 11:29:16 +0200
commit5d3b67cc755e1ffc2d9e986dd0a725160d09ae69 (patch)
tree18d8a9ac7f6976d9e276d49b40e1e1872e2a5320 /src
parentf5a00e9090b9d81936137c3fc676cfd0ad25430c (diff)
Use rustyline
Diffstat (limited to 'src')
-rw-r--r--src/main.rs50
-rw-r--r--src/parser.rs4
2 files changed, 32 insertions, 22 deletions
diff --git a/src/main.rs b/src/main.rs
index bcbfe1c..e02be3e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,7 +3,8 @@ mod parser;
use clap::Parser;
use parser::*;
-use std::{io, io::Write, ops::ControlFlow, process::Command};
+use rustyline::{error::ReadlineError, DefaultEditor};
+use std::{io, ops::ControlFlow, process::Command};
use thiserror::Error;
/// Shackle Shell - A replacement for git-shell with repo management commands built in.
@@ -15,18 +16,6 @@ struct Args {
command: Option<String>,
}
-fn prompt() -> Result<(), ShackleError> {
- print!("> ");
- io::stdout().flush()?;
- Ok(())
-}
-
-fn read_stdin() -> Result<String, ShackleError> {
- let mut buffer = String::new();
- io::stdin().read_line(&mut buffer)?;
- Ok(buffer)
-}
-
fn main() -> Result<(), ShackleError> {
let args = Args::parse();
match args.command {
@@ -95,13 +84,34 @@ fn run_command(user_input: String) -> Result<ControlFlow<(), ()>, ShackleError>
}
fn run_interactive_loop() -> Result<(), ShackleError> {
+ let mut rl = DefaultEditor::new()?;
loop {
- prompt()?;
- let user_input = read_stdin()?;
- // TODO: should this report errors differently? Most of the errors are from user actions.
- let control_flow = run_command(user_input)?;
- if control_flow.is_break() {
- break;
+ let readline = rl.readline("> ");
+ match readline {
+ Ok(user_input) => {
+ rl.add_history_entry(user_input.as_str())?;
+ match run_command(user_input) {
+ Ok(control_flow) => {
+ if control_flow.is_break() {
+ break;
+ }
+ }
+ Err(e) => {
+ println!("{:?}", e);
+ }
+ }
+ }
+ Err(ReadlineError::Interrupted) => {
+ println!("Interrupted");
+ break;
+ }
+ Err(ReadlineError::Eof) => {
+ break;
+ }
+ Err(err) => {
+ println!("Error: {:?}", err);
+ break;
+ }
}
}
Ok(())
@@ -115,4 +125,6 @@ pub enum ShackleError {
IoError(#[from] io::Error),
#[error(transparent)]
GitError(#[from] git2::Error),
+ #[error(transparent)]
+ ReadlineError(#[from] ReadlineError),
}
diff --git a/src/parser.rs b/src/parser.rs
index 89e0d76..9938924 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -58,9 +58,7 @@ impl FromStr for ShackleCommand {
fn from_str(s: &str) -> Result<Self, Self::Err> {
let trimmed = s.trim();
- if s.len() == 0 {
- Ok(ShackleCommand::Exit)
- } else if trimmed.len() == 0 {
+ if trimmed.len() == 0 {
Ok(ShackleCommand::Whitespace)
} else {
let lexed = shlex::split(trimmed);