From b677713a7caf179b144674ff4c6e6b7171ad1337 Mon Sep 17 00:00:00 2001 From: Jonas Maier <> Date: Fri, 17 Apr 2026 17:56:58 +0200 Subject: aliases --- src/run/mod.rs | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'src/run/mod.rs') diff --git a/src/run/mod.rs b/src/run/mod.rs index 091c662..d52c4e7 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -18,6 +18,7 @@ pub enum ExecError { IO(std::io::Error), ErrorStack(Vec), Panic, + AliasDepthExceeded, } impl ExecError { @@ -59,6 +60,7 @@ impl ExecError { } out } + ExecError::AliasDepthExceeded => "alias depth exceeded".to_string(), } } } @@ -404,6 +406,62 @@ impl parse::Expander for Executor { } Ok(buf) } + + type AliasAge = AliasAge; + + fn expand_alias( + &mut self, + cmd: &bstr, + older_than: Option, + ) -> Result)>, Self::Error> { + Ok(self + .se + .lock() + .unwrap() + .aliases + .get(cmd, older_than.unwrap_or(AliasAge::MAX))) + } +} + +type AliasAge = u32; +type AliasBody = Vec; +type AliasSet = Vec<(AliasAge, AliasBody)>; + +pub struct Aliases { + age: u32, + aliases: HashMap, +} + +impl Aliases { + pub fn new() -> Self { + Self { + age: 0, + aliases: HashMap::new(), + } + } + + fn insert(&mut self, name: BString, body: AliasBody) { + let age = self.age; + self.age += 1; + let new = (age, body); + if let Some(entry) = self.aliases.get_mut(&name) { + entry.push(new); + } else { + self.aliases.insert(name, vec![new]); + } + } + + fn get(&mut self, name: &bstr, older_than: AliasAge) -> Option<(AliasAge, AliasBody)> { + let Some(alias_set) = self.aliases.get(name) else { + return None; + }; + + alias_set.iter().rev().find(|e| e.0 < older_than).cloned() + } + + fn remove(&mut self, name: &bstr) { + self.aliases.remove(name); + } } fn exec(se: Arc>, ast: Ast) -> Result<(), ExecError> { @@ -479,6 +537,8 @@ const BUILTINS: &[&'static dyn Builtin] = &[ &builtin::null, &builtin::var, &builtin::completion, + &builtin::alias, + &builtin::unalias, ]; pub fn builtin_map() -> HashMap { -- cgit v1.2.3