using menu trait (#861)

This commit is contained in:
Fernando Herrera 2022-01-27 07:53:23 +00:00 committed by GitHub
parent 04395ee05c
commit 267ff4b0cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 142 additions and 107 deletions

2
Cargo.lock generated
View file

@ -2863,7 +2863,7 @@ dependencies = [
[[package]] [[package]]
name = "reedline" name = "reedline"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/nushell/reedline?branch=main#d7f42e5de4aeee9332dc8eaff07e68923401edcf" source = "git+https://github.com/nushell/reedline?branch=main#c0ec7dc2fd4181c11065f7e19c59fed2ffc83653"
dependencies = [ dependencies = [
"chrono", "chrono",
"crossterm", "crossterm",

View file

@ -14,10 +14,8 @@ pub struct NushellPrompt {
right_prompt_string: Option<String>, right_prompt_string: Option<String>,
default_prompt_indicator: String, default_prompt_indicator: String,
default_vi_insert_prompt_indicator: String, default_vi_insert_prompt_indicator: String,
default_vi_visual_prompt_indicator: String, default_vi_normal_prompt_indicator: String,
default_menu_prompt_indicator: String,
default_multiline_indicator: String, default_multiline_indicator: String,
default_history_prompt_indicator: String,
} }
impl Default for NushellPrompt { impl Default for NushellPrompt {
@ -33,10 +31,8 @@ impl NushellPrompt {
right_prompt_string: None, right_prompt_string: None,
default_prompt_indicator: "".to_string(), default_prompt_indicator: "".to_string(),
default_vi_insert_prompt_indicator: ": ".to_string(), default_vi_insert_prompt_indicator: ": ".to_string(),
default_vi_visual_prompt_indicator: "v ".to_string(), default_vi_normal_prompt_indicator: "".to_string(),
default_menu_prompt_indicator: "| ".to_string(),
default_multiline_indicator: "::: ".to_string(), default_multiline_indicator: "::: ".to_string(),
default_history_prompt_indicator: "? ".to_string(),
} }
} }
@ -56,8 +52,8 @@ impl NushellPrompt {
self.default_vi_insert_prompt_indicator = prompt_vi_insert_string; self.default_vi_insert_prompt_indicator = prompt_vi_insert_string;
} }
pub fn update_prompt_vi_visual(&mut self, prompt_vi_visual_string: String) { pub fn update_prompt_vi_normal(&mut self, prompt_vi_normal_string: String) {
self.default_vi_visual_prompt_indicator = prompt_vi_visual_string; self.default_vi_normal_prompt_indicator = prompt_vi_normal_string;
} }
pub fn update_prompt_multiline(&mut self, prompt_multiline_indicator_string: String) { pub fn update_prompt_multiline(&mut self, prompt_multiline_indicator_string: String) {
@ -71,20 +67,15 @@ impl NushellPrompt {
prompt_indicator_string: String, prompt_indicator_string: String,
prompt_multiline_indicator_string: String, prompt_multiline_indicator_string: String,
prompt_vi: (String, String), prompt_vi: (String, String),
prompt_menus: (String, String),
) { ) {
let (prompt_vi_insert_string, prompt_vi_visual_string) = prompt_vi; let (prompt_vi_insert_string, prompt_vi_normal_string) = prompt_vi;
let (prompt_indicator_menu, prompt_history_indicator_menu) = prompt_menus;
self.left_prompt_string = left_prompt_string; self.left_prompt_string = left_prompt_string;
self.right_prompt_string = right_prompt_string; self.right_prompt_string = right_prompt_string;
self.default_prompt_indicator = prompt_indicator_string; self.default_prompt_indicator = prompt_indicator_string;
self.default_vi_insert_prompt_indicator = prompt_vi_insert_string; self.default_vi_insert_prompt_indicator = prompt_vi_insert_string;
self.default_vi_visual_prompt_indicator = prompt_vi_visual_string; self.default_vi_normal_prompt_indicator = prompt_vi_normal_string;
self.default_multiline_indicator = prompt_multiline_indicator_string; self.default_multiline_indicator = prompt_multiline_indicator_string;
self.default_menu_prompt_indicator = prompt_indicator_menu;
self.default_history_prompt_indicator = prompt_history_indicator_menu;
} }
fn default_wrapped_custom_string(&self, str: String) -> String { fn default_wrapped_custom_string(&self, str: String) -> String {
@ -95,19 +86,27 @@ impl NushellPrompt {
impl Prompt for NushellPrompt { impl Prompt for NushellPrompt {
fn render_prompt_left(&self) -> Cow<str> { fn render_prompt_left(&self) -> Cow<str> {
if let Some(prompt_string) = &self.left_prompt_string { if let Some(prompt_string) = &self.left_prompt_string {
prompt_string.into() prompt_string.replace("\n", "\r\n").into()
} else { } else {
let default = DefaultPrompt::new(); let default = DefaultPrompt::new();
default.render_prompt_left().to_string().into() default
.render_prompt_left()
.to_string()
.replace("\n", "\r\n")
.into()
} }
} }
fn render_prompt_right(&self) -> Cow<str> { fn render_prompt_right(&self) -> Cow<str> {
if let Some(prompt_string) = &self.right_prompt_string { if let Some(prompt_string) = &self.right_prompt_string {
prompt_string.into() prompt_string.replace("\n", "\r\n").into()
} else { } else {
let default = DefaultPrompt::new(); let default = DefaultPrompt::new();
default.render_prompt_right().to_string().into() default
.render_prompt_right()
.to_string()
.replace("\n", "\r\n")
.into()
} }
} }
@ -116,13 +115,10 @@ impl Prompt for NushellPrompt {
PromptEditMode::Default => self.default_prompt_indicator.as_str().into(), PromptEditMode::Default => self.default_prompt_indicator.as_str().into(),
PromptEditMode::Emacs => self.default_prompt_indicator.as_str().into(), PromptEditMode::Emacs => self.default_prompt_indicator.as_str().into(),
PromptEditMode::Vi(vi_mode) => match vi_mode { PromptEditMode::Vi(vi_mode) => match vi_mode {
PromptViMode::Normal => self.default_prompt_indicator.as_str().into(), PromptViMode::Normal => self.default_vi_normal_prompt_indicator.as_str().into(),
PromptViMode::Insert => self.default_vi_insert_prompt_indicator.as_str().into(), PromptViMode::Insert => self.default_vi_insert_prompt_indicator.as_str().into(),
PromptViMode::Visual => self.default_vi_visual_prompt_indicator.as_str().into(),
}, },
PromptEditMode::Custom(str) => self.default_wrapped_custom_string(str).into(), PromptEditMode::Custom(str) => self.default_wrapped_custom_string(str).into(),
PromptEditMode::Menu => self.default_menu_prompt_indicator.as_str().into(),
PromptEditMode::HistoryMenu => self.default_history_prompt_indicator.as_str().into(),
} }
} }

View file

@ -12,16 +12,14 @@ pub(crate) const PROMPT_COMMAND: &str = "PROMPT_COMMAND";
pub(crate) const PROMPT_COMMAND_RIGHT: &str = "PROMPT_COMMAND_RIGHT"; pub(crate) const PROMPT_COMMAND_RIGHT: &str = "PROMPT_COMMAND_RIGHT";
pub(crate) const PROMPT_INDICATOR: &str = "PROMPT_INDICATOR"; pub(crate) const PROMPT_INDICATOR: &str = "PROMPT_INDICATOR";
pub(crate) const PROMPT_INDICATOR_VI_INSERT: &str = "PROMPT_INDICATOR_VI_INSERT"; pub(crate) const PROMPT_INDICATOR_VI_INSERT: &str = "PROMPT_INDICATOR_VI_INSERT";
pub(crate) const PROMPT_INDICATOR_VI_VISUAL: &str = "PROMPT_INDICATOR_VI_VISUAL"; pub(crate) const PROMPT_INDICATOR_VI_NORMAL: &str = "PROMPT_INDICATOR_VI_NORMAL";
pub(crate) const PROMPT_INDICATOR_MENU: &str = "PROMPT_INDICATOR_MENU";
pub(crate) const PROMPT_MULTILINE_INDICATOR: &str = "PROMPT_MULTILINE_INDICATOR"; pub(crate) const PROMPT_MULTILINE_INDICATOR: &str = "PROMPT_MULTILINE_INDICATOR";
pub(crate) const PROMPT_INDICATOR_HISTORY: &str = "PROMPT_INDICATOR_HISTORY";
pub(crate) fn get_prompt_indicators( pub(crate) fn get_prompt_indicators(
config: &Config, config: &Config,
engine_state: &EngineState, engine_state: &EngineState,
stack: &Stack, stack: &Stack,
) -> (String, String, String, String, String, String) { ) -> (String, String, String, String) {
let prompt_indicator = match stack.get_env_var(engine_state, PROMPT_INDICATOR) { let prompt_indicator = match stack.get_env_var(engine_state, PROMPT_INDICATOR) {
Some(pi) => pi.into_string("", config), Some(pi) => pi.into_string("", config),
None => "".to_string(), None => "".to_string(),
@ -32,9 +30,9 @@ pub(crate) fn get_prompt_indicators(
None => ": ".to_string(), None => ": ".to_string(),
}; };
let prompt_vi_visual = match stack.get_env_var(engine_state, PROMPT_INDICATOR_VI_VISUAL) { let prompt_vi_normal = match stack.get_env_var(engine_state, PROMPT_INDICATOR_VI_NORMAL) {
Some(pviv) => pviv.into_string("", config), Some(pviv) => pviv.into_string("", config),
None => "v ".to_string(), None => "".to_string(),
}; };
let prompt_multiline = match stack.get_env_var(engine_state, PROMPT_MULTILINE_INDICATOR) { let prompt_multiline = match stack.get_env_var(engine_state, PROMPT_MULTILINE_INDICATOR) {
@ -42,23 +40,11 @@ pub(crate) fn get_prompt_indicators(
None => "::: ".to_string(), None => "::: ".to_string(),
}; };
let prompt_menu = match stack.get_env_var(engine_state, PROMPT_INDICATOR_MENU) {
Some(pm) => pm.into_string("", config),
None => "| ".to_string(),
};
let prompt_history = match stack.get_env_var(engine_state, PROMPT_INDICATOR_HISTORY) {
Some(ph) => ph.into_string("", config),
None => "? ".to_string(),
};
( (
prompt_indicator, prompt_indicator,
prompt_vi_insert, prompt_vi_insert,
prompt_vi_visual, prompt_vi_normal,
prompt_multiline, prompt_multiline,
prompt_menu,
prompt_history,
) )
} }
@ -107,10 +93,8 @@ pub(crate) fn update_prompt<'prompt>(
let ( let (
prompt_indicator_string, prompt_indicator_string,
prompt_vi_insert_string, prompt_vi_insert_string,
prompt_vi_visual_string, prompt_vi_normal_string,
prompt_multiline_string, prompt_multiline_string,
prompt_indicator_menu,
prompt_indicator_history,
) = get_prompt_indicators(config, engine_state, stack); ) = get_prompt_indicators(config, engine_state, stack);
let mut stack = stack.clone(); let mut stack = stack.clone();
@ -121,8 +105,7 @@ pub(crate) fn update_prompt<'prompt>(
get_prompt_string(PROMPT_COMMAND_RIGHT, config, engine_state, &mut stack), get_prompt_string(PROMPT_COMMAND_RIGHT, config, engine_state, &mut stack),
prompt_indicator_string, prompt_indicator_string,
prompt_multiline_string, prompt_multiline_string,
(prompt_vi_insert_string, prompt_vi_visual_string), (prompt_vi_insert_string, prompt_vi_normal_string),
(prompt_indicator_menu, prompt_indicator_history),
); );
nu_prompt as &dyn Prompt nu_prompt as &dyn Prompt

View file

@ -1,26 +1,34 @@
use crossterm::event::{KeyCode, KeyModifiers}; use crossterm::event::{KeyCode, KeyModifiers};
use nu_cli::NuCompleter;
use nu_color_config::lookup_ansi_color_style; use nu_color_config::lookup_ansi_color_style;
use nu_protocol::{extract_value, Config, ParsedKeybinding, ShellError, Span, Type, Value}; use nu_protocol::{
engine::EngineState, extract_value, Config, ParsedKeybinding, ShellError, Span, Type, Value,
};
use reedline::{ use reedline::{
default_emacs_keybindings, default_vi_insert_keybindings, default_vi_normal_keybindings, default_emacs_keybindings, default_vi_insert_keybindings, default_vi_normal_keybindings,
ContextMenuInput, EditCommand, HistoryMenuInput, Keybindings, ReedlineEvent, ContextMenu, EditCommand, HistoryMenu, Keybindings, Reedline, ReedlineEvent,
}; };
// Creates an input object for the context menu based on the dictionary // Creates an input object for the context menu based on the dictionary
// stored in the config variable // stored in the config variable
pub(crate) fn create_menu_input(config: &Config) -> ContextMenuInput { pub(crate) fn add_context_menu(
let mut input = ContextMenuInput::default(); line_editor: Reedline,
engine_state: &EngineState,
config: &Config,
) -> Reedline {
let mut context_menu = ContextMenu::default();
context_menu = context_menu.with_completer(Box::new(NuCompleter::new(engine_state.clone())));
input = match config context_menu = match config
.menu_config .menu_config
.get("columns") .get("columns")
.and_then(|value| value.as_integer().ok()) .and_then(|value| value.as_integer().ok())
{ {
Some(value) => input.with_columns(value as u16), Some(value) => context_menu.with_columns(value as u16),
None => input, None => context_menu,
}; };
input = input.with_col_width( context_menu = context_menu.with_column_width(
config config
.menu_config .menu_config
.get("col_width") .get("col_width")
@ -28,82 +36,133 @@ pub(crate) fn create_menu_input(config: &Config) -> ContextMenuInput {
.map(|value| value as usize), .map(|value| value as usize),
); );
input = match config context_menu = match config
.menu_config .menu_config
.get("col_padding") .get("col_padding")
.and_then(|value| value.as_integer().ok()) .and_then(|value| value.as_integer().ok())
{ {
Some(value) => input.with_col_padding(value as usize), Some(value) => context_menu.with_column_padding(value as usize),
None => input, None => context_menu,
}; };
input = match config context_menu = match config
.menu_config .menu_config
.get("text_style") .get("text_style")
.and_then(|value| value.as_string().ok()) .and_then(|value| value.as_string().ok())
{ {
Some(value) => input.with_text_style(lookup_ansi_color_style(&value)), Some(value) => context_menu.with_text_style(lookup_ansi_color_style(&value)),
None => input, None => context_menu,
}; };
input = match config context_menu = match config
.menu_config .menu_config
.get("selected_text_style") .get("selected_text_style")
.and_then(|value| value.as_string().ok()) .and_then(|value| value.as_string().ok())
{ {
Some(value) => input.with_selected_text_style(lookup_ansi_color_style(&value)), Some(value) => context_menu.with_selected_text_style(lookup_ansi_color_style(&value)),
None => input, None => context_menu,
}; };
input context_menu = match config
.menu_config
.get("marker")
.and_then(|value| value.as_string().ok())
{
Some(value) => context_menu.with_marker(value),
None => context_menu,
};
line_editor.with_menu(Box::new(context_menu))
} }
// Creates an input object for the history menu based on the dictionary // Creates an input object for the history menu based on the dictionary
// stored in the config variable // stored in the config variable
pub(crate) fn create_history_input(config: &Config) -> HistoryMenuInput { pub(crate) fn add_history_menu(line_editor: Reedline, config: &Config) -> Reedline {
let mut input = HistoryMenuInput::default(); let mut history_menu = HistoryMenu::default();
input = match config history_menu = match config
.history_config .history_config
.get("page_size") .get("page_size")
.and_then(|value| value.as_integer().ok()) .and_then(|value| value.as_integer().ok())
{ {
Some(value) => input.with_page_size(value as usize), Some(value) => history_menu.with_page_size(value as usize),
None => input, None => history_menu,
}; };
input = match config history_menu = match config
.history_config .history_config
.get("selector") .get("selector")
.and_then(|value| value.as_string().ok()) .and_then(|value| value.as_string().ok())
{ {
Some(value) => { Some(value) => {
let char = value.chars().next().unwrap_or(':'); let char = value.chars().next().unwrap_or(':');
input.with_row_char(char) history_menu.with_row_char(char)
} }
None => input, None => history_menu,
}; };
input = match config history_menu = match config
.history_config .history_config
.get("text_style") .get("text_style")
.and_then(|value| value.as_string().ok()) .and_then(|value| value.as_string().ok())
{ {
Some(value) => input.with_text_style(lookup_ansi_color_style(&value)), Some(value) => history_menu.with_text_style(lookup_ansi_color_style(&value)),
None => input, None => history_menu,
}; };
input = match config history_menu = match config
.history_config .history_config
.get("selected_text_style") .get("selected_text_style")
.and_then(|value| value.as_string().ok()) .and_then(|value| value.as_string().ok())
{ {
Some(value) => input.with_selected_text_style(lookup_ansi_color_style(&value)), Some(value) => history_menu.with_selected_text_style(lookup_ansi_color_style(&value)),
None => input, None => history_menu,
}; };
input history_menu = match config
.history_config
.get("marker")
.and_then(|value| value.as_string().ok())
{
Some(value) => history_menu.with_marker(value),
None => history_menu,
};
line_editor.with_menu(Box::new(history_menu))
} }
fn add_menu_keybindings(keybindings: &mut Keybindings) {
keybindings.add_binding(
KeyModifiers::CONTROL,
KeyCode::Char('i'),
ReedlineEvent::UntilFound(vec![
ReedlineEvent::Menu("history_menu".to_string()),
ReedlineEvent::MenuPageNext,
]),
);
keybindings.add_binding(
KeyModifiers::CONTROL | KeyModifiers::SHIFT,
KeyCode::Char('i'),
ReedlineEvent::MenuPagePrevious,
);
keybindings.add_binding(
KeyModifiers::NONE,
KeyCode::Tab,
ReedlineEvent::UntilFound(vec![
ReedlineEvent::Menu("context_menu".to_string()),
ReedlineEvent::MenuNext,
]),
);
keybindings.add_binding(
KeyModifiers::SHIFT,
KeyCode::BackTab,
ReedlineEvent::MenuPrevious,
);
}
pub enum KeybindingsMode { pub enum KeybindingsMode {
Emacs(Keybindings), Emacs(Keybindings),
Vi { Vi {
@ -117,6 +176,8 @@ pub(crate) fn create_keybindings(config: &Config) -> Result<KeybindingsMode, She
match config.edit_mode.as_str() { match config.edit_mode.as_str() {
"emacs" => { "emacs" => {
let mut keybindings = default_emacs_keybindings(); let mut keybindings = default_emacs_keybindings();
add_menu_keybindings(&mut keybindings);
// temporal keybinding with multiple events // temporal keybinding with multiple events
keybindings.add_binding( keybindings.add_binding(
KeyModifiers::SHIFT, KeyModifiers::SHIFT,
@ -139,6 +200,9 @@ pub(crate) fn create_keybindings(config: &Config) -> Result<KeybindingsMode, She
let mut insert_keybindings = default_vi_insert_keybindings(); let mut insert_keybindings = default_vi_insert_keybindings();
let mut normal_keybindings = default_vi_normal_keybindings(); let mut normal_keybindings = default_vi_normal_keybindings();
add_menu_keybindings(&mut insert_keybindings);
add_menu_keybindings(&mut normal_keybindings);
for parsed_keybinding in parsed_keybindings { for parsed_keybinding in parsed_keybindings {
if parsed_keybinding.mode.into_string("", config).as_str() == "vi_insert" { if parsed_keybinding.mode.into_string("", config).as_str() == "vi_insert" {
add_keybinding(&mut insert_keybindings, parsed_keybinding, config)? add_keybinding(&mut insert_keybindings, parsed_keybinding, config)?
@ -254,28 +318,27 @@ fn parse_event(value: Value, config: &Config) -> Result<ReedlineEvent, ShellErro
"nexthistory" => ReedlineEvent::NextHistory, "nexthistory" => ReedlineEvent::NextHistory,
"previoushistory" => ReedlineEvent::PreviousHistory, "previoushistory" => ReedlineEvent::PreviousHistory,
"repaint" => ReedlineEvent::Repaint, "repaint" => ReedlineEvent::Repaint,
"contextmenu" => ReedlineEvent::ContextMenu,
"menudown" => ReedlineEvent::MenuDown, "menudown" => ReedlineEvent::MenuDown,
"menuup" => ReedlineEvent::MenuUp, "menuup" => ReedlineEvent::MenuUp,
"menuleft" => ReedlineEvent::MenuLeft, "menuleft" => ReedlineEvent::MenuLeft,
"menuright" => ReedlineEvent::MenuRight, "menuright" => ReedlineEvent::MenuRight,
"menunext" => ReedlineEvent::MenuNext, "menunext" => ReedlineEvent::MenuNext,
"menuprevious" => ReedlineEvent::MenuPrevious, "menuprevious" => ReedlineEvent::MenuPrevious,
"historymenu" => ReedlineEvent::HistoryMenu, "menupagenext" => ReedlineEvent::MenuPageNext,
"historymenunext" => ReedlineEvent::HistoryMenuNext, "menupageprevious" => ReedlineEvent::MenuPagePrevious,
"historymenuprevious" => ReedlineEvent::HistoryMenuPrevious, "menu" => {
"historypagenext" => ReedlineEvent::HistoryPageNext, let menu = extract_value("name", &cols, &vals, &span)?;
"historypageprevious" => ReedlineEvent::HistoryPagePrevious, ReedlineEvent::Menu(menu.into_string("", config))
}
// TODO: add ReedlineEvent::Mouse
// TODO: add ReedlineEvent::Resize
// TODO: add ReedlineEvent::Paste
"edit" => { "edit" => {
let edit = extract_value("edit", &cols, &vals, &span)?; let edit = extract_value("edit", &cols, &vals, &span)?;
let edit = parse_edit(edit, config)?; let edit = parse_edit(edit, config)?;
ReedlineEvent::Edit(vec![edit]) ReedlineEvent::Edit(vec![edit])
} }
// TODO: add ReedlineEvent::Mouse
// TODO: add ReedlineEvent::Resize
// TODO: add ReedlineEvent::Paste
v => { v => {
return Err(ShellError::UnsupportedConfigValue( return Err(ShellError::UnsupportedConfigValue(
"Reedline event".to_string(), "Reedline event".to_string(),

View file

@ -1,5 +1,6 @@
use std::{sync::atomic::Ordering, time::Instant}; use std::{sync::atomic::Ordering, time::Instant};
use crate::reedline_config::{add_context_menu, add_history_menu};
use crate::{config_files, prompt_update, reedline_config}; use crate::{config_files, prompt_update, reedline_config};
use crate::{ use crate::{
reedline_config::KeybindingsMode, reedline_config::KeybindingsMode,
@ -7,7 +8,7 @@ use crate::{
}; };
use log::trace; use log::trace;
use miette::{IntoDiagnostic, Result}; use miette::{IntoDiagnostic, Result};
use nu_cli::{NuCompleter, NuHighlighter, NuValidator, NushellPrompt}; use nu_cli::{NuHighlighter, NuValidator, NushellPrompt};
use nu_color_config::get_color_config; use nu_color_config::get_color_config;
use nu_engine::convert_env_values; use nu_engine::convert_env_values;
use nu_parser::lex; use nu_parser::lex;
@ -95,14 +96,8 @@ pub(crate) fn evaluate(engine_state: &mut EngineState) -> Result<()> {
ctrlc.store(false, Ordering::SeqCst); ctrlc.store(false, Ordering::SeqCst);
} }
let line_editor = Reedline::create() let mut line_editor = Reedline::create()
.into_diagnostic()? .into_diagnostic()?
// .with_completion_action_handler(Box::new(fuzzy_completion::FuzzyCompletion {
// completer: Box::new(NuCompleter::new(engine_state.clone())),
// }))
// .with_completion_action_handler(Box::new(
// ListCompletionHandler::default().with_completer(Box::new(completer)),
// ))
.with_highlighter(Box::new(NuHighlighter { .with_highlighter(Box::new(NuHighlighter {
engine_state: engine_state.clone(), engine_state: engine_state.clone(),
config: config.clone(), config: config.clone(),
@ -111,19 +106,17 @@ pub(crate) fn evaluate(engine_state: &mut EngineState) -> Result<()> {
.with_validator(Box::new(NuValidator { .with_validator(Box::new(NuValidator {
engine_state: engine_state.clone(), engine_state: engine_state.clone(),
})) }))
.with_ansi_colors(config.use_ansi_coloring) .with_ansi_colors(config.use_ansi_coloring);
.with_menu_completer(
Box::new(NuCompleter::new(engine_state.clone())), line_editor = add_context_menu(line_editor, engine_state, &config);
reedline_config::create_menu_input(&config), line_editor = add_history_menu(line_editor, &config);
)
.with_history_menu(reedline_config::create_history_input(&config));
//FIXME: if config.use_ansi_coloring is false then we should //FIXME: if config.use_ansi_coloring is false then we should
// turn off the hinter but I don't see any way to do that yet. // turn off the hinter but I don't see any way to do that yet.
let color_hm = get_color_config(&config); let color_hm = get_color_config(&config);
let line_editor = if let Some(history_path) = history_path.clone() { line_editor = if let Some(history_path) = history_path.clone() {
let history = std::fs::read_to_string(&history_path); let history = std::fs::read_to_string(&history_path);
if history.is_ok() { if history.is_ok() {
line_editor line_editor
@ -146,7 +139,7 @@ pub(crate) fn evaluate(engine_state: &mut EngineState) -> Result<()> {
}; };
// Changing the line editor based on the found keybindings // Changing the line editor based on the found keybindings
let mut line_editor = match reedline_config::create_keybindings(&config) { line_editor = match reedline_config::create_keybindings(&config) {
Ok(keybindings) => match keybindings { Ok(keybindings) => match keybindings {
KeybindingsMode::Emacs(keybindings) => { KeybindingsMode::Emacs(keybindings) => {
let edit_mode = Box::new(Emacs::new(keybindings)); let edit_mode = Box::new(Emacs::new(keybindings));