From 8046a94bde376e018c01df4cdc3ade2c6aeaf32c Mon Sep 17 00:00:00 2001 From: Jonas Maier <> Date: Tue, 10 Mar 2026 16:43:21 +0100 Subject: completion in command interpolation --- src/parse/mod.rs | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'src') 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) -> StringPart { - StringPart::Cmd(x) + StringPart::Cmd(CmdInterp { + cmd: x, + already_complete: true, + }) } pub fn cmd(x: [ExpString; N]) -> Command { @@ -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 { pub enum StringPart { Boring(BString), Var(Var), - Cmd(Ast), + Cmd(CmdInterp), +} + +#[derive(Debug, Clone, PartialEq)] +pub struct CmdInterp { + pub cmd: Ast, + 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 { -- cgit v1.2.3