From 7728b844958bb7882ddf384b40e5711d7a9316ad Mon Sep 17 00:00:00 2001 From: Jonas Maier <> Date: Tue, 10 Mar 2026 13:13:49 +0100 Subject: completion if there is variables in the to-be-completed string --- src/completion.rs | 1 + src/main.rs | 10 +++++----- src/parse/mod.rs | 18 +++++++----------- src/run/mod.rs | 20 +++++++++++++++++++- 4 files changed, 32 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/completion.rs b/src/completion.rs index 237e956..3adce90 100644 --- a/src/completion.rs +++ b/src/completion.rs @@ -47,6 +47,7 @@ fn _path_completion(mut prefix: BString) -> io::Result> { } pub fn path_completion(prefix: BString) -> Vec { + eprintln!("path completion request for {}\r\n", String::from_utf8_lossy(&prefix)); match _path_completion(prefix) { Ok(suggestions) => suggestions, Err(err) => { diff --git a/src/main.rs b/src/main.rs index 1d8806a..17c4ba0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,6 +32,7 @@ use raw::*; use crate::cursor::{Direction, move_cursor}; use crate::history::HistoryEntry; use crate::parse::{Ast, PreExpansion}; +use crate::run::Executor; macro_rules! print { ($($x:tt)*) => {{ @@ -348,7 +349,9 @@ fn event_loop() { b'\t' => { let cmd = se.line.into_bytes(); - let comp = parse::completion_context(&cmd); + drop(se); + let comp = parse::completion_context(&cmd, &mut Executor::new_for_completion(session.clone())); + let mut se = session.lock().unwrap(); match comp.kind { parse::CompletionKind::Command => todo!(), parse::CompletionKind::Argument => { @@ -376,10 +379,7 @@ fn event_loop() { stdout.lock().flush().unwrap(); } parse::CompletionKind::None => { - for _ in 0..4 { - se.line.add(b' '); - print!(" ") - } + se.type_bytes(b" "); } } } diff --git a/src/parse/mod.rs b/src/parse/mod.rs index f08426e..47e2d87 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -704,27 +704,23 @@ impl CompletionContext { } } -fn expstr_cc(s: &ExpString, kind: CompletionKind) -> CompletionContext { - if s.parts.len() > 1 || !s.parts[0].is_boring() { - CompletionContext::none() - } else { - CompletionContext { - kind, - partial: s.parts[0].clone().unwrap_boring().clone(), - } +fn expstr_cc(s: &ExpString, kind: CompletionKind, e: &mut E) -> CompletionContext { + match s.clone().expand(e) { + Ok(buf) => CompletionContext { kind, partial: buf }, + Err(_) => CompletionContext::none(), } } -pub fn completion_context<'a>(x: &'a [u8]) -> CompletionContext { +pub fn completion_context<'a, E: Expander>(x: &'a [u8], e: &mut E) -> CompletionContext { let mut cursor = Cursor::new(x, ParseMode::Completion); let ast = Ast::parse(&mut cursor); match ast { Ok(Ast::Pipes(pipes)) if cursor.spaced == false => { if let Some(cmd) = pipes.cmds.last() { if cmd.args.is_empty() { - expstr_cc(&cmd.cmd, CompletionKind::Command) + expstr_cc(&cmd.cmd, CompletionKind::Command, e) } else { - expstr_cc(&cmd.args[cmd.args.len() - 1], CompletionKind::Argument) + expstr_cc(&cmd.args[cmd.args.len() - 1], CompletionKind::Argument, e) } } else { CompletionContext::none() diff --git a/src/run/mod.rs b/src/run/mod.rs index 757f4cc..5a8370f 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -83,6 +83,7 @@ impl From for ExecError { pub struct Executor { se: Arc>, args: Option>, + expand_commands: bool, } pub enum Input { @@ -172,6 +173,14 @@ impl SpawnedCmd { } impl Executor { + pub fn new_for_completion(se: Arc>) -> Self { + Self { + se, + args: None, + expand_commands: false, + } + } + fn spawn_cmd( &mut self, cmd: CommandKind, @@ -310,6 +319,7 @@ impl Executor { let mut this = Self { se: session, args: None, + expand_commands: true, }; let cmd = parse::Command { @@ -362,6 +372,10 @@ impl parse::Expander for Executor { } fn expand_cmd(&mut self, ast: Ast) -> Result { + if !self.expand_commands { + return Err(ExecError::ExecError(-1)); + } + let (stdin, _) = io::pipe().unwrap(); let (mut expansion, stdout) = io::pipe().unwrap(); let mut this = self.clone(); @@ -378,7 +392,11 @@ impl parse::Expander for Executor { } fn exec(se: Arc>, ast: Ast) -> Result<(), ExecError> { - let mut exec = Executor { se, args: None }; + let mut exec = Executor { + se, + args: None, + expand_commands: true, + }; let ast = ast.expand(&mut exec)?; exec.execute(ast, Input::Stdin, Output::Stdout) } -- cgit v1.2.3