aboutsummaryrefslogtreecommitdiffstats
path: root/src/completion.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/completion.rs')
-rw-r--r--src/completion.rs62
1 files changed, 62 insertions, 0 deletions
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<Mutex<Session>>, prefix: BString) -> Vec<
out
}
+
+pub struct CompletionResult {
+ pub kind: parse::CompletionKind,
+ pub suggestions: Vec<Suggestion>,
+ 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<Mutex<Session>>, 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,
+ }
+}