diff --git a/schala-repl/src/repl/command_tree.rs b/schala-repl/src/repl/command_tree.rs index d1ceda5..30c612b 100644 --- a/schala-repl/src/repl/command_tree.rs +++ b/schala-repl/src/repl/command_tree.rs @@ -54,14 +54,17 @@ impl CommandTree { CommandTree::Top(_) => "" } } - pub fn get_children(&self) -> Vec<&str> { + pub fn get_children(&self) -> &Vec { use CommandTree::*; match self { Terminal { children, .. } | NonTerminal { children, .. } | - Top(children) => children.iter().map(|x| x.get_cmd()).collect() + Top(children) => children } } + pub fn get_subcommands(&self) -> Vec<&str> { + self.get_children().iter().map(|x| x.get_cmd()).collect() + } pub fn perform(&self, repl: &mut Repl, arguments: &Vec<&str>) -> InterpreterDirectiveOutput { let mut dir_pointer: &CommandTree = self; diff --git a/schala-repl/src/repl/help.rs b/schala-repl/src/repl/help.rs index e14af5c..1e51cad 100644 --- a/schala-repl/src/repl/help.rs +++ b/schala-repl/src/repl/help.rs @@ -1,31 +1,39 @@ use std::fmt::Write as FmtWrite; use super::{Repl, InterpreterDirectiveOutput}; -use crate::repl::command_tree::CommandTree; pub fn help(repl: &mut Repl, arguments: &[&str]) -> InterpreterDirectiveOutput { - let mut buf = String::new(); - let directives = match repl.get_directives() { - CommandTree::Top(children) => children, - _ => panic!("Top-level CommandTree not Top") - }; - match arguments { - [] => return global_help(repl, &directives), - _ => { - writeln!(buf, "Command-specific help not available yet").unwrap(); + [] => return global_help(repl), + commands => { + let dirs = repl.get_directives(); + let mut directive_list = dirs.get_children(); + let mut matched_directive = None; + for cmd in commands { + let found = directive_list.iter().find(|directive| directive.get_cmd() == *cmd); + if let Some(dir) = found { + directive_list = dir.get_children(); + } + + matched_directive = found; + } + + Some(if let Some(dir) = matched_directive { + format!("{}", dir.get_help()) + } else { + format!("Last command not found") + }) } - }; - Some(buf) + } } -fn global_help(repl: &mut Repl, directives: &Vec) -> InterpreterDirectiveOutput { +fn global_help(repl: &mut Repl) -> InterpreterDirectiveOutput { let mut buf = String::new(); writeln!(buf, "MetaInterpreter options").unwrap(); writeln!(buf, "-----------------------").unwrap(); - for directive in directives { + for directive in repl.get_directives().get_children() { let trailer = " "; writeln!(buf, "{}{}- {}", directive.get_cmd(), trailer, directive.get_help()).unwrap(); } diff --git a/schala-repl/src/repl/mod.rs b/schala-repl/src/repl/mod.rs index 1070d7a..e8d7073 100644 --- a/schala-repl/src/repl/mod.rs +++ b/schala-repl/src/repl/mod.rs @@ -220,7 +220,7 @@ impl Completer for TabCompleteHandler { _ => false }; let word = if top { word.get(1..).unwrap() } else { word }; - for cmd in command_tree.map(|x| x.get_children()).unwrap_or(vec![]).into_iter() { + for cmd in command_tree.map(|x| x.get_subcommands()).unwrap_or(vec![]).into_iter() { if cmd.starts_with(word) { completions.push(Completion { completion: format!("{}{}", if top { ":" } else { "" }, cmd),