diff options
author | Canop <cano.petrole@gmail.com> | 2021-08-12 16:46:10 +0200 |
---|---|---|
committer | Canop <cano.petrole@gmail.com> | 2021-08-12 16:46:10 +0200 |
commit | ee354f9a7a2684783456b10707462f71045b1c3e (patch) | |
tree | b9618e61403db32d331d98e7c88fd0f0d01181c0 | |
parent | c9b840fd85e7eb6393dbb52f4ba3b35cf2f831e7 (diff) |
allow a verb in configuration to refer to a builtin
Fix #432
-rw-r--r-- | src/cli/mod.rs | 3 | ||||
-rw-r--r-- | src/conf/verb_conf.rs | 15 | ||||
-rw-r--r-- | src/verb/verb.rs | 4 | ||||
-rw-r--r-- | src/verb/verb_store.rs | 22 |
4 files changed, 29 insertions, 15 deletions
diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 6f84164..6c72b1b 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -136,8 +136,7 @@ pub fn run() -> Result<Option<Launchable>, ProgramError> { tree_options.apply_launch_args(&cli_matches); // verb store is completed from the config file(s) - let mut verb_store = VerbStore::default(); - verb_store.init(&mut config)?; + let verb_store = VerbStore::new(&mut config)?; // reading the other arguments let file_export_path = cli_matches.value_of("file-export-path").map(str::to_string); diff --git a/src/conf/verb_conf.rs b/src/conf/verb_conf.rs index 022425a..cf4b1dc 100644 --- a/src/conf/verb_conf.rs +++ b/src/conf/verb_conf.rs @@ -7,7 +7,6 @@ use { verb::*, }, serde::Deserialize, - std::convert::TryFrom, }; /// a deserializable verb entry in the configuration @@ -51,9 +50,11 @@ pub struct VerbConf { /// read a deserialized verb conf item into a verb, /// checking a few basic things in the process -impl TryFrom<&VerbConf> for Verb { - type Error = ConfError; - fn try_from(vc: &VerbConf) -> Result<Self, Self::Error> { +impl VerbConf { + /// the verb_store is provided to allow a verb to be built from other ones + /// already defined + pub fn make_verb(&self, previous_verbs: &[Verb]) -> Result<Verb, ConfError> { + let vc = self; if vc.leave_broot == Some(false) && vc.from_shell == Some(true) { return Err(ConfError::InvalidVerbConf { details: "You can't simultaneously have leave_broot=false and from_shell=true".to_string(), @@ -83,7 +84,11 @@ impl TryFrom<&VerbConf> for Verb { // an external (Some(ep), None, None, None) => { if let Some(internal_pattern) = ep.as_internal_pattern() { - VerbExecution::Internal(InternalExecution::try_from(internal_pattern)?) + if let Some(previous_verb) = previous_verbs.iter().find(|&v| v.has_name(internal_pattern)) { + previous_verb.execution.clone() + } else { + VerbExecution::Internal(InternalExecution::try_from(internal_pattern)?) + } } else { VerbExecution::External(make_external_execution(ep.clone())) } diff --git a/src/verb/verb.rs b/src/verb/verb.rs index c800b06..336de58 100644 --- a/src/verb/verb.rs +++ b/src/verb/verb.rs @@ -169,6 +169,10 @@ impl Verb { self } + pub fn has_name(&self, searched_name: &str) -> bool { + self.names.iter().any(|name| name == searched_name) + } + /// Assuming the verb has been matched, check whether the arguments /// are OK according to the regex. Return none when there's no problem /// and return the error to display if arguments don't match. diff --git a/src/verb/verb_store.rs b/src/verb/verb_store.rs index ff139e6..b7db794 100644 --- a/src/verb/verb_store.rs +++ b/src/verb/verb_store.rs @@ -11,7 +11,6 @@ use { keys, }, crossterm::event::KeyEvent, - std::convert::TryFrom, }; /// Provide access to the verbs: @@ -21,7 +20,6 @@ use { /// When the user types some keys, we select a verb /// - if the input exactly matches a shortcut or the name /// - if only one verb name starts with the input -#[derive(Default)] pub struct VerbStore { pub verbs: Vec<Verb>, } @@ -34,14 +32,22 @@ pub enum PrefixSearchResult<'v, T> { } impl VerbStore { - pub fn init(&mut self, conf: &mut Conf) -> Result<(), ConfError> { - // We first add the verbs coming from configuration, as we'll search in order. - // This way, a user can overload a standard verb. + pub fn new(conf: &mut Conf) -> Result<Self, ConfError> { + // we start with the builtin verbs so that a verb from configuration + // can refer to a built-in + let mut verbs = builtin_verbs(); + for vc in &conf.verbs { - self.verbs.push(Verb::try_from(vc)?); + let verb = vc.make_verb(&verbs)?; + verbs.push(verb); } - self.verbs.extend(builtin_verbs()); - Ok(()) + + // We reverse the array as we'll search in order. + // This way, a user can overload a standard verb, or a standard + // shortcut. + verbs.reverse(); + + Ok(Self { verbs }) } pub fn search_sel_info<'v>( |