nushell/crates/nu-cli/src/completions/flag_completions.rs
Richard 0de289f6b7
Feature/refactor completion options (#5228)
* Copy completion filter to custom completions

* Remove filter function from completer

This function was a no-op for FileCompletion and CommandCompletion.
Flag- and VariableCompletion just filters with `starts_with` which
happens in both completers anyway and should therefore also be a no-op.
The remaining use case in CustomCompletion was moved into the
CustomCompletion source file.

Filtering should probably happen immediately while fetching completions
to avoid unnecessary memory allocations.

* Add get_sort_by() to Completer trait

* Remove CompletionOptions from Completer::fetch()

* Fix clippy lints

* Apply Completer changes to DotNuCompletion
2022-04-19 13:59:10 -05:00

81 lines
2.4 KiB
Rust

use crate::completions::Completer;
use nu_protocol::{
ast::{Expr, Expression},
engine::StateWorkingSet,
Span,
};
use reedline::Suggestion;
#[derive(Clone)]
pub struct FlagCompletion {
expression: Expression,
}
impl FlagCompletion {
pub fn new(expression: Expression) -> Self {
Self { expression }
}
}
impl Completer for FlagCompletion {
fn fetch(
&mut self,
working_set: &StateWorkingSet,
prefix: Vec<u8>,
span: Span,
offset: usize,
_: usize,
) -> Vec<Suggestion> {
// Check if it's a flag
if let Expr::Call(call) = &self.expression.expr {
let decl = working_set.get_decl(call.decl_id);
let sig = decl.signature();
let mut output = vec![];
for named in &sig.named {
let flag_desc = &named.desc;
if let Some(short) = named.short {
let mut named = vec![0; short.len_utf8()];
short.encode_utf8(&mut named);
named.insert(0, b'-');
if named.starts_with(&prefix) {
output.push(Suggestion {
value: String::from_utf8_lossy(&named).to_string(),
description: Some(flag_desc.to_string()),
extra: None,
span: reedline::Span {
start: span.start - offset,
end: span.end - offset,
},
});
}
}
if named.long.is_empty() {
continue;
}
let mut named = named.long.as_bytes().to_vec();
named.insert(0, b'-');
named.insert(0, b'-');
if named.starts_with(&prefix) {
output.push(Suggestion {
value: String::from_utf8_lossy(&named).to_string(),
description: Some(flag_desc.to_string()),
extra: None,
span: reedline::Span {
start: span.start - offset,
end: span.end - offset,
},
});
}
}
return output;
}
vec![]
}
}