From 7b5a112d000bb21fd81569617353daa0c911d084 Mon Sep 17 00:00:00 2001 From: Jonas Maier <> Date: Tue, 17 Mar 2026 15:17:23 +0100 Subject: refactor completion logic --- src/completion.rs | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'src/completion.rs') diff --git a/src/completion.rs b/src/completion.rs index 3e2565b..c7a183f 100644 --- a/src/completion.rs +++ b/src/completion.rs @@ -1,3 +1,4 @@ +use crate::parse::{self, CompletionContext}; use crate::{BString, Session}; use std::collections::HashMap; use std::ffi::OsStr; @@ -139,3 +140,64 @@ pub fn command_completion(session: Arc>, prefix: BString) -> Vec< out } + +pub struct CompletionResult { + pub kind: parse::CompletionKind, + pub suggestions: Vec, + pub shared_prefix: BString, +} + +impl CompletionResult { + pub fn empty() -> Self { + CompletionResult { + kind: parse::CompletionKind::None, + suggestions: Vec::new(), + shared_prefix: BString::new(), + } + } +} + +pub fn completion(session: Arc>, cmd: &[u8]) -> CompletionResult { + let comp = parse::completion_context( + &cmd, + &mut crate::run::Executor::new_for_completion(session.clone()), + ); + + let mut suggestions = match comp.kind { + parse::CompletionKind::Command => command_completion(session.clone(), comp.partial), + parse::CompletionKind::Argument => path_completion(comp.partial), + parse::CompletionKind::Variable => variable_completion(session.clone(), comp.partial), + parse::CompletionKind::None => return CompletionResult::empty(), + }; + + suggestions.sort_by(|x, y| x.delta.cmp(&y.delta)); + suggestions.dedup_by(|x, y| x.delta == y.delta); + + if suggestions.is_empty() { + return CompletionResult { + kind: comp.kind, + ..CompletionResult::empty() + }; + } + + // find longest shared prefix + let mut shared_prefix = &suggestions[0].delta[..]; + for s in suggestions.iter() { + let mut new = &shared_prefix[..0]; + for i in 0..shared_prefix.len().min(s.delta.len()) { + if shared_prefix[i] != s.delta[i] { + break; + } else { + new = &s.delta[..=i]; + } + } + shared_prefix = new; + } + let shared_prefix = shared_prefix.to_vec(); + + CompletionResult { + kind: comp.kind, + suggestions, + shared_prefix, + } +} -- cgit v1.2.3