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 reedline::Suggestion;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct CommandCompletion {
|
pub struct CommandCompletion<'a> {
|
||||||
engine_state: Arc<EngineState>,
|
engine_state: Arc<EngineState>,
|
||||||
flattened: Vec<(Span, FlatShape)>,
|
flattened: &'a [(Span, FlatShape)],
|
||||||
flat_idx: usize,
|
flat_idx: usize,
|
||||||
flat_shape: FlatShape,
|
flat_shape: &'a FlatShape,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandCompletion {
|
impl<'a> CommandCompletion<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
engine_state: Arc<EngineState>,
|
engine_state: Arc<EngineState>,
|
||||||
_: &StateWorkingSet,
|
_: &StateWorkingSet,
|
||||||
flattened: Vec<(Span, FlatShape)>,
|
flattened: &'a [(Span, FlatShape)],
|
||||||
flat_idx: usize,
|
flat_idx: usize,
|
||||||
flat_shape: FlatShape,
|
flat_shape: &'a FlatShape,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
engine_state,
|
engine_state,
|
||||||
|
@ -146,7 +146,7 @@ impl CommandCompletion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Completer for CommandCompletion {
|
impl<'a> Completer for CommandCompletion<'a> {
|
||||||
fn fetch(
|
fn fetch(
|
||||||
&mut self,
|
&mut self,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
|
|
|
@ -1,20 +1,23 @@
|
||||||
use crate::completions::{
|
use crate::completions::{
|
||||||
CommandCompletion, Completer, CustomCompletion, FileCompletion, FlagCompletion,
|
CommandCompletion, Completer, CompletionOptions, CustomCompletion, FileCompletion,
|
||||||
VariableCompletion,
|
FlagCompletion, VariableCompletion,
|
||||||
};
|
};
|
||||||
use nu_parser::{flatten_expression, parse, FlatShape};
|
use nu_parser::{flatten_expression, parse, FlatShape};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
engine::{EngineState, Stack, StateWorkingSet},
|
engine::{EngineState, Stack, StateWorkingSet},
|
||||||
Span, Value,
|
Span, Value,
|
||||||
};
|
};
|
||||||
use reedline::{Completer as ReedlineCompleter, Suggestion};
|
use reedline::{Completer as ReedlineCompleter, Span as ReedlineSpan, Suggestion};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct NuCompleter {
|
pub struct NuCompleter {
|
||||||
engine_state: Arc<EngineState>,
|
engine_state: Arc<EngineState>,
|
||||||
stack: Stack,
|
stack: Stack,
|
||||||
config: Option<Value>,
|
config: Option<Value>,
|
||||||
|
cached_results: Option<(Vec<Suggestion>, CompletionOptions)>,
|
||||||
|
last_fetch: Option<Instant>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NuCompleter {
|
impl NuCompleter {
|
||||||
|
@ -23,12 +26,14 @@ impl NuCompleter {
|
||||||
engine_state,
|
engine_state,
|
||||||
stack,
|
stack,
|
||||||
config,
|
config,
|
||||||
|
cached_results: None,
|
||||||
|
last_fetch: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the completion for a given completer
|
// Process the completion for a given completer
|
||||||
fn process_completion<T: Completer>(
|
fn process_completion<T: Completer>(
|
||||||
&self,
|
&mut self,
|
||||||
completer: &mut T,
|
completer: &mut T,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
prefix: Vec<u8>,
|
prefix: Vec<u8>,
|
||||||
|
@ -36,9 +41,41 @@ impl NuCompleter {
|
||||||
offset: usize,
|
offset: usize,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
) -> Vec<Suggestion> {
|
) -> 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
|
// Fetch
|
||||||
let (mut suggestions, options) =
|
let (mut suggestions, options) = match self.cached_results.clone() {
|
||||||
completer.fetch(working_set, prefix.clone(), new_span, offset, pos);
|
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
|
// Filter
|
||||||
suggestions = completer.filter(prefix.clone(), suggestions, options.clone());
|
suggestions = completer.filter(prefix.clone(), suggestions, options.clone());
|
||||||
|
@ -46,11 +83,15 @@ impl NuCompleter {
|
||||||
// Sort
|
// Sort
|
||||||
suggestions = completer.sort(suggestions, prefix, options);
|
suggestions = completer.sort(suggestions, prefix, options);
|
||||||
|
|
||||||
|
// Update last fetch
|
||||||
|
self.last_fetch = Some(Instant::now());
|
||||||
|
|
||||||
suggestions
|
suggestions
|
||||||
}
|
}
|
||||||
|
|
||||||
fn completion_helper(&mut self, line: &str, pos: usize) -> Vec<Suggestion> {
|
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 offset = working_set.next_span_start();
|
||||||
let mut line = line.to_string();
|
let mut line = line.to_string();
|
||||||
line.insert(pos, 'a');
|
line.insert(pos, 'a');
|
||||||
|
@ -143,9 +184,9 @@ impl NuCompleter {
|
||||||
let mut completer = CommandCompletion::new(
|
let mut completer = CommandCompletion::new(
|
||||||
self.engine_state.clone(),
|
self.engine_state.clone(),
|
||||||
&working_set,
|
&working_set,
|
||||||
flattened.clone(),
|
&flattened,
|
||||||
flat_idx,
|
flat_idx,
|
||||||
flat_shape.clone(),
|
flat_shape,
|
||||||
);
|
);
|
||||||
|
|
||||||
return self.process_completion(
|
return self.process_completion(
|
||||||
|
|
Loading…
Reference in a new issue