mirror of
https://github.com/nushell/nushell
synced 2024-12-28 14:03:09 +00:00
nu-cli/completions: cache layer for fetching (#5114)
This commit is contained in:
parent
5e177fe8e7
commit
e86c1b118e
2 changed files with 57 additions and 16 deletions
|
@ -9,20 +9,20 @@ use nu_protocol::{
|
|||
use reedline::Suggestion;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct CommandCompletion {
|
||||
pub struct CommandCompletion<'a> {
|
||||
engine_state: Arc<EngineState>,
|
||||
flattened: Vec<(Span, FlatShape)>,
|
||||
flattened: &'a [(Span, FlatShape)],
|
||||
flat_idx: usize,
|
||||
flat_shape: FlatShape,
|
||||
flat_shape: &'a FlatShape,
|
||||
}
|
||||
|
||||
impl CommandCompletion {
|
||||
impl<'a> CommandCompletion<'a> {
|
||||
pub fn new(
|
||||
engine_state: Arc<EngineState>,
|
||||
_: &StateWorkingSet,
|
||||
flattened: Vec<(Span, FlatShape)>,
|
||||
flattened: &'a [(Span, FlatShape)],
|
||||
flat_idx: usize,
|
||||
flat_shape: FlatShape,
|
||||
flat_shape: &'a FlatShape,
|
||||
) -> Self {
|
||||
Self {
|
||||
engine_state,
|
||||
|
@ -146,7 +146,7 @@ impl CommandCompletion {
|
|||
}
|
||||
}
|
||||
|
||||
impl Completer for CommandCompletion {
|
||||
impl<'a> Completer for CommandCompletion<'a> {
|
||||
fn fetch(
|
||||
&mut self,
|
||||
working_set: &StateWorkingSet,
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
use crate::completions::{
|
||||
CommandCompletion, Completer, CustomCompletion, FileCompletion, FlagCompletion,
|
||||
VariableCompletion,
|
||||
CommandCompletion, Completer, CompletionOptions, CustomCompletion, FileCompletion,
|
||||
FlagCompletion, VariableCompletion,
|
||||
};
|
||||
use nu_parser::{flatten_expression, parse, FlatShape};
|
||||
use nu_protocol::{
|
||||
engine::{EngineState, Stack, StateWorkingSet},
|
||||
Span, Value,
|
||||
};
|
||||
use reedline::{Completer as ReedlineCompleter, Suggestion};
|
||||
use reedline::{Completer as ReedlineCompleter, Span as ReedlineSpan, Suggestion};
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NuCompleter {
|
||||
engine_state: Arc<EngineState>,
|
||||
stack: Stack,
|
||||
config: Option<Value>,
|
||||
cached_results: Option<(Vec<Suggestion>, CompletionOptions)>,
|
||||
last_fetch: Option<Instant>,
|
||||
}
|
||||
|
||||
impl NuCompleter {
|
||||
|
@ -23,12 +26,14 @@ impl NuCompleter {
|
|||
engine_state,
|
||||
stack,
|
||||
config,
|
||||
cached_results: None,
|
||||
last_fetch: None,
|
||||
}
|
||||
}
|
||||
|
||||
// Process the completion for a given completer
|
||||
fn process_completion<T: Completer>(
|
||||
&self,
|
||||
&mut self,
|
||||
completer: &mut T,
|
||||
working_set: &StateWorkingSet,
|
||||
prefix: Vec<u8>,
|
||||
|
@ -36,9 +41,41 @@ impl NuCompleter {
|
|||
offset: usize,
|
||||
pos: usize,
|
||||
) -> Vec<Suggestion> {
|
||||
// Cleanup the result cache if it's old
|
||||
if let Some(instant) = self.last_fetch {
|
||||
if instant.elapsed() > Duration::from_millis(1000) {
|
||||
self.cached_results = None;
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch
|
||||
let (mut suggestions, options) =
|
||||
completer.fetch(working_set, prefix.clone(), new_span, offset, pos);
|
||||
let (mut suggestions, options) = match self.cached_results.clone() {
|
||||
Some((suggestions, options)) => {
|
||||
// Update cached spans
|
||||
let suggestions = suggestions
|
||||
.into_iter()
|
||||
.map(|suggestion| Suggestion {
|
||||
value: suggestion.value,
|
||||
description: suggestion.description,
|
||||
extra: suggestion.extra,
|
||||
span: ReedlineSpan {
|
||||
start: new_span.start - offset,
|
||||
end: new_span.end - offset,
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
|
||||
(suggestions, options)
|
||||
}
|
||||
None => {
|
||||
let result = completer.fetch(working_set, prefix.clone(), new_span, offset, pos);
|
||||
|
||||
// Update cache results
|
||||
self.cached_results = Some(result.clone());
|
||||
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
// Filter
|
||||
suggestions = completer.filter(prefix.clone(), suggestions, options.clone());
|
||||
|
@ -46,11 +83,15 @@ impl NuCompleter {
|
|||
// Sort
|
||||
suggestions = completer.sort(suggestions, prefix, options);
|
||||
|
||||
// Update last fetch
|
||||
self.last_fetch = Some(Instant::now());
|
||||
|
||||
suggestions
|
||||
}
|
||||
|
||||
fn completion_helper(&mut self, line: &str, pos: usize) -> Vec<Suggestion> {
|
||||
let mut working_set = StateWorkingSet::new(&self.engine_state);
|
||||
let engine_state = self.engine_state.clone();
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
let offset = working_set.next_span_start();
|
||||
let mut line = line.to_string();
|
||||
line.insert(pos, 'a');
|
||||
|
@ -143,9 +184,9 @@ impl NuCompleter {
|
|||
let mut completer = CommandCompletion::new(
|
||||
self.engine_state.clone(),
|
||||
&working_set,
|
||||
flattened.clone(),
|
||||
&flattened,
|
||||
flat_idx,
|
||||
flat_shape.clone(),
|
||||
flat_shape,
|
||||
);
|
||||
|
||||
return self.process_completion(
|
||||
|
|
Loading…
Reference in a new issue