aboutsummaryrefslogtreecommitdiffstats
path: root/src/parse
diff options
context:
space:
mode:
authorJonas Maier <>2026-03-10 16:43:21 +0100
committerJonas Maier <>2026-03-10 16:43:21 +0100
commit8046a94bde376e018c01df4cdc3ade2c6aeaf32c (patch)
treee09b2be4faefddc2c3300bd4d1fcca44657ac9ec /src/parse
parent1bab9e3ed54476d0b4a47da84693a2e4e50effc6 (diff)
downloadpish-8046a94bde376e018c01df4cdc3ade2c6aeaf32c.tar.gz
completion in command interpolation
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/mod.rs40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index 4f7dac5..4250caf 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -93,7 +93,10 @@ pub fn var_default(x: &[u8], default: ExpString) -> StringPart {
}
pub fn cmdp(x: Ast<PreExpansion>) -> StringPart {
- StringPart::Cmd(x)
+ StringPart::Cmd(CmdInterp {
+ cmd: x,
+ already_complete: true,
+ })
}
pub fn cmd<const N: usize>(x: [ExpString; N]) -> Command<PreExpansion> {
@@ -179,7 +182,7 @@ impl CmdDisplay for StringPart {
}
StringPart::Cmd(ast) => {
write!(w, "cmdp(")?;
- ast.cdisplay(w)?;
+ ast.cmd.cdisplay(w)?;
write!(w, ")")
}
}
@@ -335,7 +338,13 @@ impl Pipes<PreExpansion> {
pub enum StringPart {
Boring(BString),
Var(Var),
- Cmd(Ast<PreExpansion>),
+ Cmd(CmdInterp),
+}
+
+#[derive(Debug, Clone, PartialEq)]
+pub struct CmdInterp {
+ pub cmd: Ast<PreExpansion>,
+ pub already_complete: bool,
}
#[derive(Debug, Clone, PartialEq)]
@@ -391,7 +400,7 @@ impl ExpString {
e.expand_var(v.name.name, default)?
}
StringPart::Cmd(ast) => {
- let exp = ast.expand(e)?;
+ let exp = ast.cmd.expand(e)?;
e.expand_cmd(exp)?
}
};
@@ -608,11 +617,24 @@ impl Parse for ExpString {
b.adv();
let cmd = Ast::parse(b)?;
b.spaces();
+
if b.is_empty() {
- return Err(ParseError::Eof);
- } else if b.peek() == b')' {
+ if !b.is_completion() {
+ return Err(ParseError::Expected(')'));
+ }
+ }
+
+ if b.has() && b.peek() == b')' {
b.adv();
- p.push(StringPart::Cmd(cmd));
+ p.push(StringPart::Cmd(CmdInterp {
+ cmd,
+ already_complete: true,
+ }));
+ } else if b.is_completion() {
+ p.push(StringPart::Cmd(CmdInterp {
+ cmd,
+ already_complete: false,
+ }))
} else {
return Err(ParseError::Expected(')'));
}
@@ -751,6 +773,10 @@ impl ExpString {
kind: CompletionKind::Variable,
partial: var.name.name.clone(),
}
+ } else if let Some(StringPart::Cmd(cmd)) = self.parts.last()
+ && !cmd.already_complete
+ {
+ cmd.cmd.completion(e)
} else if let Ok(s) = self.clone().expand(e) {
CompletionContext { kind, partial: s }
} else {