summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock92
-rw-r--r--Cargo.toml1
-rw-r--r--readme.org6
-rw-r--r--src/main.rs50
-rw-r--r--src/parser.rs4
5 files changed, 127 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ffc28bf..60f3880 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -108,6 +108,17 @@ dependencies = [
]
[[package]]
+name = "clipboard-win"
+version = "4.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362"
+dependencies = [
+ "error-code",
+ "str-buf",
+ "winapi",
+]
+
+[[package]]
name = "comma"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -153,6 +164,16 @@ dependencies = [
]
[[package]]
+name = "error-code"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21"
+dependencies = [
+ "libc",
+ "str-buf",
+]
+
+[[package]]
name = "fastrand"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -341,6 +362,18 @@ dependencies = [
]
[[package]]
+name = "nix"
+version = "0.26.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "libc",
+ "static_assertions",
+]
+
+[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -488,7 +521,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01ff60778f96fb5a48adbe421d21bf6578ed58c0872d712e7e08593c195adff8"
dependencies = [
"comma",
- "nix",
+ "nix 0.25.1",
"regex",
"tempfile",
"thiserror",
@@ -509,6 +542,32 @@ dependencies = [
]
[[package]]
+name = "rustyline"
+version = "11.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dfc8644681285d1fb67a467fb3021bfea306b99b4146b166a1fe3ada965eece"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "clipboard-win",
+ "libc",
+ "log",
+ "memchr",
+ "nix 0.26.2",
+ "scopeguard",
+ "unicode-segmentation",
+ "unicode-width",
+ "utf8parse",
+ "winapi",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
name = "serde"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -526,6 +585,7 @@ dependencies = [
"nom",
"once_cell",
"rexpect",
+ "rustyline",
"shlex",
"tempfile",
"thiserror",
@@ -538,6 +598,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "str-buf"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0"
+
+[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -639,6 +711,18 @@ dependencies = [
]
[[package]]
+name = "unicode-segmentation"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+
+[[package]]
name = "url"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -650,6 +734,12 @@ dependencies = [
]
[[package]]
+name = "utf8parse"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+
+[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index f2a906a..5771db2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,6 +10,7 @@ clap = { version = "4.1.8", features = ["derive"] }
git2 = { version = "0.16.1", default-features = false, features = ["vendored-libgit2"] }
nom = "7.1.3"
rexpect = "0.5.0"
+rustyline = { version = "11.0.0", default-features = false }
shlex = "1.1.0"
thiserror = "1.0.38"
diff --git a/readme.org b/readme.org
index fe09dc5..0753297 100644
--- a/readme.org
+++ b/readme.org
@@ -21,11 +21,11 @@ Pijul.
- [X] Isolation of workdir between tests
- [X] git fetch with git upload-pack
- [X] git push with git receive-pack
-- [X] proper shell argument lexing, with quote stuff https://lib.rs/crates/shlex
+- [X] proper shell argument lexing, with quote stuff
+- [X] history (only within same session)
- [ ] restrict repos to only acceptable paths
- [ ] git init of shared repos
-- [ ] history (only within same session) https://lib.rs/crates/rustyline
-- [ ] don't quit interactive shell sessions if there's an error
+- [X] don't quit interactive shell sessions if there's an error
- [ ] git archive with git upload-archive
- [X] help command
- [ ] help docs on all the commands
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);