forked from extern/nushell
use arc to avoid cloning entire engine for menus (#5104)
* use arc to avoid cloning entire engine for menus * remove complete import path * remove stack clone * reference in completer
This commit is contained in:
parent
13869e7d52
commit
3ceb39c82c
@ -44,7 +44,7 @@ pub trait Completer {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort is results using the completion options
|
// Sort results using the completion options
|
||||||
fn sort(
|
fn sort(
|
||||||
&self,
|
&self,
|
||||||
items: Vec<Suggestion>,
|
items: Vec<Suggestion>,
|
||||||
|
@ -7,9 +7,10 @@ use nu_protocol::{
|
|||||||
Span,
|
Span,
|
||||||
};
|
};
|
||||||
use reedline::Suggestion;
|
use reedline::Suggestion;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct CommandCompletion {
|
pub struct CommandCompletion {
|
||||||
engine_state: EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
flattened: Vec<(Span, FlatShape)>,
|
flattened: Vec<(Span, FlatShape)>,
|
||||||
flat_idx: usize,
|
flat_idx: usize,
|
||||||
flat_shape: FlatShape,
|
flat_shape: FlatShape,
|
||||||
@ -17,7 +18,7 @@ pub struct CommandCompletion {
|
|||||||
|
|
||||||
impl CommandCompletion {
|
impl CommandCompletion {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
engine_state: EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
_: &StateWorkingSet,
|
_: &StateWorkingSet,
|
||||||
flattened: Vec<(Span, FlatShape)>,
|
flattened: Vec<(Span, FlatShape)>,
|
||||||
flat_idx: usize,
|
flat_idx: usize,
|
||||||
|
@ -8,16 +8,17 @@ use nu_protocol::{
|
|||||||
Span, Value,
|
Span, Value,
|
||||||
};
|
};
|
||||||
use reedline::{Completer as ReedlineCompleter, Suggestion};
|
use reedline::{Completer as ReedlineCompleter, Suggestion};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct NuCompleter {
|
pub struct NuCompleter {
|
||||||
engine_state: EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
stack: Stack,
|
stack: Stack,
|
||||||
config: Option<Value>,
|
config: Option<Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NuCompleter {
|
impl NuCompleter {
|
||||||
pub fn new(engine_state: EngineState, stack: Stack, config: Option<Value>) -> Self {
|
pub fn new(engine_state: Arc<EngineState>, stack: Stack, config: Option<Value>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
engine_state,
|
engine_state,
|
||||||
stack,
|
stack,
|
||||||
|
@ -6,9 +6,10 @@ use nu_protocol::{
|
|||||||
PipelineData, Span, Type, Value, CONFIG_VARIABLE_ID,
|
PipelineData, Span, Type, Value, CONFIG_VARIABLE_ID,
|
||||||
};
|
};
|
||||||
use reedline::Suggestion;
|
use reedline::Suggestion;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct CustomCompletion {
|
pub struct CustomCompletion {
|
||||||
engine_state: EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
stack: Stack,
|
stack: Stack,
|
||||||
config: Option<Value>,
|
config: Option<Value>,
|
||||||
decl_id: usize,
|
decl_id: usize,
|
||||||
@ -17,7 +18,7 @@ pub struct CustomCompletion {
|
|||||||
|
|
||||||
impl CustomCompletion {
|
impl CustomCompletion {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
engine_state: EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
stack: Stack,
|
stack: Stack,
|
||||||
config: Option<Value>,
|
config: Option<Value>,
|
||||||
decl_id: usize,
|
decl_id: usize,
|
||||||
|
@ -5,16 +5,17 @@ use nu_protocol::{
|
|||||||
};
|
};
|
||||||
use reedline::Suggestion;
|
use reedline::Suggestion;
|
||||||
use std::path::{is_separator, Path};
|
use std::path::{is_separator, Path};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
const SEP: char = std::path::MAIN_SEPARATOR;
|
const SEP: char = std::path::MAIN_SEPARATOR;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FileCompletion {
|
pub struct FileCompletion {
|
||||||
engine_state: EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileCompletion {
|
impl FileCompletion {
|
||||||
pub fn new(engine_state: EngineState) -> Self {
|
pub fn new(engine_state: Arc<EngineState>) -> Self {
|
||||||
Self { engine_state }
|
Self { engine_state }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,16 @@ use nu_protocol::{
|
|||||||
engine::{EngineState, StateWorkingSet},
|
engine::{EngineState, StateWorkingSet},
|
||||||
Span,
|
Span,
|
||||||
};
|
};
|
||||||
|
|
||||||
use reedline::Suggestion;
|
use reedline::Suggestion;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct VariableCompletion {
|
pub struct VariableCompletion {
|
||||||
engine_state: EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VariableCompletion {
|
impl VariableCompletion {
|
||||||
pub fn new(engine_state: EngineState) -> Self {
|
pub fn new(engine_state: Arc<EngineState>) -> Self {
|
||||||
Self { engine_state }
|
Self { engine_state }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use nu_engine::documentation::get_flags_section;
|
use nu_engine::documentation::get_flags_section;
|
||||||
use nu_protocol::{engine::EngineState, levenshtein_distance};
|
use nu_protocol::{engine::EngineState, levenshtein_distance};
|
||||||
use reedline::{Completer, Suggestion};
|
use reedline::{Completer, Suggestion};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct NuHelpCompleter(EngineState);
|
pub struct NuHelpCompleter(Arc<EngineState>);
|
||||||
|
|
||||||
impl NuHelpCompleter {
|
impl NuHelpCompleter {
|
||||||
pub fn new(engine_state: EngineState) -> Self {
|
pub fn new(engine_state: Arc<EngineState>) -> Self {
|
||||||
Self(engine_state)
|
Self(engine_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ use nu_protocol::{
|
|||||||
IntoPipelineData, Span, Value,
|
IntoPipelineData, Span, Value,
|
||||||
};
|
};
|
||||||
use reedline::{menu_functions::parse_selection_char, Completer, Suggestion};
|
use reedline::{menu_functions::parse_selection_char, Completer, Suggestion};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
const SELECTION_CHAR: char = '!';
|
const SELECTION_CHAR: char = '!';
|
||||||
|
|
||||||
@ -11,7 +12,7 @@ pub struct NuMenuCompleter {
|
|||||||
block_id: usize,
|
block_id: usize,
|
||||||
span: Span,
|
span: Span,
|
||||||
stack: Stack,
|
stack: Stack,
|
||||||
engine_state: EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
only_buffer_difference: bool,
|
only_buffer_difference: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ impl NuMenuCompleter {
|
|||||||
block_id: usize,
|
block_id: usize,
|
||||||
span: Span,
|
span: Span,
|
||||||
stack: Stack,
|
stack: Stack,
|
||||||
engine_state: EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
only_buffer_difference: bool,
|
only_buffer_difference: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -38,7 +39,6 @@ impl Completer for NuMenuCompleter {
|
|||||||
let parsed = parse_selection_char(line, SELECTION_CHAR);
|
let parsed = parse_selection_char(line, SELECTION_CHAR);
|
||||||
|
|
||||||
let block = self.engine_state.get_block(self.block_id);
|
let block = self.engine_state.get_block(self.block_id);
|
||||||
let mut stack = self.stack.clone();
|
|
||||||
|
|
||||||
if let Some(buffer) = block.signature.get_positional(0) {
|
if let Some(buffer) = block.signature.get_positional(0) {
|
||||||
if let Some(buffer_id) = &buffer.var_id {
|
if let Some(buffer_id) = &buffer.var_id {
|
||||||
@ -46,7 +46,7 @@ impl Completer for NuMenuCompleter {
|
|||||||
val: parsed.remainder.to_string(),
|
val: parsed.remainder.to_string(),
|
||||||
span: self.span,
|
span: self.span,
|
||||||
};
|
};
|
||||||
stack.add_var(*buffer_id, line_buffer);
|
self.stack.add_var(*buffer_id, line_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,12 +56,19 @@ impl Completer for NuMenuCompleter {
|
|||||||
val: pos as i64,
|
val: pos as i64,
|
||||||
span: self.span,
|
span: self.span,
|
||||||
};
|
};
|
||||||
stack.add_var(*position_id, line_buffer);
|
self.stack.add_var(*position_id, line_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let input = Value::nothing(self.span).into_pipeline_data();
|
let input = Value::nothing(self.span).into_pipeline_data();
|
||||||
let res = eval_block(&self.engine_state, &mut stack, block, input, false, false);
|
let res = eval_block(
|
||||||
|
&self.engine_state,
|
||||||
|
&mut self.stack,
|
||||||
|
block,
|
||||||
|
input,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
if let Ok(values) = res {
|
if let Ok(values) = res {
|
||||||
let values = values.into_value(self.span);
|
let values = values.into_value(self.span);
|
||||||
|
@ -14,6 +14,7 @@ use reedline::{
|
|||||||
default_emacs_keybindings, default_vi_insert_keybindings, default_vi_normal_keybindings,
|
default_emacs_keybindings, default_vi_insert_keybindings, default_vi_normal_keybindings,
|
||||||
ColumnarMenu, EditCommand, Keybindings, ListMenu, Reedline, ReedlineEvent, ReedlineMenu,
|
ColumnarMenu, EditCommand, Keybindings, ListMenu, Reedline, ReedlineEvent, ReedlineMenu,
|
||||||
};
|
};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
const DEFAULT_COMPLETION_MENU: &str = r#"
|
const DEFAULT_COMPLETION_MENU: &str = r#"
|
||||||
{
|
{
|
||||||
@ -72,14 +73,14 @@ const DEFAULT_HELP_MENU: &str = r#"
|
|||||||
// Adds all menus to line editor
|
// Adds all menus to line editor
|
||||||
pub(crate) fn add_menus(
|
pub(crate) fn add_menus(
|
||||||
mut line_editor: Reedline,
|
mut line_editor: Reedline,
|
||||||
engine_state: &EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
) -> Result<Reedline, ShellError> {
|
) -> Result<Reedline, ShellError> {
|
||||||
line_editor = line_editor.clear_menus();
|
line_editor = line_editor.clear_menus();
|
||||||
|
|
||||||
for menu in &config.menus {
|
for menu in &config.menus {
|
||||||
line_editor = add_menu(line_editor, menu, engine_state, stack, config)?
|
line_editor = add_menu(line_editor, menu, engine_state.clone(), stack, config)?
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checking if the default menus have been added from the config file
|
// Checking if the default menus have been added from the config file
|
||||||
@ -96,7 +97,7 @@ pub(crate) fn add_menus(
|
|||||||
.any(|menu| menu.name.into_string("", config) == name)
|
.any(|menu| menu.name.into_string("", config) == name)
|
||||||
{
|
{
|
||||||
let (block, _) = {
|
let (block, _) = {
|
||||||
let mut working_set = StateWorkingSet::new(engine_state);
|
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||||
let (output, _) = parse(
|
let (output, _) = parse(
|
||||||
&mut working_set,
|
&mut working_set,
|
||||||
Some(name), // format!("entry #{}", entry_num)
|
Some(name), // format!("entry #{}", entry_num)
|
||||||
@ -110,11 +111,12 @@ pub(crate) fn add_menus(
|
|||||||
|
|
||||||
let mut temp_stack = Stack::new();
|
let mut temp_stack = Stack::new();
|
||||||
let input = Value::nothing(Span::test_data()).into_pipeline_data();
|
let input = Value::nothing(Span::test_data()).into_pipeline_data();
|
||||||
let res = eval_block(engine_state, &mut temp_stack, &block, input, false, false)?;
|
let res = eval_block(&engine_state, &mut temp_stack, &block, input, false, false)?;
|
||||||
|
|
||||||
if let PipelineData::Value(value, None) = res {
|
if let PipelineData::Value(value, None) = res {
|
||||||
for menu in create_menus(&value, config)? {
|
for menu in create_menus(&value, config)? {
|
||||||
line_editor = add_menu(line_editor, &menu, engine_state, stack, config)?;
|
line_editor =
|
||||||
|
add_menu(line_editor, &menu, engine_state.clone(), stack, config)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,7 +128,7 @@ pub(crate) fn add_menus(
|
|||||||
fn add_menu(
|
fn add_menu(
|
||||||
line_editor: Reedline,
|
line_editor: Reedline,
|
||||||
menu: &ParsedMenu,
|
menu: &ParsedMenu,
|
||||||
engine_state: &EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
) -> Result<Reedline, ShellError> {
|
) -> Result<Reedline, ShellError> {
|
||||||
@ -176,7 +178,7 @@ macro_rules! add_style {
|
|||||||
pub(crate) fn add_columnar_menu(
|
pub(crate) fn add_columnar_menu(
|
||||||
line_editor: Reedline,
|
line_editor: Reedline,
|
||||||
menu: &ParsedMenu,
|
menu: &ParsedMenu,
|
||||||
engine_state: &EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
) -> Result<Reedline, ShellError> {
|
) -> Result<Reedline, ShellError> {
|
||||||
@ -258,7 +260,7 @@ pub(crate) fn add_columnar_menu(
|
|||||||
*val,
|
*val,
|
||||||
*span,
|
*span,
|
||||||
stack.captures_to_stack(captures),
|
stack.captures_to_stack(captures),
|
||||||
engine_state.clone(),
|
engine_state,
|
||||||
only_buffer_difference,
|
only_buffer_difference,
|
||||||
);
|
);
|
||||||
Ok(line_editor.with_menu(ReedlineMenu::WithCompleter {
|
Ok(line_editor.with_menu(ReedlineMenu::WithCompleter {
|
||||||
@ -278,7 +280,7 @@ pub(crate) fn add_columnar_menu(
|
|||||||
pub(crate) fn add_list_menu(
|
pub(crate) fn add_list_menu(
|
||||||
line_editor: Reedline,
|
line_editor: Reedline,
|
||||||
menu: &ParsedMenu,
|
menu: &ParsedMenu,
|
||||||
engine_state: &EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
) -> Result<Reedline, ShellError> {
|
) -> Result<Reedline, ShellError> {
|
||||||
@ -344,7 +346,7 @@ pub(crate) fn add_list_menu(
|
|||||||
*val,
|
*val,
|
||||||
*span,
|
*span,
|
||||||
stack.captures_to_stack(captures),
|
stack.captures_to_stack(captures),
|
||||||
engine_state.clone(),
|
engine_state,
|
||||||
only_buffer_difference,
|
only_buffer_difference,
|
||||||
);
|
);
|
||||||
Ok(line_editor.with_menu(ReedlineMenu::WithCompleter {
|
Ok(line_editor.with_menu(ReedlineMenu::WithCompleter {
|
||||||
@ -364,7 +366,7 @@ pub(crate) fn add_list_menu(
|
|||||||
pub(crate) fn add_description_menu(
|
pub(crate) fn add_description_menu(
|
||||||
line_editor: Reedline,
|
line_editor: Reedline,
|
||||||
menu: &ParsedMenu,
|
menu: &ParsedMenu,
|
||||||
engine_state: &EngineState,
|
engine_state: Arc<EngineState>,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
) -> Result<Reedline, ShellError> {
|
) -> Result<Reedline, ShellError> {
|
||||||
@ -451,7 +453,7 @@ pub(crate) fn add_description_menu(
|
|||||||
|
|
||||||
match &menu.source {
|
match &menu.source {
|
||||||
Value::Nothing { .. } => {
|
Value::Nothing { .. } => {
|
||||||
let completer = Box::new(NuHelpCompleter::new(engine_state.clone()));
|
let completer = Box::new(NuHelpCompleter::new(engine_state));
|
||||||
Ok(line_editor.with_menu(ReedlineMenu::WithCompleter {
|
Ok(line_editor.with_menu(ReedlineMenu::WithCompleter {
|
||||||
menu: Box::new(description_menu),
|
menu: Box::new(description_menu),
|
||||||
completer,
|
completer,
|
||||||
@ -466,7 +468,7 @@ pub(crate) fn add_description_menu(
|
|||||||
*val,
|
*val,
|
||||||
*span,
|
*span,
|
||||||
stack.captures_to_stack(captures),
|
stack.captures_to_stack(captures),
|
||||||
engine_state.clone(),
|
engine_state,
|
||||||
only_buffer_difference,
|
only_buffer_difference,
|
||||||
);
|
);
|
||||||
Ok(line_editor.with_menu(ReedlineMenu::WithCompleter {
|
Ok(line_editor.with_menu(ReedlineMenu::WithCompleter {
|
||||||
|
@ -169,6 +169,7 @@ pub fn evaluate_repl(
|
|||||||
ctrlc.store(false, Ordering::SeqCst);
|
ctrlc.store(false, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let engine_reference = std::sync::Arc::new(engine_state.clone());
|
||||||
line_editor = line_editor
|
line_editor = line_editor
|
||||||
.with_highlighter(Box::new(NuHighlighter {
|
.with_highlighter(Box::new(NuHighlighter {
|
||||||
engine_state: engine_state.clone(),
|
engine_state: engine_state.clone(),
|
||||||
@ -182,7 +183,7 @@ pub fn evaluate_repl(
|
|||||||
DefaultHinter::default().with_style(color_hm["hints"]),
|
DefaultHinter::default().with_style(color_hm["hints"]),
|
||||||
))
|
))
|
||||||
.with_completer(Box::new(NuCompleter::new(
|
.with_completer(Box::new(NuCompleter::new(
|
||||||
engine_state.clone(),
|
engine_reference.clone(),
|
||||||
stack.clone(),
|
stack.clone(),
|
||||||
stack.vars.get(&CONFIG_VARIABLE_ID).cloned(),
|
stack.vars.get(&CONFIG_VARIABLE_ID).cloned(),
|
||||||
)))
|
)))
|
||||||
@ -194,7 +195,7 @@ pub fn evaluate_repl(
|
|||||||
info!("update reedline {}:{}:{}", file!(), line!(), column!());
|
info!("update reedline {}:{}:{}", file!(), line!(), column!());
|
||||||
}
|
}
|
||||||
|
|
||||||
line_editor = match add_menus(line_editor, engine_state, stack, &config) {
|
line_editor = match add_menus(line_editor, engine_reference, stack, &config) {
|
||||||
Ok(line_editor) => line_editor,
|
Ok(line_editor) => line_editor,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let working_set = StateWorkingSet::new(engine_state);
|
let working_set = StateWorkingSet::new(engine_state);
|
||||||
|
Loading…
Reference in New Issue
Block a user