diff --git a/Cargo.lock b/Cargo.lock index 16c27fc6ed..1454300e56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,14 @@ dependencies = [ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "argon2rs" version = "0.2.5" @@ -118,6 +126,14 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "conch-parser" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "constant_time_eq" version = "0.1.3" @@ -246,6 +262,17 @@ name = "lazy_static" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lexical-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "stackvector 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "libc" version = "0.2.54" @@ -289,6 +316,16 @@ name = "nodrop" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "nom" +version = "5.0.0-beta1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lexical-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-integer" version = "0.1.39" @@ -319,12 +356,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "objectshell" version = "0.1.0" dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "chrono-tz 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "conch-parser 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)", "prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustyline 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustyline 4.0.0 (git+https://github.com/jonathandturner/rustyline.git)", "sysinfo 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -472,7 +512,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustyline" version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/jonathandturner/rustyline.git#15cc18b1dd550873c9a44d90e8992f18c46b3744" dependencies = [ "dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", @@ -505,6 +545,19 @@ name = "serde" version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "stackvector" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "static_assertions" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "syn" version = "0.15.34" @@ -596,6 +649,14 @@ name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "utf8-ranges" version = "1.0.2" @@ -606,6 +667,11 @@ name = "utf8parse" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "void" version = "1.0.2" @@ -632,6 +698,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392" "checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" @@ -646,6 +713,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum chrono-tz 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e0e430fad0384e4defc3dc6b1223d1b886087a8bf9b7080e5ae027f73851ea15" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum conch-parser 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a6a607cf95979f2126c094f2ce279fbc8c58b7649d3b4a25905950931eba3c9" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" @@ -662,12 +730,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" +"checksum lexical-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e82e023e062f1d25f807ad182008fba1b46538e999f908a08cc0c29e084462e" "checksum libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)" = "6527f311b2baba609e980e008460ab5ebff6d6da15213bb8eb193b7746eefa24" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" @@ -688,11 +758,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58" "checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" "checksum rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288" -"checksum rustyline 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf0a3bbb3167469f834da68a6636b93d4f6838f5438dd53ac02668abee8b997a" +"checksum rustyline 4.0.0 (git+https://github.com/jonathandturner/rustyline.git)" = "" "checksum ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f" "checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)" = "a72e9b96fa45ce22a4bc23da3858dfccfd60acd28a25bcd328a98fdd6bea43fd" +"checksum stackvector 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c049c77bf85fbc036484c97b008276d539d9ebff9dfbde37b632ebcd5b8746b6" +"checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" "checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum sysinfo 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d88e417391431019773011a31a6c967538da388782b7711f2f6fafd9e601e55" @@ -704,8 +776,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" "checksum utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d" +"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" diff --git a/Cargo.toml b/Cargo.toml index 2a5f671b78..cccfdf8d09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,13 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rustyline = "4.0.0" +rustyline = { version = "4.0.0", git = "https://github.com/jonathandturner/rustyline.git" } sysinfo = "0.8.3" chrono = "0.4.6" chrono-tz = "0.5.1" derive-new = "0.5.6" prettytable-rs = "0.8.0" itertools = "0.8.0" +ansi_term = "0.11.0" +conch-parser = "0.1.0" +nom = "5.0.0-beta1" diff --git a/history.txt b/history.txt index 3acce780b7..ae997c8ba9 100644 --- a/history.txt +++ b/history.txt @@ -5,3 +5,21 @@ ps ls ps ls +cargo install cargo-edit +ls +ls | foo | bar +ls +ls | ap +ls ab cd +ls ab cd | de +ls ab cd | grep 1243 +ls ab cd|grep 1243 +ls +hello world +hello world | zomg +ls +ls | zomgt +ls | zomg +ls soms +ls something +ls something | grep diff --git a/src/main.rs b/src/main.rs index b687ed2d4e..a5986355be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,16 +7,22 @@ mod env; mod errors; mod format; mod object; +mod parser; crate use crate::commands::command::Command; crate use crate::env::{Environment, Host}; crate use crate::format::RenderView; +crate use crate::errors::ShellError; use crate::object::base::{ToEntriesView, ToGenericView}; use rustyline::error::ReadlineError; use rustyline::Editor; use std::collections::BTreeMap; use std::error::Error; use sysinfo::{self, SystemExt}; +use ansi_term::Color; +use conch_parser::lexer::Lexer; +use conch_parser::parse::DefaultParser; + #[derive(Debug)] pub enum MaybeOwned<'a, T> { @@ -52,12 +58,25 @@ fn main() -> Result<(), Box> { commands.insert("ls".to_string(), Box::new(ls)); loop { - let readline = rl.readline(">> "); + let readline = rl.readline(&format!("{}> ", Color::Green.paint(env.cwd().display().to_string()))); + match readline { Ok(line) => { + let result = crate::parser::shell_parser(&line).map_err(|e| ShellError::new(format!("{:?}", e)))?; + + let parsed = result.1; + rl.add_history_entry(line.as_ref()); - match commands.get_mut(&line) { + if parsed.len() > 1 { + println!("Piping is not yet implemented"); + } + + println!("DEBUG: {:?}", parsed); + + let command = &parsed[0][0].name(); + + match commands.get_mut(*command) { Some(command) => { let result = command.run(&mut host, &mut env).unwrap(); let view = result.to_generic_view(); diff --git a/src/parser.rs b/src/parser.rs new file mode 100644 index 0000000000..4d60103733 --- /dev/null +++ b/src/parser.rs @@ -0,0 +1,52 @@ +use nom::branch::alt; +use nom::bytes::complete::{escaped, is_not, tag}; +use nom::{ws, named, separated_list, complete}; +use nom::character::complete::one_of; +use nom::multi::separated_list; +use nom::sequence::{preceded, terminated}; +use nom::IResult; + +#[derive(Debug)] +pub enum Item { + Quoted(String), + Bare(String), +} + +impl Item { + crate fn name(&self) -> &str { + match self { + Item::Quoted(s) => s, + Item::Bare(s) => s + } + } +} + +fn esc(s: &str) -> IResult<&str, &str> { + escaped(is_not("\\\""), '\\', one_of("\"n\\"))(s) +} + +fn quoted(s: &str) -> IResult<&str, Item> { + terminated(preceded(tag("\""), esc), tag("\""))(s) + .map(|(a, b)| (a, Item::Quoted(b.to_string()))) +} + +fn unquoted(s: &str) -> IResult<&str, Item> { + is_not(" |")(s).map(|(a, b)| (a, Item::Bare(b.to_string()))) +} + +fn command_token(s: &str) -> IResult<&str, Item> { + alt((quoted, unquoted))(s) +} + +fn command_args(s: &str) -> IResult<&str, Vec> { + separated_list(tag(" "), command_token)(s) +} + +named!( + pub shell_parser(&str) -> Vec>, + complete!( + ws!( + separated_list!(tag("|"), command_args) + ) + ) +);