mirror of
https://github.com/nushell/nushell.git
synced 2024-11-07 17:14:23 +01:00
history-menu (#846)
This commit is contained in:
parent
0cecaf82b1
commit
69954a362d
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2863,7 +2863,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "reedline"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/nushell/reedline?branch=main#7a07ab2bcca2e0287a1efcf8ccdf9845229428c5"
|
||||
source = "git+https://github.com/nushell/reedline?branch=main#d7f42e5de4aeee9332dc8eaff07e68923401edcf"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossterm",
|
||||
|
@ -17,6 +17,7 @@ pub struct NushellPrompt {
|
||||
default_vi_visual_prompt_indicator: String,
|
||||
default_menu_prompt_indicator: String,
|
||||
default_multiline_indicator: String,
|
||||
default_history_prompt_indicator: String,
|
||||
}
|
||||
|
||||
impl Default for NushellPrompt {
|
||||
@ -35,6 +36,7 @@ impl NushellPrompt {
|
||||
default_vi_visual_prompt_indicator: "v ".to_string(),
|
||||
default_menu_prompt_indicator: "| ".to_string(),
|
||||
default_multiline_indicator: "::: ".to_string(),
|
||||
default_history_prompt_indicator: "? ".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,11 +69,12 @@ impl NushellPrompt {
|
||||
left_prompt_string: Option<String>,
|
||||
right_prompt_string: Option<String>,
|
||||
prompt_indicator_string: String,
|
||||
prompt_indicator_menu: String,
|
||||
prompt_multiline_indicator_string: String,
|
||||
prompt_vi: (String, String),
|
||||
prompt_menus: (String, String),
|
||||
) {
|
||||
let (prompt_vi_insert_string, prompt_vi_visual_string) = prompt_vi;
|
||||
let (prompt_indicator_menu, prompt_history_indicator_menu) = prompt_menus;
|
||||
|
||||
self.left_prompt_string = left_prompt_string;
|
||||
self.right_prompt_string = right_prompt_string;
|
||||
@ -79,7 +82,9 @@ impl NushellPrompt {
|
||||
self.default_vi_insert_prompt_indicator = prompt_vi_insert_string;
|
||||
self.default_vi_visual_prompt_indicator = prompt_vi_visual_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 {
|
||||
@ -117,6 +122,7 @@ impl Prompt for NushellPrompt {
|
||||
},
|
||||
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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,7 @@ pub struct Config {
|
||||
pub log_level: String,
|
||||
pub menu_config: HashMap<String, Value>,
|
||||
pub keybindings: Vec<ParsedKeybinding>,
|
||||
pub history_config: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
@ -86,6 +87,7 @@ impl Default for Config {
|
||||
log_level: String::new(),
|
||||
menu_config: HashMap::new(),
|
||||
keybindings: Vec::new(),
|
||||
history_config: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -243,6 +245,13 @@ impl Value {
|
||||
eprintln!("$config.keybindings is not a valid keybindings list")
|
||||
}
|
||||
}
|
||||
"history_config" => {
|
||||
if let Ok(map) = create_map(value, &config) {
|
||||
config.history_config = map;
|
||||
} else {
|
||||
eprintln!("$config.history_config is not a record")
|
||||
}
|
||||
}
|
||||
x => {
|
||||
eprintln!("$config.{} is an unknown config setting", x)
|
||||
}
|
||||
|
@ -15,12 +15,13 @@ 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_MENU: &str = "PROMPT_INDICATOR_MENU";
|
||||
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(
|
||||
config: &Config,
|
||||
engine_state: &EngineState,
|
||||
stack: &Stack,
|
||||
) -> (String, String, String, String, String) {
|
||||
) -> (String, String, String, String, String, String) {
|
||||
let prompt_indicator = match stack.get_env_var(engine_state, PROMPT_INDICATOR) {
|
||||
Some(pi) => pi.into_string("", config),
|
||||
None => "〉".to_string(),
|
||||
@ -36,22 +37,28 @@ pub(crate) fn get_prompt_indicators(
|
||||
None => "v ".to_string(),
|
||||
};
|
||||
|
||||
let prompt_multiline = match stack.get_env_var(engine_state, PROMPT_MULTILINE_INDICATOR) {
|
||||
Some(pm) => pm.into_string("", config),
|
||||
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_multiline = match stack.get_env_var(engine_state, PROMPT_MULTILINE_INDICATOR) {
|
||||
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_vi_insert,
|
||||
prompt_vi_visual,
|
||||
prompt_menu,
|
||||
prompt_multiline,
|
||||
prompt_menu,
|
||||
prompt_history,
|
||||
)
|
||||
}
|
||||
|
||||
@ -101,8 +108,9 @@ pub(crate) fn update_prompt<'prompt>(
|
||||
prompt_indicator_string,
|
||||
prompt_vi_insert_string,
|
||||
prompt_vi_visual_string,
|
||||
prompt_indicator_menu,
|
||||
prompt_multiline_string,
|
||||
prompt_indicator_menu,
|
||||
prompt_indicator_history,
|
||||
) = get_prompt_indicators(config, engine_state, stack);
|
||||
|
||||
let mut stack = stack.clone();
|
||||
@ -112,9 +120,9 @@ pub(crate) fn update_prompt<'prompt>(
|
||||
get_prompt_string(PROMPT_COMMAND, config, engine_state, &mut stack),
|
||||
get_prompt_string(PROMPT_COMMAND_RIGHT, config, engine_state, &mut stack),
|
||||
prompt_indicator_string,
|
||||
prompt_indicator_menu,
|
||||
prompt_multiline_string,
|
||||
(prompt_vi_insert_string, prompt_vi_visual_string),
|
||||
(prompt_indicator_menu, prompt_indicator_history),
|
||||
);
|
||||
|
||||
nu_prompt as &dyn Prompt
|
||||
|
@ -3,10 +3,10 @@ use nu_color_config::lookup_ansi_color_style;
|
||||
use nu_protocol::{extract_value, Config, ParsedKeybinding, ShellError, Span, Type, Value};
|
||||
use reedline::{
|
||||
default_emacs_keybindings, default_vi_insert_keybindings, default_vi_normal_keybindings,
|
||||
ContextMenuInput, EditCommand, Keybindings, ReedlineEvent,
|
||||
ContextMenuInput, EditCommand, HistoryMenuInput, Keybindings, ReedlineEvent,
|
||||
};
|
||||
|
||||
// This 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
|
||||
pub(crate) fn create_menu_input(config: &Config) -> ContextMenuInput {
|
||||
let mut input = ContextMenuInput::default();
|
||||
@ -58,6 +58,52 @@ pub(crate) fn create_menu_input(config: &Config) -> ContextMenuInput {
|
||||
input
|
||||
}
|
||||
|
||||
// Creates an input object for the history menu based on the dictionary
|
||||
// stored in the config variable
|
||||
pub(crate) fn create_history_input(config: &Config) -> HistoryMenuInput {
|
||||
let mut input = HistoryMenuInput::default();
|
||||
|
||||
input = match config
|
||||
.history_config
|
||||
.get("page_size")
|
||||
.and_then(|value| value.as_integer().ok())
|
||||
{
|
||||
Some(value) => input.with_page_size(value as usize),
|
||||
None => input,
|
||||
};
|
||||
|
||||
input = match config
|
||||
.history_config
|
||||
.get("selector")
|
||||
.and_then(|value| value.as_string().ok())
|
||||
{
|
||||
Some(value) => {
|
||||
let char = value.chars().next().unwrap_or(':');
|
||||
input.with_row_char(char)
|
||||
}
|
||||
None => input,
|
||||
};
|
||||
|
||||
input = match config
|
||||
.history_config
|
||||
.get("text_style")
|
||||
.and_then(|value| value.as_string().ok())
|
||||
{
|
||||
Some(value) => input.with_text_style(lookup_ansi_color_style(&value)),
|
||||
None => input,
|
||||
};
|
||||
|
||||
input = match config
|
||||
.history_config
|
||||
.get("selected_text_style")
|
||||
.and_then(|value| value.as_string().ok())
|
||||
{
|
||||
Some(value) => input.with_selected_text_style(lookup_ansi_color_style(&value)),
|
||||
None => input,
|
||||
};
|
||||
|
||||
input
|
||||
}
|
||||
pub enum KeybindingsMode {
|
||||
Emacs(Keybindings),
|
||||
Vi {
|
||||
@ -215,6 +261,11 @@ fn parse_event(value: Value, config: &Config) -> Result<ReedlineEvent, ShellErro
|
||||
"menuright" => ReedlineEvent::MenuRight,
|
||||
"menunext" => ReedlineEvent::MenuNext,
|
||||
"menuprevious" => ReedlineEvent::MenuPrevious,
|
||||
"historymenu" => ReedlineEvent::HistoryMenu,
|
||||
"historymenunext" => ReedlineEvent::HistoryMenuNext,
|
||||
"historymenuprevious" => ReedlineEvent::HistoryMenuPrevious,
|
||||
"historypagenext" => ReedlineEvent::HistoryPageNext,
|
||||
"historypageprevious" => ReedlineEvent::HistoryPagePrevious,
|
||||
|
||||
// TODO: add ReedlineEvent::Mouse
|
||||
// TODO: add ReedlineEvent::Resize
|
||||
|
@ -119,7 +119,8 @@ pub(crate) fn evaluate(ctrlc: Arc<AtomicBool>, engine_state: &mut EngineState) -
|
||||
.with_menu_completer(
|
||||
Box::new(NuCompleter::new(engine_state.clone())),
|
||||
reedline_config::create_menu_input(&config),
|
||||
);
|
||||
)
|
||||
.with_history_menu(reedline_config::create_history_input(&config));
|
||||
|
||||
//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.
|
||||
|
Loading…
Reference in New Issue
Block a user