mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 03:34:58 +02:00
Generic menus (#5085)
* updated to reedline generic menus * help menu with examples * generic menus in the engine * description menu template * list of menus in config * default value for menu * menu from block * generic menus examples * change to reedline git path * cargo fmt * menu name typo * remove commas from default file * added error message
This commit is contained in:
@ -13,6 +13,17 @@ pub struct ParsedKeybinding {
|
||||
pub mode: Value,
|
||||
}
|
||||
|
||||
/// Definition of a parsed menu from the config object
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ParsedMenu {
|
||||
pub name: Value,
|
||||
pub marker: Value,
|
||||
pub only_buffer_difference: Value,
|
||||
pub style: Value,
|
||||
pub menu_type: Value,
|
||||
pub source: Value,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Config {
|
||||
pub filesize_metric: bool,
|
||||
@ -31,10 +42,8 @@ pub struct Config {
|
||||
pub max_history_size: i64,
|
||||
pub sync_history_on_enter: bool,
|
||||
pub log_level: String,
|
||||
pub menu_config: HashMap<String, Value>,
|
||||
pub keybindings: Vec<ParsedKeybinding>,
|
||||
pub history_config: HashMap<String, Value>,
|
||||
pub help_config: HashMap<String, Value>,
|
||||
pub menus: Vec<ParsedMenu>,
|
||||
pub rm_always_trash: bool,
|
||||
}
|
||||
|
||||
@ -57,10 +66,8 @@ impl Default for Config {
|
||||
max_history_size: 1000,
|
||||
sync_history_on_enter: true,
|
||||
log_level: String::new(),
|
||||
menu_config: HashMap::new(),
|
||||
history_config: HashMap::new(),
|
||||
help_config: HashMap::new(),
|
||||
keybindings: Vec::new(),
|
||||
menus: Vec::new(),
|
||||
rm_always_trash: false,
|
||||
}
|
||||
}
|
||||
@ -215,34 +222,20 @@ impl Value {
|
||||
eprintln!("$config.log_level is not a string")
|
||||
}
|
||||
}
|
||||
"menu_config" => {
|
||||
if let Ok(map) = create_map(value, &config) {
|
||||
config.menu_config = map;
|
||||
} else {
|
||||
eprintln!("$config.menu_config is not a record")
|
||||
"menus" => match create_menus(value, &config) {
|
||||
Ok(map) => config.menus = map,
|
||||
Err(e) => {
|
||||
eprintln!("$config.menus is not a valid list of menus");
|
||||
eprintln!("{:?}", e);
|
||||
}
|
||||
}
|
||||
"history_config" => {
|
||||
if let Ok(map) = create_map(value, &config) {
|
||||
config.history_config = map;
|
||||
} else {
|
||||
eprintln!("$config.history_config is not a record")
|
||||
},
|
||||
"keybindings" => match create_keybindings(value, &config) {
|
||||
Ok(keybindings) => config.keybindings = keybindings,
|
||||
Err(e) => {
|
||||
eprintln!("$config.keybindings is not a valid keybindings list");
|
||||
eprintln!("{:?}", e);
|
||||
}
|
||||
}
|
||||
"help_config" => {
|
||||
if let Ok(map) = create_map(value, &config) {
|
||||
config.help_config = map;
|
||||
} else {
|
||||
eprintln!("$config.help_config is not a record")
|
||||
}
|
||||
}
|
||||
"keybindings" => {
|
||||
if let Ok(keybindings) = create_keybindings(value, &config) {
|
||||
config.keybindings = keybindings;
|
||||
} else {
|
||||
eprintln!("$config.keybindings is not a valid keybindings list")
|
||||
}
|
||||
}
|
||||
},
|
||||
x => {
|
||||
eprintln!("$config.{} is an unknown config setting", x)
|
||||
}
|
||||
@ -310,18 +303,19 @@ fn create_keybindings(value: &Value, config: &Config) -> Result<Vec<ParsedKeybin
|
||||
match value {
|
||||
Value::Record { cols, vals, span } => {
|
||||
// Finding the modifier value in the record
|
||||
let modifier = extract_value("modifier", cols, vals, span)?;
|
||||
let keycode = extract_value("keycode", cols, vals, span)?;
|
||||
let mode = extract_value("mode", cols, vals, span)?;
|
||||
let event = extract_value("event", cols, vals, span)?;
|
||||
let modifier = extract_value("modifier", cols, vals, span)?.clone();
|
||||
let keycode = extract_value("keycode", cols, vals, span)?.clone();
|
||||
let mode = extract_value("mode", cols, vals, span)?.clone();
|
||||
let event = extract_value("event", cols, vals, span)?.clone();
|
||||
|
||||
let keybinding = ParsedKeybinding {
|
||||
modifier: modifier.clone(),
|
||||
keycode: keycode.clone(),
|
||||
mode: mode.clone(),
|
||||
event: event.clone(),
|
||||
modifier,
|
||||
keycode,
|
||||
mode,
|
||||
event,
|
||||
};
|
||||
|
||||
// We return a menu to be able to do recursion on the same function
|
||||
Ok(vec![keybinding])
|
||||
}
|
||||
Value::List { vals, .. } => {
|
||||
@ -341,6 +335,49 @@ fn create_keybindings(value: &Value, config: &Config) -> Result<Vec<ParsedKeybin
|
||||
}
|
||||
}
|
||||
|
||||
// Parses the config object to extract the strings that will compose a keybinding for reedline
|
||||
pub fn create_menus(value: &Value, config: &Config) -> Result<Vec<ParsedMenu>, ShellError> {
|
||||
match value {
|
||||
Value::Record { cols, vals, span } => {
|
||||
// Finding the modifier value in the record
|
||||
let name = extract_value("name", cols, vals, span)?.clone();
|
||||
let marker = extract_value("marker", cols, vals, span)?.clone();
|
||||
let only_buffer_difference =
|
||||
extract_value("only_buffer_difference", cols, vals, span)?.clone();
|
||||
let style = extract_value("style", cols, vals, span)?.clone();
|
||||
let menu_type = extract_value("type", cols, vals, span)?.clone();
|
||||
|
||||
// Source is an optional value
|
||||
let source = match extract_value("source", cols, vals, span) {
|
||||
Ok(source) => source.clone(),
|
||||
Err(_) => Value::Nothing { span: *span },
|
||||
};
|
||||
|
||||
let menu = ParsedMenu {
|
||||
name,
|
||||
only_buffer_difference,
|
||||
marker,
|
||||
style,
|
||||
menu_type,
|
||||
source,
|
||||
};
|
||||
|
||||
Ok(vec![menu])
|
||||
}
|
||||
Value::List { vals, .. } => {
|
||||
let res = vals
|
||||
.iter()
|
||||
.map(|inner_value| create_menus(inner_value, config))
|
||||
.collect::<Result<Vec<Vec<ParsedMenu>>, ShellError>>();
|
||||
|
||||
let res = res?.into_iter().flatten().collect::<Vec<ParsedMenu>>();
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
_ => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_value<'record>(
|
||||
name: &str,
|
||||
cols: &'record [String],
|
||||
|
Reference in New Issue
Block a user