aboutsummaryrefslogtreecommitdiffstats
path: root/src/parse
diff options
context:
space:
mode:
authorJonas Maier <>2026-04-17 17:56:58 +0200
committerJonas Maier <>2026-04-17 17:56:58 +0200
commitb677713a7caf179b144674ff4c6e6b7171ad1337 (patch)
tree073c32bac54fe2b960203ddd307530a5e761ebad /src/parse
parentddd2627360ee7a30b26cd3b7fab19ede55c574d7 (diff)
downloadpish-b677713a7caf179b144674ff4c6e6b7171ad1337.tar.gz
aliases
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/mod.rs45
1 files changed, 41 insertions, 4 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index 8682f04..184a514 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -1,4 +1,4 @@
-use crate::BString;
+use crate::{BString, bstr};
#[cfg(test)]
mod test;
@@ -30,6 +30,17 @@ pub trait Expander {
type Error;
fn expand_var(&mut self, v: BString, default: Option<BString>) -> Res<BString, Self::Error>;
fn expand_cmd(&mut self, c: Ast<PostExpansion>) -> Res<BString, Self::Error>;
+
+ type AliasAge;
+ fn expand_alias(
+ &mut self,
+ cmd: &bstr,
+ age: Option<Self::AliasAge>,
+ ) -> Res<Option<(Self::AliasAge, Vec<ExpString>)>, Self::Error> {
+ let _ = cmd;
+ let _ = age;
+ Ok(None)
+ }
}
#[derive(Debug, Clone, PartialEq)]
@@ -857,7 +868,30 @@ pub struct Command<T: Stage> {
}
impl Command<PreExpansion> {
- fn expand<E: Expander>(self, e: &mut E) -> Res<Command<PostExpansion>, E::Error> {
+ fn full_alias_expansion<E: Expander>(&mut self, e: &mut E) -> Res<(), E::Error> {
+ self.args.reverse();
+ let mut age = None;
+
+ while self.cmd.parts.len() == 1
+ && let StringPart::Boring(s) = &self.cmd.parts[0]
+ {
+ if let Some((new_age, exp)) = e.expand_alias(&s, age.take())? {
+ age = Some(new_age);
+ self.cmd = exp.first().unwrap().clone();
+ for e in exp.into_iter().skip(1).rev() {
+ self.args.push(e);
+ }
+ } else {
+ break;
+ }
+ }
+ self.args.reverse();
+
+ Ok(())
+ }
+
+ fn expand<E: Expander>(mut self, e: &mut E) -> Res<Command<PostExpansion>, E::Error> {
+ self.full_alias_expansion(e)?;
let cmd = self.cmd.expand(e)?;
let mut args = Vec::with_capacity(self.args.len());
for arg in self.args.into_iter() {
@@ -999,8 +1033,11 @@ pub fn completion_context<E: Expander>(x: &[u8], e: &mut E) -> CompletionContext
ast.completion(e)
}
-trait Parse: Sized {
+pub trait Parse: Sized {
fn parse(b: &mut Cursor<'_>) -> Result<Self>;
+ fn parse_from_bytes(x: &[u8]) -> Result<Self> {
+ Self::parse(&mut Cursor::new(x, ParseMode::Command))
+ }
}
enum ParseMode {
@@ -1008,7 +1045,7 @@ enum ParseMode {
Completion,
}
-struct Cursor<'a> {
+pub struct Cursor<'a> {
buf: &'a [u8],
mode: ParseMode,