use nu_ansi_term::Style;
use std::ops::Range;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub struct Span {
pub start: usize,
pub end: usize,
}
impl Span {
pub fn new(start: usize, end: usize) -> Span {
assert!(
end >= start,
"Can't create a Span whose end < start, start={start}, end={end}"
);
Span { start, end }
}
}
pub trait Completer: Send {
fn complete(&mut self, line: &str, pos: usize) -> Vec<Suggestion>;
fn complete_with_base_ranges(
&mut self,
line: &str,
pos: usize,
) -> (Vec<Suggestion>, Vec<Range<usize>>) {
let mut ranges = vec![];
let suggestions = self.complete(line, pos);
for suggestion in &suggestions {
ranges.push(suggestion.span.start..suggestion.span.end);
}
ranges.dedup();
(suggestions, ranges)
}
fn partial_complete(
&mut self,
line: &str,
pos: usize,
start: usize,
offset: usize,
) -> Vec<Suggestion> {
self.complete(line, pos)
.into_iter()
.skip(start)
.take(offset)
.collect()
}
fn total_completions(&mut self, line: &str, pos: usize) -> usize {
self.complete(line, pos).len()
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct Suggestion {
pub value: String,
pub display_override: Option<String>,
pub description: Option<String>,
pub style: Option<Style>,
pub extra: Option<Vec<String>>,
pub span: Span,
pub append_whitespace: bool,
pub match_indices: Option<Vec<usize>>,
}
impl Suggestion {
pub fn display_value(&self) -> &str {
self.display_override.as_ref().unwrap_or(&self.value)
}
}