mirror of
https://github.com/nushell/nushell.git
synced 2024-11-21 16:03:19 +01:00
Use IntoValue
in config code (#13751)
# Description Cleans up and refactors the config code using the `IntoValue` macro. Shoutout to @cptpiepmatz for making the macro! # User-Facing Changes Should be none. # After Submitting Somehow refactor the reverse transformation.
This commit is contained in:
parent
4792328d0e
commit
abd230e12e
@ -55,7 +55,7 @@ impl Command for History {
|
||||
HistoryFileFormat::Sqlite => {
|
||||
history_path.push("history.sqlite3");
|
||||
}
|
||||
HistoryFileFormat::PlainText => {
|
||||
HistoryFileFormat::Plaintext => {
|
||||
history_path.push("history.txt");
|
||||
}
|
||||
}
|
||||
@ -75,7 +75,7 @@ impl Command for History {
|
||||
.ok()
|
||||
}
|
||||
|
||||
HistoryFileFormat::PlainText => FileBackedHistory::with_file(
|
||||
HistoryFileFormat::Plaintext => FileBackedHistory::with_file(
|
||||
history.max_size as usize,
|
||||
history_path.clone().into(),
|
||||
)
|
||||
@ -87,7 +87,7 @@ impl Command for History {
|
||||
};
|
||||
|
||||
match history.file_format {
|
||||
HistoryFileFormat::PlainText => Ok(history_reader
|
||||
HistoryFileFormat::Plaintext => Ok(history_reader
|
||||
.and_then(|h| {
|
||||
h.search(SearchQuery::everything(SearchDirection::Forward, None))
|
||||
.ok()
|
||||
|
@ -51,7 +51,9 @@ impl CommandCompletion {
|
||||
if working_set
|
||||
.permanent_state
|
||||
.config
|
||||
.max_external_completion_results
|
||||
.completions
|
||||
.external
|
||||
.max_results
|
||||
> executables.len() as i64
|
||||
&& !executables.contains(
|
||||
&item
|
||||
@ -211,7 +213,7 @@ impl Completer for CommandCompletion {
|
||||
working_set,
|
||||
span,
|
||||
offset,
|
||||
config.enable_external_completion,
|
||||
config.completions.external.enable,
|
||||
options.match_algorithm,
|
||||
)
|
||||
} else {
|
||||
|
@ -46,9 +46,9 @@ impl NuCompleter {
|
||||
let config = self.engine_state.get_config();
|
||||
|
||||
let options = CompletionOptions {
|
||||
case_sensitive: config.case_sensitive_completions,
|
||||
match_algorithm: config.completion_algorithm.into(),
|
||||
sort: config.completion_sort,
|
||||
case_sensitive: config.completions.case_sensitive,
|
||||
match_algorithm: config.completions.algorithm.into(),
|
||||
sort: config.completions.sort,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@ -208,7 +208,7 @@ impl NuCompleter {
|
||||
|
||||
// We got no results for internal completion
|
||||
// now we can check if external completer is set and use it
|
||||
if let Some(closure) = config.external_completer.as_ref() {
|
||||
if let Some(closure) = config.completions.external.completer.as_ref() {
|
||||
if let Some(external_result) =
|
||||
self.external_completion(closure, &spans, fake_offset, new_span)
|
||||
{
|
||||
@ -338,7 +338,9 @@ impl NuCompleter {
|
||||
}
|
||||
|
||||
// Try to complete using an external completer (if set)
|
||||
if let Some(closure) = config.external_completer.as_ref() {
|
||||
if let Some(closure) =
|
||||
config.completions.external.completer.as_ref()
|
||||
{
|
||||
if let Some(external_result) = self.external_completion(
|
||||
closure,
|
||||
&spans,
|
||||
|
@ -167,7 +167,7 @@ pub fn complete_item(
|
||||
.rfind(|c: &char| is_separator(*c))
|
||||
.unwrap_or(SEP);
|
||||
let cwd_pathbuf = Path::new(cwd).to_path_buf();
|
||||
let ls_colors = (engine_state.config.use_ls_colors_completions
|
||||
let ls_colors = (engine_state.config.completions.use_ls_colors
|
||||
&& engine_state.config.use_ansi_coloring)
|
||||
.then(|| {
|
||||
let ls_colors_env_str = match stack.get_env_var(engine_state, "LS_COLORS") {
|
||||
|
@ -245,7 +245,7 @@ pub(crate) fn get_history_path(storage_path: &str, mode: HistoryFileFormat) -> O
|
||||
nu_path::config_dir().map(|mut history_path| {
|
||||
history_path.push(storage_path);
|
||||
history_path.push(match mode {
|
||||
HistoryFileFormat::PlainText => HISTORY_FILE_TXT,
|
||||
HistoryFileFormat::Plaintext => HISTORY_FILE_TXT,
|
||||
HistoryFileFormat::Sqlite => HISTORY_FILE_SQLITE,
|
||||
});
|
||||
history_path.into()
|
||||
|
@ -53,7 +53,7 @@ pub fn evaluate_commands(
|
||||
// Parse the source code
|
||||
let (block, delta) = {
|
||||
if let Some(ref t_mode) = table_mode {
|
||||
Arc::make_mut(&mut engine_state.config).table_mode =
|
||||
Arc::make_mut(&mut engine_state.config).table.mode =
|
||||
t_mode.coerce_str()?.parse().unwrap_or_default();
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ pub fn evaluate_commands(
|
||||
}
|
||||
|
||||
if let Some(t_mode) = table_mode {
|
||||
Arc::make_mut(&mut engine_state.config).table_mode =
|
||||
Arc::make_mut(&mut engine_state.config).table.mode =
|
||||
t_mode.coerce_str()?.parse().unwrap_or_default();
|
||||
}
|
||||
|
||||
|
@ -118,13 +118,13 @@ pub(crate) fn update_prompt(
|
||||
|
||||
// Now that we have the prompt string lets ansify it.
|
||||
// <133 A><prompt><133 B><command><133 C><command output>
|
||||
let left_prompt_string = if config.shell_integration_osc633 {
|
||||
let left_prompt_string = if config.shell_integration.osc633 {
|
||||
if stack.get_env_var(engine_state, "TERM_PROGRAM") == Some(Value::test_string("vscode")) {
|
||||
// We're in vscode and we have osc633 enabled
|
||||
Some(format!(
|
||||
"{VSCODE_PRE_PROMPT_MARKER}{configured_left_prompt_string}{VSCODE_POST_PROMPT_MARKER}"
|
||||
))
|
||||
} else if config.shell_integration_osc133 {
|
||||
} else if config.shell_integration.osc133 {
|
||||
// If we're in VSCode but we don't find the env var, but we have osc133 set, then use it
|
||||
Some(format!(
|
||||
"{PRE_PROMPT_MARKER}{configured_left_prompt_string}{POST_PROMPT_MARKER}"
|
||||
@ -132,7 +132,7 @@ pub(crate) fn update_prompt(
|
||||
} else {
|
||||
configured_left_prompt_string.into()
|
||||
}
|
||||
} else if config.shell_integration_osc133 {
|
||||
} else if config.shell_integration.osc133 {
|
||||
Some(format!(
|
||||
"{PRE_PROMPT_MARKER}{configured_left_prompt_string}{POST_PROMPT_MARKER}"
|
||||
))
|
||||
|
@ -159,8 +159,8 @@ fn add_menu(
|
||||
stack: &Stack,
|
||||
config: Arc<Config>,
|
||||
) -> Result<Reedline, ShellError> {
|
||||
let span = menu.menu_type.span();
|
||||
if let Value::Record { val, .. } = &menu.menu_type {
|
||||
let span = menu.r#type.span();
|
||||
if let Value::Record { val, .. } = &menu.r#type {
|
||||
let layout = extract_value("layout", val, span)?.to_expanded_string("", &config);
|
||||
|
||||
match layout.as_str() {
|
||||
@ -170,15 +170,15 @@ fn add_menu(
|
||||
"description" => add_description_menu(line_editor, menu, engine_state, stack, config),
|
||||
_ => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "columnar, list, ide or description".to_string(),
|
||||
value: menu.menu_type.to_abbreviated_string(&config),
|
||||
span: menu.menu_type.span(),
|
||||
value: menu.r#type.to_abbreviated_string(&config),
|
||||
span: menu.r#type.span(),
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "only record type".to_string(),
|
||||
value: menu.menu_type.to_abbreviated_string(&config),
|
||||
span: menu.menu_type.span(),
|
||||
value: menu.r#type.to_abbreviated_string(&config),
|
||||
span: menu.r#type.span(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -224,11 +224,11 @@ pub(crate) fn add_columnar_menu(
|
||||
stack: &Stack,
|
||||
config: &Config,
|
||||
) -> Result<Reedline, ShellError> {
|
||||
let span = menu.menu_type.span();
|
||||
let span = menu.r#type.span();
|
||||
let name = menu.name.to_expanded_string("", config);
|
||||
let mut columnar_menu = ColumnarMenu::default().with_name(&name);
|
||||
|
||||
if let Value::Record { val, .. } = &menu.menu_type {
|
||||
if let Value::Record { val, .. } = &menu.r#type {
|
||||
columnar_menu = match extract_value("columns", val, span) {
|
||||
Ok(columns) => {
|
||||
let columns = columns.as_int()?;
|
||||
@ -299,8 +299,8 @@ pub(crate) fn add_list_menu(
|
||||
let name = menu.name.to_expanded_string("", &config);
|
||||
let mut list_menu = ListMenu::default().with_name(&name);
|
||||
|
||||
let span = menu.menu_type.span();
|
||||
if let Value::Record { val, .. } = &menu.menu_type {
|
||||
let span = menu.r#type.span();
|
||||
if let Value::Record { val, .. } = &menu.r#type {
|
||||
list_menu = match extract_value("page_size", val, span) {
|
||||
Ok(page_size) => {
|
||||
let page_size = page_size.as_int()?;
|
||||
@ -352,11 +352,11 @@ pub(crate) fn add_ide_menu(
|
||||
stack: &Stack,
|
||||
config: Arc<Config>,
|
||||
) -> Result<Reedline, ShellError> {
|
||||
let span = menu.menu_type.span();
|
||||
let span = menu.r#type.span();
|
||||
let name = menu.name.to_expanded_string("", &config);
|
||||
let mut ide_menu = IdeMenu::default().with_name(&name);
|
||||
|
||||
if let Value::Record { val, .. } = &menu.menu_type {
|
||||
if let Value::Record { val, .. } = &menu.r#type {
|
||||
ide_menu = match extract_value("min_completion_width", val, span) {
|
||||
Ok(min_completion_width) => {
|
||||
let min_completion_width = min_completion_width.as_int()?;
|
||||
@ -536,8 +536,8 @@ pub(crate) fn add_description_menu(
|
||||
let name = menu.name.to_expanded_string("", &config);
|
||||
let mut description_menu = DescriptionMenu::default().with_name(&name);
|
||||
|
||||
let span = menu.menu_type.span();
|
||||
if let Value::Record { val, .. } = &menu.menu_type {
|
||||
let span = menu.r#type.span();
|
||||
if let Value::Record { val, .. } = &menu.r#type {
|
||||
description_menu = match extract_value("columns", val, span) {
|
||||
Ok(columns) => {
|
||||
let columns = columns.as_int()?;
|
||||
|
@ -72,11 +72,11 @@ pub fn evaluate_repl(
|
||||
let mut entry_num = 0;
|
||||
|
||||
// Let's grab the shell_integration configs
|
||||
let shell_integration_osc2 = config.shell_integration_osc2;
|
||||
let shell_integration_osc7 = config.shell_integration_osc7;
|
||||
let shell_integration_osc9_9 = config.shell_integration_osc9_9;
|
||||
let shell_integration_osc133 = config.shell_integration_osc133;
|
||||
let shell_integration_osc633 = config.shell_integration_osc633;
|
||||
let shell_integration_osc2 = config.shell_integration.osc2;
|
||||
let shell_integration_osc7 = config.shell_integration.osc7;
|
||||
let shell_integration_osc9_9 = config.shell_integration.osc9_9;
|
||||
let shell_integration_osc133 = config.shell_integration.osc133;
|
||||
let shell_integration_osc633 = config.shell_integration.osc633;
|
||||
|
||||
let nu_prompt = NushellPrompt::new(
|
||||
shell_integration_osc133,
|
||||
@ -322,9 +322,9 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) {
|
||||
start_time = std::time::Instant::now();
|
||||
// Find the configured cursor shapes for each mode
|
||||
let cursor_config = CursorConfig {
|
||||
vi_insert: map_nucursorshape_to_cursorshape(config.cursor_shape_vi_insert),
|
||||
vi_normal: map_nucursorshape_to_cursorshape(config.cursor_shape_vi_normal),
|
||||
emacs: map_nucursorshape_to_cursorshape(config.cursor_shape_emacs),
|
||||
vi_insert: map_nucursorshape_to_cursorshape(config.cursor_shape.vi_insert),
|
||||
vi_normal: map_nucursorshape_to_cursorshape(config.cursor_shape.vi_normal),
|
||||
emacs: map_nucursorshape_to_cursorshape(config.cursor_shape.emacs),
|
||||
};
|
||||
perf!("get config/cursor config", start_time, use_color);
|
||||
|
||||
@ -352,8 +352,8 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) {
|
||||
// STACK-REFERENCE 2
|
||||
stack_arc.clone(),
|
||||
)))
|
||||
.with_quick_completions(config.quick_completions)
|
||||
.with_partial_completions(config.partial_completions)
|
||||
.with_quick_completions(config.completions.quick)
|
||||
.with_partial_completions(config.completions.partial)
|
||||
.with_ansi_colors(config.use_ansi_coloring)
|
||||
.with_cwd(Some(
|
||||
engine_state
|
||||
@ -457,12 +457,12 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) {
|
||||
.with_completer(Box::<DefaultCompleter>::default());
|
||||
|
||||
// Let's grab the shell_integration configs
|
||||
let shell_integration_osc2 = config.shell_integration_osc2;
|
||||
let shell_integration_osc7 = config.shell_integration_osc7;
|
||||
let shell_integration_osc9_9 = config.shell_integration_osc9_9;
|
||||
let shell_integration_osc133 = config.shell_integration_osc133;
|
||||
let shell_integration_osc633 = config.shell_integration_osc633;
|
||||
let shell_integration_reset_application_mode = config.shell_integration_reset_application_mode;
|
||||
let shell_integration_osc2 = config.shell_integration.osc2;
|
||||
let shell_integration_osc7 = config.shell_integration.osc7;
|
||||
let shell_integration_osc9_9 = config.shell_integration.osc9_9;
|
||||
let shell_integration_osc133 = config.shell_integration.osc133;
|
||||
let shell_integration_osc633 = config.shell_integration.osc633;
|
||||
let shell_integration_reset_application_mode = config.shell_integration.reset_application_mode;
|
||||
|
||||
// TODO: we may clone the stack, this can lead to major performance issues
|
||||
// so we should avoid it or making stack cheaper to clone.
|
||||
@ -1173,7 +1173,7 @@ fn update_line_editor_history(
|
||||
history_session_id: Option<HistorySessionId>,
|
||||
) -> Result<Reedline, ErrReport> {
|
||||
let history: Box<dyn reedline::History> = match history.file_format {
|
||||
HistoryFileFormat::PlainText => Box::new(
|
||||
HistoryFileFormat::Plaintext => Box::new(
|
||||
FileBackedHistory::with_file(history.max_size as usize, history_path)
|
||||
.into_diagnostic()?,
|
||||
),
|
||||
@ -1211,10 +1211,10 @@ fn confirm_stdin_is_terminal() -> Result<()> {
|
||||
fn map_nucursorshape_to_cursorshape(shape: NuCursorShape) -> Option<SetCursorStyle> {
|
||||
match shape {
|
||||
NuCursorShape::Block => Some(SetCursorStyle::SteadyBlock),
|
||||
NuCursorShape::UnderScore => Some(SetCursorStyle::SteadyUnderScore),
|
||||
NuCursorShape::Underscore => Some(SetCursorStyle::SteadyUnderScore),
|
||||
NuCursorShape::Line => Some(SetCursorStyle::SteadyBar),
|
||||
NuCursorShape::BlinkBlock => Some(SetCursorStyle::BlinkingBlock),
|
||||
NuCursorShape::BlinkUnderScore => Some(SetCursorStyle::BlinkingUnderScore),
|
||||
NuCursorShape::BlinkUnderscore => Some(SetCursorStyle::BlinkingUnderScore),
|
||||
NuCursorShape::BlinkLine => Some(SetCursorStyle::BlinkingBar),
|
||||
NuCursorShape::Inherit => None,
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ fn rm(
|
||||
}
|
||||
|
||||
let span = call.head;
|
||||
let rm_always_trash = stack.get_config(engine_state).rm_always_trash;
|
||||
let rm_always_trash = stack.get_config(engine_state).rm.always_trash;
|
||||
|
||||
if !TRASH_SUPPORTED {
|
||||
if rm_always_trash {
|
||||
|
@ -258,7 +258,7 @@ fn parse_table_config(
|
||||
let flatten_separator: Option<String> = call.get_flag(state, stack, "flatten-separator")?;
|
||||
let abbrivation: Option<usize> = call
|
||||
.get_flag(state, stack, "abbreviated")?
|
||||
.or_else(|| stack.get_config(state).table_abbreviation_threshold);
|
||||
.or_else(|| stack.get_config(state).table.abbreviated_row_count);
|
||||
let table_view = match (expand, collapse) {
|
||||
(false, false) => TableView::General,
|
||||
(_, true) => TableView::Collapsed,
|
||||
@ -269,7 +269,7 @@ fn parse_table_config(
|
||||
},
|
||||
};
|
||||
let theme =
|
||||
get_theme_flag(call, state, stack)?.unwrap_or_else(|| stack.get_config(state).table_mode);
|
||||
get_theme_flag(call, state, stack)?.unwrap_or_else(|| stack.get_config(state).table.mode);
|
||||
let index = get_index_flag(call, state, stack)?;
|
||||
|
||||
let term_width = get_width_param(width_param);
|
||||
@ -520,7 +520,7 @@ fn handle_record(
|
||||
}
|
||||
}
|
||||
|
||||
let indent = (config.table_indent.left, config.table_indent.right);
|
||||
let indent = (config.table.padding.left, config.table.padding.right);
|
||||
let opts = TableOpts::new(
|
||||
&config,
|
||||
styles,
|
||||
@ -821,7 +821,7 @@ impl PagingTableCreator {
|
||||
self.engine_state.signals(),
|
||||
self.head,
|
||||
self.cfg.term_width,
|
||||
(cfg.table_indent.left, cfg.table_indent.right),
|
||||
(cfg.table.padding.left, cfg.table.padding.right),
|
||||
self.cfg.theme,
|
||||
self.cfg.index.unwrap_or(0) + self.row_offset,
|
||||
self.cfg.index.is_none(),
|
||||
@ -1010,7 +1010,7 @@ fn render_path_name(
|
||||
ls_colors: &LsColors,
|
||||
span: Span,
|
||||
) -> Option<Value> {
|
||||
if !config.use_ls_colors {
|
||||
if !config.ls.use_ls_colors {
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -1024,10 +1024,10 @@ fn render_path_name(
|
||||
// clickable links don't work in remote SSH sessions
|
||||
let in_ssh_session = std::env::var("SSH_CLIENT").is_ok();
|
||||
//TODO: Deprecated show_clickable_links_in_ls in favor of shell_integration_osc8
|
||||
let show_clickable_links = config.show_clickable_links_in_ls
|
||||
let show_clickable_links = config.ls.clickable_links
|
||||
&& !in_ssh_session
|
||||
&& has_metadata
|
||||
&& config.shell_integration_osc8;
|
||||
&& config.shell_integration.osc8;
|
||||
|
||||
let ansi_style = style.map(Style::to_nu_ansi_term_style).unwrap_or_default();
|
||||
|
||||
@ -1074,7 +1074,7 @@ fn create_empty_placeholder(
|
||||
stack: &Stack,
|
||||
) -> String {
|
||||
let config = stack.get_config(engine_state);
|
||||
if !config.table_show_empty {
|
||||
if !config.table.show_empty {
|
||||
return String::new();
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ fn derive_struct_from_value(
|
||||
/// .remove("favorite_toy")
|
||||
/// .map(|v| <#ty as nu_protocol::FromValue>::from_value(v))
|
||||
/// .transpose()?
|
||||
/// .flatten(),
|
||||
/// .flatten(),
|
||||
/// })
|
||||
/// }
|
||||
/// }
|
||||
@ -491,7 +491,7 @@ fn enum_from_value(data: &DataEnum, attrs: &[Attribute]) -> Result {
|
||||
}
|
||||
|
||||
/// Implements `FromValue::expected_type` for enums.
|
||||
///
|
||||
///
|
||||
/// Since it's difficult to name the type of an enum in the current type system, we want to use the
|
||||
/// default implementation if `#[nu_value(type_name = "...")]` was *not* given.
|
||||
/// For that, a `None` value is returned, for a passed type name we return something like this:
|
||||
|
@ -1,5 +1,6 @@
|
||||
use proc_macro2::Span;
|
||||
use std::collections::HashMap;
|
||||
use syn::ext::IdentExt;
|
||||
use syn::Ident;
|
||||
|
||||
use crate::attributes::{ContainerAttributes, MemberAttributes};
|
||||
@ -33,18 +34,17 @@ impl NameResolver {
|
||||
/// If a duplicate identifier is detected, it returns [`DeriveError::NonUniqueName`].
|
||||
pub fn resolve_ident<M>(
|
||||
&mut self,
|
||||
ident: &'_ Ident,
|
||||
container_attrs: &'_ ContainerAttributes,
|
||||
member_attrs: &'_ MemberAttributes,
|
||||
ident: &Ident,
|
||||
container_attrs: &ContainerAttributes,
|
||||
member_attrs: &MemberAttributes,
|
||||
default: impl Into<Option<Case>>,
|
||||
) -> Result<String, DeriveError<M>> {
|
||||
let span = ident.span();
|
||||
let rename_all = container_attrs.rename_all;
|
||||
let rename = member_attrs.rename.as_ref();
|
||||
let ident = match (rename, rename_all) {
|
||||
(Some(rename), _) => rename.to_string(),
|
||||
(None, Some(case)) => ident.to_case(case),
|
||||
(None, None) => ident.to_case(default),
|
||||
let ident = if let Some(rename) = &member_attrs.rename {
|
||||
rename.clone()
|
||||
} else {
|
||||
let case = container_attrs.rename_all.or(default.into());
|
||||
ident.unraw().to_case(case)
|
||||
};
|
||||
|
||||
if let Some(seen) = self.seen_names.get(&ident) {
|
||||
|
@ -177,8 +177,8 @@ impl ExploreConfig {
|
||||
pub fn from_nu_config(config: &Config) -> Self {
|
||||
let mut ret = Self::default();
|
||||
|
||||
ret.table.column_padding_left = config.table_indent.left;
|
||||
ret.table.column_padding_right = config.table_indent.right;
|
||||
ret.table.column_padding_left = config.table.padding.left;
|
||||
ret.table.column_padding_right = config.table.padding.right;
|
||||
|
||||
let explore_cfg_hash_map = config.explore.clone();
|
||||
let colors = get_color_map(&explore_cfg_hash_map);
|
||||
|
@ -36,8 +36,8 @@ fn try_build_map(
|
||||
signals,
|
||||
Span::unknown(),
|
||||
usize::MAX,
|
||||
(config.table_indent.left, config.table_indent.right),
|
||||
config.table_mode,
|
||||
(config.table.padding.left, config.table.padding.right),
|
||||
config.table.mode,
|
||||
0,
|
||||
false,
|
||||
);
|
||||
@ -63,8 +63,8 @@ fn try_build_list(
|
||||
signals,
|
||||
Span::unknown(),
|
||||
usize::MAX,
|
||||
(config.table_indent.left, config.table_indent.right),
|
||||
config.table_mode,
|
||||
(config.table.padding.left, config.table.padding.right),
|
||||
config.table.mode,
|
||||
0,
|
||||
false,
|
||||
);
|
||||
|
@ -1,12 +1,8 @@
|
||||
use std::str::FromStr;
|
||||
use super::prelude::*;
|
||||
use crate as nu_protocol;
|
||||
use crate::engine::Closure;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{record, Config, Span, Value};
|
||||
|
||||
use super::helper::ReconstructVal;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, Default)]
|
||||
#[derive(Clone, Copy, Debug, Default, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum CompletionAlgorithm {
|
||||
#[default]
|
||||
Prefix,
|
||||
@ -25,17 +21,7 @@ impl FromStr for CompletionAlgorithm {
|
||||
}
|
||||
}
|
||||
|
||||
impl ReconstructVal for CompletionAlgorithm {
|
||||
fn reconstruct_value(&self, span: Span) -> Value {
|
||||
let str = match self {
|
||||
CompletionAlgorithm::Prefix => "prefix",
|
||||
CompletionAlgorithm::Fuzzy => "fuzzy",
|
||||
};
|
||||
Value::string(str, span)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, Default, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Default, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum CompletionSort {
|
||||
#[default]
|
||||
Smart,
|
||||
@ -54,31 +40,44 @@ impl FromStr for CompletionSort {
|
||||
}
|
||||
}
|
||||
|
||||
impl ReconstructVal for CompletionSort {
|
||||
fn reconstruct_value(&self, span: Span) -> Value {
|
||||
let str = match self {
|
||||
Self::Smart => "smart",
|
||||
Self::Alphabetical => "alphabetical",
|
||||
};
|
||||
Value::string(str, span)
|
||||
#[derive(Clone, Debug, IntoValue, Serialize, Deserialize)]
|
||||
pub struct ExternalCompleterConfig {
|
||||
pub enable: bool,
|
||||
pub max_results: i64,
|
||||
pub completer: Option<Closure>,
|
||||
}
|
||||
|
||||
impl Default for ExternalCompleterConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enable: true,
|
||||
max_results: 100,
|
||||
completer: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn reconstruct_external_completer(config: &Config, span: Span) -> Value {
|
||||
if let Some(closure) = config.external_completer.as_ref() {
|
||||
Value::closure(closure.clone(), span)
|
||||
} else {
|
||||
Value::nothing(span)
|
||||
}
|
||||
#[derive(Clone, Debug, IntoValue, Serialize, Deserialize)]
|
||||
pub struct CompleterConfig {
|
||||
pub sort: CompletionSort,
|
||||
pub case_sensitive: bool,
|
||||
pub quick: bool,
|
||||
pub partial: bool,
|
||||
pub algorithm: CompletionAlgorithm,
|
||||
pub external: ExternalCompleterConfig,
|
||||
pub use_ls_colors: bool,
|
||||
}
|
||||
|
||||
pub(super) fn reconstruct_external(config: &Config, span: Span) -> Value {
|
||||
Value::record(
|
||||
record! {
|
||||
"max_results" => Value::int(config.max_external_completion_results, span),
|
||||
"completer" => reconstruct_external_completer(config, span),
|
||||
"enable" => Value::bool(config.enable_external_completion, span),
|
||||
},
|
||||
span,
|
||||
)
|
||||
impl Default for CompleterConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
sort: CompletionSort::default(),
|
||||
case_sensitive: false,
|
||||
quick: true,
|
||||
partial: true,
|
||||
algorithm: CompletionAlgorithm::default(),
|
||||
external: ExternalCompleterConfig::default(),
|
||||
use_ls_colors: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
8
crates/nu-protocol/src/config/datetime_format.rs
Normal file
8
crates/nu-protocol/src/config/datetime_format.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use super::prelude::*;
|
||||
use crate as nu_protocol;
|
||||
|
||||
#[derive(Clone, Debug, Default, IntoValue, Serialize, Deserialize)]
|
||||
pub struct DatetimeFormatConfig {
|
||||
pub normal: Option<String>,
|
||||
pub table: Option<String>,
|
||||
}
|
17
crates/nu-protocol/src/config/filesize.rs
Normal file
17
crates/nu-protocol/src/config/filesize.rs
Normal file
@ -0,0 +1,17 @@
|
||||
use super::prelude::*;
|
||||
use crate as nu_protocol;
|
||||
|
||||
#[derive(Clone, Debug, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct FilesizeConfig {
|
||||
pub metric: bool,
|
||||
pub format: String,
|
||||
}
|
||||
|
||||
impl Default for FilesizeConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
metric: false,
|
||||
format: "auto".into(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,17 +1,13 @@
|
||||
use crate::{Record, ShellError, Span, Value};
|
||||
use crate::{IntoValue, Record, ShellError, Span, Value};
|
||||
use std::{collections::HashMap, fmt::Display, str::FromStr};
|
||||
|
||||
pub(super) trait ReconstructVal {
|
||||
fn reconstruct_value(&self, span: Span) -> Value;
|
||||
}
|
||||
|
||||
pub(super) fn process_string_enum<T, E>(
|
||||
config_point: &mut T,
|
||||
config_path: &[&str],
|
||||
value: &mut Value,
|
||||
errors: &mut Vec<ShellError>,
|
||||
) where
|
||||
T: FromStr<Err = E> + ReconstructVal,
|
||||
T: FromStr<Err = E> + Clone + IntoValue,
|
||||
E: Display,
|
||||
{
|
||||
let span = value.span();
|
||||
@ -32,7 +28,7 @@ pub(super) fn process_string_enum<T, E>(
|
||||
inner: vec![],
|
||||
});
|
||||
// Reconstruct
|
||||
*value = config_point.reconstruct_value(span);
|
||||
*value = config_point.clone().into_value(span);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -44,7 +40,7 @@ pub(super) fn process_string_enum<T, E>(
|
||||
inner: vec![],
|
||||
});
|
||||
// Reconstruct
|
||||
*value = config_point.reconstruct_value(span);
|
||||
*value = config_point.clone().into_value(span);
|
||||
}
|
||||
}
|
||||
|
||||
|
41
crates/nu-protocol/src/config/history.rs
Normal file
41
crates/nu-protocol/src/config/history.rs
Normal file
@ -0,0 +1,41 @@
|
||||
use super::prelude::*;
|
||||
use crate as nu_protocol;
|
||||
|
||||
#[derive(Clone, Copy, Debug, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum HistoryFileFormat {
|
||||
/// Store history as an SQLite database with additional context
|
||||
Sqlite,
|
||||
/// store history as a plain text file where every line is one command (without any context such as timestamps)
|
||||
Plaintext,
|
||||
}
|
||||
|
||||
impl FromStr for HistoryFileFormat {
|
||||
type Err = &'static str;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_ascii_lowercase().as_str() {
|
||||
"sqlite" => Ok(Self::Sqlite),
|
||||
"plaintext" => Ok(Self::Plaintext),
|
||||
_ => Err("expected either 'sqlite' or 'plaintext'"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct HistoryConfig {
|
||||
pub max_size: i64,
|
||||
pub sync_on_enter: bool,
|
||||
pub file_format: HistoryFileFormat,
|
||||
pub isolation: bool,
|
||||
}
|
||||
|
||||
impl Default for HistoryConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
max_size: 100_000,
|
||||
sync_on_enter: true,
|
||||
file_format: HistoryFileFormat::Plaintext,
|
||||
isolation: false,
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
use crate::{Config, Record, ShellError, Span, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use super::prelude::*;
|
||||
use crate as nu_protocol;
|
||||
use crate::ShellError;
|
||||
|
||||
/// Definition of a parsed hook from the config object
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[derive(Clone, Debug, IntoValue, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Hooks {
|
||||
pub pre_prompt: Option<Value>,
|
||||
pub pre_execution: Option<Value>,
|
||||
@ -65,24 +66,3 @@ pub(super) fn create_hooks(value: &Value) -> Result<Hooks, ShellError> {
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn reconstruct_hooks(config: &Config, span: Span) -> Value {
|
||||
let mut hook = Record::new();
|
||||
if let Some(ref value) = config.hooks.pre_prompt {
|
||||
hook.push("pre_prompt", value.clone());
|
||||
}
|
||||
if let Some(ref value) = config.hooks.pre_execution {
|
||||
hook.push("pre_execution", value.clone());
|
||||
}
|
||||
if let Some(ref value) = config.hooks.env_change {
|
||||
hook.push("env_change", value.clone());
|
||||
}
|
||||
if let Some(ref value) = config.hooks.display_output {
|
||||
hook.push("display_output", value.clone());
|
||||
}
|
||||
if let Some(ref value) = config.hooks.command_not_found {
|
||||
hook.push("command_not_found", value.clone());
|
||||
}
|
||||
|
||||
Value::record(hook, span)
|
||||
}
|
||||
|
17
crates/nu-protocol/src/config/ls.rs
Normal file
17
crates/nu-protocol/src/config/ls.rs
Normal file
@ -0,0 +1,17 @@
|
||||
use super::prelude::*;
|
||||
use crate as nu_protocol;
|
||||
|
||||
#[derive(Clone, Copy, Debug, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct LsConfig {
|
||||
pub use_ls_colors: bool,
|
||||
pub clickable_links: bool,
|
||||
}
|
||||
|
||||
impl Default for LsConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
use_ls_colors: true,
|
||||
clickable_links: true,
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,7 @@
|
||||
use super::helper::ReconstructVal;
|
||||
use crate::{Config, Record, Span, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
use super::prelude::*;
|
||||
use crate as nu_protocol;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
|
||||
#[derive(Clone, Copy, Debug, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum ErrorStyle {
|
||||
Plain,
|
||||
Fancy,
|
||||
@ -20,26 +18,3 @@ impl FromStr for ErrorStyle {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ReconstructVal for ErrorStyle {
|
||||
fn reconstruct_value(&self, span: Span) -> Value {
|
||||
Value::string(
|
||||
match self {
|
||||
ErrorStyle::Fancy => "fancy",
|
||||
ErrorStyle::Plain => "plain",
|
||||
},
|
||||
span,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn reconstruct_datetime_format(config: &Config, span: Span) -> Value {
|
||||
let mut record = Record::new();
|
||||
if let Some(normal) = &config.datetime_normal_format {
|
||||
record.push("normal", Value::string(normal, span));
|
||||
}
|
||||
if let Some(table) = &config.datetime_table_format {
|
||||
record.push("table", Value::string(table, span));
|
||||
}
|
||||
Value::record(record, span)
|
||||
}
|
||||
|
@ -1,15 +1,11 @@
|
||||
use super::helper::{process_bool_config, report_invalid_key, report_invalid_value};
|
||||
use super::prelude::*;
|
||||
use crate as nu_protocol;
|
||||
use crate::ShellError;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{record, ShellError, Span, Value};
|
||||
|
||||
use super::helper::{
|
||||
process_bool_config, report_invalid_key, report_invalid_value, ReconstructVal,
|
||||
};
|
||||
|
||||
/// Configures when plugins should be stopped if inactive
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||
#[derive(Clone, Debug, Default, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct PluginGcConfigs {
|
||||
/// The config to use for plugins not otherwise specified
|
||||
pub default: PluginGcConfig,
|
||||
@ -61,23 +57,11 @@ impl PluginGcConfigs {
|
||||
});
|
||||
} else {
|
||||
report_invalid_value("should be a record", value.span(), errors);
|
||||
*value = self.reconstruct_value(value.span());
|
||||
*value = self.clone().into_value(value.span());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ReconstructVal for PluginGcConfigs {
|
||||
fn reconstruct_value(&self, span: Span) -> Value {
|
||||
Value::record(
|
||||
record! {
|
||||
"default" => self.default.reconstruct_value(span),
|
||||
"plugins" => reconstruct_plugins(&self.plugins, span),
|
||||
},
|
||||
span,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn process_plugins(
|
||||
path: &[&str],
|
||||
value: &mut Value,
|
||||
@ -100,7 +84,7 @@ fn process_plugins(
|
||||
report_invalid_value("should be a record", value.span(), errors);
|
||||
if let Some(conf) = plugins.get(key) {
|
||||
// Reconstruct the value if it existed before
|
||||
*value = conf.reconstruct_value(value.span());
|
||||
*value = conf.clone().into_value(value.span());
|
||||
true
|
||||
} else {
|
||||
// Remove it if it didn't
|
||||
@ -111,18 +95,8 @@ fn process_plugins(
|
||||
}
|
||||
}
|
||||
|
||||
fn reconstruct_plugins(plugins: &HashMap<String, PluginGcConfig>, span: Span) -> Value {
|
||||
Value::record(
|
||||
plugins
|
||||
.iter()
|
||||
.map(|(key, val)| (key.to_owned(), val.reconstruct_value(span)))
|
||||
.collect(),
|
||||
span,
|
||||
)
|
||||
}
|
||||
|
||||
/// Configures when a plugin should be stopped if inactive
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct PluginGcConfig {
|
||||
/// True if the plugin should be stopped automatically
|
||||
pub enabled: bool,
|
||||
@ -139,6 +113,16 @@ impl Default for PluginGcConfig {
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoValue for PluginGcConfig {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
record! {
|
||||
"enabled" => self.enabled.into_value(span),
|
||||
"stop_after" => Value::duration(self.stop_after, span),
|
||||
}
|
||||
.into_value(span)
|
||||
}
|
||||
}
|
||||
|
||||
impl PluginGcConfig {
|
||||
fn process(&mut self, path: &[&str], value: &mut Value, errors: &mut Vec<ShellError>) {
|
||||
if let Value::Record { val, .. } = value {
|
||||
@ -177,23 +161,11 @@ impl PluginGcConfig {
|
||||
})
|
||||
} else {
|
||||
report_invalid_value("should be a record", value.span(), errors);
|
||||
*value = self.reconstruct_value(value.span());
|
||||
*value = self.clone().into_value(value.span());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ReconstructVal for PluginGcConfig {
|
||||
fn reconstruct_value(&self, span: Span) -> Value {
|
||||
Value::record(
|
||||
record! {
|
||||
"enabled" => Value::bool(self.enabled, span),
|
||||
"stop_after" => Value::duration(self.stop_after, span),
|
||||
},
|
||||
span,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn join_path<'a>(a: &[&'a str], b: &[&'a str]) -> Vec<&'a str> {
|
||||
a.iter().copied().chain(b.iter().copied()).collect()
|
||||
}
|
||||
@ -201,6 +173,7 @@ fn join_path<'a>(a: &[&'a str], b: &[&'a str]) -> Vec<&'a str> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use nu_protocol::{record, Span};
|
||||
|
||||
fn test_pair() -> (PluginGcConfigs, Value) {
|
||||
(
|
||||
@ -247,6 +220,6 @@ mod tests {
|
||||
#[test]
|
||||
fn reconstruct() {
|
||||
let (input, expected) = test_pair();
|
||||
assert_eq!(expected, input.reconstruct_value(Span::test_data()));
|
||||
assert_eq!(expected, input.into_value(Span::test_data()));
|
||||
}
|
||||
}
|
||||
|
3
crates/nu-protocol/src/config/prelude.rs
Normal file
3
crates/nu-protocol/src/config/prelude.rs
Normal file
@ -0,0 +1,3 @@
|
||||
pub use crate::{record, IntoValue, Span, Value};
|
||||
pub use serde::{Deserialize, Serialize};
|
||||
pub use std::str::FromStr;
|
@ -1,11 +1,9 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::{extract_value, helper::ReconstructVal};
|
||||
use crate::{record, Config, ShellError, Span, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use super::{extract_value, prelude::*};
|
||||
use crate as nu_protocol;
|
||||
use crate::ShellError;
|
||||
|
||||
/// Definition of a parsed keybinding from the config object
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[derive(Clone, Debug, IntoValue, Serialize, Deserialize)]
|
||||
pub struct ParsedKeybinding {
|
||||
pub modifier: Value,
|
||||
pub keycode: Value,
|
||||
@ -14,23 +12,23 @@ pub struct ParsedKeybinding {
|
||||
}
|
||||
|
||||
/// Definition of a parsed menu from the config object
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[derive(Clone, Debug, IntoValue, Serialize, Deserialize)]
|
||||
pub struct ParsedMenu {
|
||||
pub name: Value,
|
||||
pub marker: Value,
|
||||
pub only_buffer_difference: Value,
|
||||
pub style: Value,
|
||||
pub menu_type: Value,
|
||||
pub r#type: Value,
|
||||
pub source: Value,
|
||||
}
|
||||
|
||||
/// Definition of a Nushell CursorShape (to be mapped to crossterm::cursor::CursorShape)
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Copy, Default)]
|
||||
#[derive(Clone, Copy, Debug, Default, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum NuCursorShape {
|
||||
UnderScore,
|
||||
Underscore,
|
||||
Line,
|
||||
Block,
|
||||
BlinkUnderScore,
|
||||
BlinkUnderscore,
|
||||
BlinkLine,
|
||||
BlinkBlock,
|
||||
#[default]
|
||||
@ -44,66 +42,24 @@ impl FromStr for NuCursorShape {
|
||||
match s.to_ascii_lowercase().as_str() {
|
||||
"line" => Ok(NuCursorShape::Line),
|
||||
"block" => Ok(NuCursorShape::Block),
|
||||
"underscore" => Ok(NuCursorShape::UnderScore),
|
||||
"underscore" => Ok(NuCursorShape::Underscore),
|
||||
"blink_line" => Ok(NuCursorShape::BlinkLine),
|
||||
"blink_block" => Ok(NuCursorShape::BlinkBlock),
|
||||
"blink_underscore" => Ok(NuCursorShape::BlinkUnderScore),
|
||||
"blink_underscore" => Ok(NuCursorShape::BlinkUnderscore),
|
||||
"inherit" => Ok(NuCursorShape::Inherit),
|
||||
_ => Err("expected either 'line', 'block', 'underscore', 'blink_line', 'blink_block', 'blink_underscore' or 'inherit'"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ReconstructVal for NuCursorShape {
|
||||
fn reconstruct_value(&self, span: Span) -> Value {
|
||||
Value::string(
|
||||
match self {
|
||||
NuCursorShape::Line => "line",
|
||||
NuCursorShape::Block => "block",
|
||||
NuCursorShape::UnderScore => "underscore",
|
||||
NuCursorShape::BlinkLine => "blink_line",
|
||||
NuCursorShape::BlinkBlock => "blink_block",
|
||||
NuCursorShape::BlinkUnderScore => "blink_underscore",
|
||||
NuCursorShape::Inherit => "inherit",
|
||||
},
|
||||
span,
|
||||
)
|
||||
}
|
||||
#[derive(Clone, Copy, Debug, Default, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CursorShapeConfig {
|
||||
pub emacs: NuCursorShape,
|
||||
pub vi_insert: NuCursorShape,
|
||||
pub vi_normal: NuCursorShape,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
|
||||
pub enum HistoryFileFormat {
|
||||
/// Store history as an SQLite database with additional context
|
||||
Sqlite,
|
||||
/// store history as a plain text file where every line is one command (without any context such as timestamps)
|
||||
PlainText,
|
||||
}
|
||||
|
||||
impl FromStr for HistoryFileFormat {
|
||||
type Err = &'static str;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_ascii_lowercase().as_str() {
|
||||
"sqlite" => Ok(Self::Sqlite),
|
||||
"plaintext" => Ok(Self::PlainText),
|
||||
_ => Err("expected either 'sqlite' or 'plaintext'"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ReconstructVal for HistoryFileFormat {
|
||||
fn reconstruct_value(&self, span: Span) -> Value {
|
||||
Value::string(
|
||||
match self {
|
||||
HistoryFileFormat::Sqlite => "sqlite",
|
||||
HistoryFileFormat::PlainText => "plaintext",
|
||||
},
|
||||
span,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Default, Copy)]
|
||||
#[derive(Clone, Copy, Debug, Default, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum EditBindings {
|
||||
Vi,
|
||||
#[default]
|
||||
@ -122,18 +78,6 @@ impl FromStr for EditBindings {
|
||||
}
|
||||
}
|
||||
|
||||
impl ReconstructVal for EditBindings {
|
||||
fn reconstruct_value(&self, span: Span) -> Value {
|
||||
Value::string(
|
||||
match self {
|
||||
EditBindings::Vi => "vi",
|
||||
EditBindings::Emacs => "emacs",
|
||||
},
|
||||
span,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses the config object to extract the strings that will compose a keybinding for reedline
|
||||
pub(super) fn create_keybindings(value: &Value) -> Result<Vec<ParsedKeybinding>, ShellError> {
|
||||
let span = value.span();
|
||||
@ -172,34 +116,6 @@ pub(super) fn create_keybindings(value: &Value) -> Result<Vec<ParsedKeybinding>,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn reconstruct_keybindings(config: &Config, span: Span) -> Value {
|
||||
Value::list(
|
||||
config
|
||||
.keybindings
|
||||
.iter()
|
||||
.map(
|
||||
|ParsedKeybinding {
|
||||
modifier,
|
||||
keycode,
|
||||
mode,
|
||||
event,
|
||||
}| {
|
||||
Value::record(
|
||||
record! {
|
||||
"modifier" => modifier.clone(),
|
||||
"keycode" => keycode.clone(),
|
||||
"mode" => mode.clone(),
|
||||
"event" => event.clone(),
|
||||
},
|
||||
span,
|
||||
)
|
||||
},
|
||||
)
|
||||
.collect(),
|
||||
span,
|
||||
)
|
||||
}
|
||||
|
||||
/// Parses the config object to extract the strings that will compose a keybinding for reedline
|
||||
pub fn create_menus(value: &Value) -> Result<Vec<ParsedMenu>, ShellError> {
|
||||
let span = value.span();
|
||||
@ -211,7 +127,7 @@ pub fn create_menus(value: &Value) -> Result<Vec<ParsedMenu>, ShellError> {
|
||||
let only_buffer_difference =
|
||||
extract_value("only_buffer_difference", val, span)?.clone();
|
||||
let style = extract_value("style", val, span)?.clone();
|
||||
let menu_type = extract_value("type", val, span)?.clone();
|
||||
let r#type = extract_value("type", val, span)?.clone();
|
||||
|
||||
// Source is an optional value
|
||||
let source = match extract_value("source", val, span) {
|
||||
@ -224,7 +140,7 @@ pub fn create_menus(value: &Value) -> Result<Vec<ParsedMenu>, ShellError> {
|
||||
only_buffer_difference,
|
||||
marker,
|
||||
style,
|
||||
menu_type,
|
||||
r#type,
|
||||
source,
|
||||
};
|
||||
|
||||
@ -243,35 +159,3 @@ pub fn create_menus(value: &Value) -> Result<Vec<ParsedMenu>, ShellError> {
|
||||
_ => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn reconstruct_menus(config: &Config, span: Span) -> Value {
|
||||
Value::list(
|
||||
config
|
||||
.menus
|
||||
.iter()
|
||||
.map(
|
||||
|ParsedMenu {
|
||||
name,
|
||||
only_buffer_difference,
|
||||
marker,
|
||||
style,
|
||||
menu_type, // WARNING: this is not the same name as what is used in Config.nu! ("type")
|
||||
source,
|
||||
}| {
|
||||
Value::record(
|
||||
record! {
|
||||
"name" => name.clone(),
|
||||
"only_buffer_difference" => only_buffer_difference.clone(),
|
||||
"marker" => marker.clone(),
|
||||
"style" => style.clone(),
|
||||
"type" => menu_type.clone(),
|
||||
"source" => source.clone(),
|
||||
},
|
||||
span,
|
||||
)
|
||||
},
|
||||
)
|
||||
.collect(),
|
||||
span,
|
||||
)
|
||||
}
|
||||
|
16
crates/nu-protocol/src/config/rm.rs
Normal file
16
crates/nu-protocol/src/config/rm.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use super::prelude::*;
|
||||
use crate as nu_protocol;
|
||||
|
||||
#[derive(Clone, Copy, Debug, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct RmConfig {
|
||||
pub always_trash: bool,
|
||||
}
|
||||
|
||||
#[allow(clippy::derivable_impls)]
|
||||
impl Default for RmConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
always_trash: false,
|
||||
}
|
||||
}
|
||||
}
|
28
crates/nu-protocol/src/config/shell_integration.rs
Normal file
28
crates/nu-protocol/src/config/shell_integration.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use super::prelude::*;
|
||||
use crate as nu_protocol;
|
||||
|
||||
#[derive(Clone, Copy, Debug, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ShellIntegrationConfig {
|
||||
pub osc2: bool,
|
||||
pub osc7: bool,
|
||||
pub osc8: bool,
|
||||
pub osc9_9: bool,
|
||||
pub osc133: bool,
|
||||
pub osc633: bool,
|
||||
pub reset_application_mode: bool,
|
||||
}
|
||||
|
||||
#[allow(clippy::derivable_impls)]
|
||||
impl Default for ShellIntegrationConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
osc2: false,
|
||||
osc7: false,
|
||||
osc8: false,
|
||||
osc9_9: false,
|
||||
osc133: false,
|
||||
osc633: false,
|
||||
reset_application_mode: false,
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
use super::helper::ReconstructVal;
|
||||
use crate::{record, Config, ShellError, Span, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
use super::prelude::*;
|
||||
use crate as nu_protocol;
|
||||
use crate::ShellError;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, Default)]
|
||||
#[derive(Clone, Copy, Debug, Default, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum TableMode {
|
||||
Basic,
|
||||
Thin,
|
||||
@ -51,33 +50,7 @@ impl FromStr for TableMode {
|
||||
}
|
||||
}
|
||||
|
||||
impl ReconstructVal for TableMode {
|
||||
fn reconstruct_value(&self, span: Span) -> Value {
|
||||
Value::string(
|
||||
match self {
|
||||
TableMode::Basic => "basic",
|
||||
TableMode::Thin => "thin",
|
||||
TableMode::Light => "light",
|
||||
TableMode::Compact => "compact",
|
||||
TableMode::WithLove => "with_love",
|
||||
TableMode::CompactDouble => "compact_double",
|
||||
TableMode::Rounded => "rounded",
|
||||
TableMode::Reinforced => "reinforced",
|
||||
TableMode::Heavy => "heavy",
|
||||
TableMode::None => "none",
|
||||
TableMode::Psql => "psql",
|
||||
TableMode::Markdown => "markdown",
|
||||
TableMode::Dots => "dots",
|
||||
TableMode::Restructured => "restructured",
|
||||
TableMode::AsciiRounded => "ascii_rounded",
|
||||
TableMode::BasicCompact => "basic_compact",
|
||||
},
|
||||
span,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum FooterMode {
|
||||
/// Never show the footer
|
||||
Never,
|
||||
@ -108,21 +81,18 @@ impl FromStr for FooterMode {
|
||||
}
|
||||
}
|
||||
|
||||
impl ReconstructVal for FooterMode {
|
||||
fn reconstruct_value(&self, span: Span) -> Value {
|
||||
Value::string(
|
||||
match self {
|
||||
FooterMode::Always => "always".to_string(),
|
||||
FooterMode::Never => "never".to_string(),
|
||||
FooterMode::Auto => "auto".to_string(),
|
||||
FooterMode::RowCount(c) => c.to_string(),
|
||||
},
|
||||
span,
|
||||
)
|
||||
impl IntoValue for FooterMode {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
match self {
|
||||
FooterMode::Always => "always".into_value(span),
|
||||
FooterMode::Never => "never".into_value(span),
|
||||
FooterMode::Auto => "auto".into_value(span),
|
||||
FooterMode::RowCount(c) => c.to_string().into_value(span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[derive(Clone, Copy, Debug, IntoValue, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum TableIndexMode {
|
||||
/// Always show indexes
|
||||
Always,
|
||||
@ -145,22 +115,9 @@ impl FromStr for TableIndexMode {
|
||||
}
|
||||
}
|
||||
|
||||
impl ReconstructVal for TableIndexMode {
|
||||
fn reconstruct_value(&self, span: Span) -> Value {
|
||||
Value::string(
|
||||
match self {
|
||||
TableIndexMode::Always => "always",
|
||||
TableIndexMode::Never => "never",
|
||||
TableIndexMode::Auto => "auto",
|
||||
},
|
||||
span,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// A Table view configuration, for a situation where
|
||||
/// we need to limit cell width in order to adjust for a terminal size.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum TrimStrategy {
|
||||
/// Wrapping strategy.
|
||||
///
|
||||
@ -196,7 +153,7 @@ impl TrimStrategy {
|
||||
|
||||
impl Default for TrimStrategy {
|
||||
fn default() -> Self {
|
||||
TrimStrategy::Wrap {
|
||||
Self::Wrap {
|
||||
try_to_keep_words: true,
|
||||
}
|
||||
}
|
||||
@ -289,45 +246,89 @@ fn try_parse_trim_methodology(value: &Value) -> Option<TrimStrategy> {
|
||||
None
|
||||
}
|
||||
|
||||
pub(super) fn reconstruct_trim_strategy(config: &Config, span: Span) -> Value {
|
||||
match &config.trim_strategy {
|
||||
TrimStrategy::Wrap { try_to_keep_words } => Value::record(
|
||||
record! {
|
||||
"methodology" => Value::string("wrapping", span),
|
||||
"wrapping_try_keep_words" => Value::bool(*try_to_keep_words, span),
|
||||
},
|
||||
span,
|
||||
),
|
||||
TrimStrategy::Truncate { suffix } => Value::record(
|
||||
match suffix {
|
||||
Some(s) => record! {
|
||||
"methodology" => Value::string("truncating", span),
|
||||
"truncating_suffix" => Value::string(s.clone(), span),
|
||||
},
|
||||
None => record! {
|
||||
"methodology" => Value::string("truncating", span),
|
||||
"truncating_suffix" => Value::nothing(span),
|
||||
},
|
||||
},
|
||||
span,
|
||||
),
|
||||
impl IntoValue for TrimStrategy {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
match self {
|
||||
TrimStrategy::Wrap { try_to_keep_words } => {
|
||||
record! {
|
||||
"methodology" => "wrapping".into_value(span),
|
||||
"wrapping_try_keep_words" => try_to_keep_words.into_value(span),
|
||||
}
|
||||
}
|
||||
TrimStrategy::Truncate { suffix } => {
|
||||
record! {
|
||||
"methodology" => "truncating".into_value(span),
|
||||
"truncating_suffix" => suffix.into_value(span),
|
||||
}
|
||||
}
|
||||
}
|
||||
.into_value(span)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct TableIndent {
|
||||
pub left: usize,
|
||||
pub right: usize,
|
||||
}
|
||||
|
||||
pub(super) fn reconstruct_padding(config: &Config, span: Span) -> Value {
|
||||
// For better completions always reconstruct the record version even though unsigned int would
|
||||
// be supported, `as` conversion is sane as it came from an i64 original
|
||||
Value::record(
|
||||
record!(
|
||||
"left" => Value::int(config.table_indent.left as i64, span),
|
||||
"right" => Value::int(config.table_indent.right as i64, span),
|
||||
),
|
||||
span,
|
||||
)
|
||||
impl IntoValue for TableIndent {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
record! {
|
||||
"left" => (self.left as i64).into_value(span),
|
||||
"right" => (self.right as i64).into_value(span),
|
||||
}
|
||||
.into_value(span)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for TableIndent {
|
||||
fn default() -> Self {
|
||||
Self { left: 1, right: 1 }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct TableConfig {
|
||||
pub mode: TableMode,
|
||||
pub index_mode: TableIndexMode,
|
||||
pub show_empty: bool,
|
||||
pub padding: TableIndent,
|
||||
pub trim: TrimStrategy,
|
||||
pub header_on_separator: bool,
|
||||
pub abbreviated_row_count: Option<usize>,
|
||||
}
|
||||
|
||||
impl IntoValue for TableConfig {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
let abbv_count = self
|
||||
.abbreviated_row_count
|
||||
.map(|t| t as i64)
|
||||
.into_value(span);
|
||||
|
||||
record! {
|
||||
"mode" => self.mode.into_value(span),
|
||||
"index_mode" => self.index_mode.into_value(span),
|
||||
"show_empty" => self.show_empty.into_value(span),
|
||||
"padding" => self.padding.into_value(span),
|
||||
"trim" => self.trim.into_value(span),
|
||||
"header_on_separator" => self.header_on_separator.into_value(span),
|
||||
"abbreviated_row_count" => abbv_count,
|
||||
}
|
||||
.into_value(span)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for TableConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
mode: TableMode::Rounded,
|
||||
index_mode: TableIndexMode::Always,
|
||||
show_empty: true,
|
||||
trim: TrimStrategy::default(),
|
||||
header_on_separator: false,
|
||||
padding: TableIndent::default(),
|
||||
abbreviated_row_count: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
|
||||
HistoryFileFormat::Sqlite => {
|
||||
path.push("history.sqlite3");
|
||||
}
|
||||
HistoryFileFormat::PlainText => {
|
||||
HistoryFileFormat::Plaintext => {
|
||||
path.push("history.txt");
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ pub fn format_filesize_from_conf(num_bytes: i64, config: &Config) -> String {
|
||||
// and filesize_metric is false, return KiB
|
||||
format_filesize(
|
||||
num_bytes,
|
||||
config.filesize_format.as_str(),
|
||||
Some(config.filesize_metric),
|
||||
&config.filesize.format,
|
||||
Some(config.filesize.metric),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -832,7 +832,7 @@ impl Value {
|
||||
Value::Float { val, .. } => val.to_string(),
|
||||
Value::Filesize { val, .. } => format_filesize_from_conf(*val, config),
|
||||
Value::Duration { val, .. } => format_duration(*val),
|
||||
Value::Date { val, .. } => match &config.datetime_normal_format {
|
||||
Value::Date { val, .. } => match &config.datetime_format.normal {
|
||||
Some(format) => self.format_datetime(val, format),
|
||||
None => {
|
||||
format!(
|
||||
@ -886,7 +886,7 @@ impl Value {
|
||||
/// - "[record {n} fields]"
|
||||
pub fn to_abbreviated_string(&self, config: &Config) -> String {
|
||||
match self {
|
||||
Value::Date { val, .. } => match &config.datetime_table_format {
|
||||
Value::Date { val, .. } => match &config.datetime_format.table {
|
||||
Some(format) => self.format_datetime(val, format),
|
||||
None => HumanTime::from(*val).to_string(),
|
||||
},
|
||||
|
@ -23,8 +23,8 @@ pub fn create_nu_table_config(
|
||||
with_index: out.with_index,
|
||||
with_header: out.with_header,
|
||||
split_color: Some(lookup_separator_color(comp)),
|
||||
trim: config.trim_strategy.clone(),
|
||||
header_on_border: config.table_move_header,
|
||||
trim: config.table.trim.clone(),
|
||||
header_on_border: config.table.header_on_separator,
|
||||
expand,
|
||||
}
|
||||
}
|
||||
@ -62,7 +62,8 @@ pub fn error_sign(style_computer: &StyleComputer) -> (String, TextStyle) {
|
||||
}
|
||||
|
||||
pub fn wrap_text(text: &str, width: usize, config: &Config) -> String {
|
||||
string_wrap(text, width, is_cfg_trim_keep_words(config))
|
||||
let keep_words = config.table.trim == TrimStrategy::wrap(true);
|
||||
string_wrap(text, width, keep_words)
|
||||
}
|
||||
|
||||
pub fn get_header_style(style_computer: &StyleComputer) -> TextStyle {
|
||||
@ -163,15 +164,6 @@ fn convert_with_precision(val: &str, precision: usize) -> Result<String, ShellEr
|
||||
Ok(format!("{val_float:.precision$}"))
|
||||
}
|
||||
|
||||
fn is_cfg_trim_keep_words(config: &Config) -> bool {
|
||||
matches!(
|
||||
config.trim_strategy,
|
||||
TrimStrategy::Wrap {
|
||||
try_to_keep_words: true
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
pub fn load_theme(mode: TableMode) -> TableTheme {
|
||||
match mode {
|
||||
TableMode::Basic => TableTheme::basic(),
|
||||
|
@ -36,7 +36,7 @@ fn collapsed_table(
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let indent = (config.table_indent.left, config.table_indent.right);
|
||||
let indent = (config.table.padding.left, config.table.padding.right);
|
||||
let table = table.draw(style_computer, &theme, indent);
|
||||
|
||||
Ok(Some(table))
|
||||
|
@ -26,8 +26,8 @@ impl JustTable {
|
||||
fn create_table(input: &[Value], opts: TableOpts<'_>) -> Result<Option<String>, ShellError> {
|
||||
match table(input, &opts)? {
|
||||
Some(mut out) => {
|
||||
let left = opts.config.table_indent.left;
|
||||
let right = opts.config.table_indent.right;
|
||||
let left = opts.config.table.padding.left;
|
||||
let right = opts.config.table.padding.right;
|
||||
out.table.set_indent(left, right);
|
||||
|
||||
colorize_space(out.table.get_records_mut(), opts.style_computer);
|
||||
@ -59,8 +59,8 @@ fn kv_table(record: &Record, opts: TableOpts<'_>) -> StringResult {
|
||||
|
||||
let mut out = TableOutput::new(table, false, true);
|
||||
|
||||
let left = opts.config.table_indent.left;
|
||||
let right = opts.config.table_indent.right;
|
||||
let left = opts.config.table.padding.left;
|
||||
let right = opts.config.table.padding.right;
|
||||
out.table.set_indent(left, right);
|
||||
|
||||
let table_config =
|
||||
|
@ -67,7 +67,7 @@ impl<'a> TableOpts<'a> {
|
||||
}
|
||||
|
||||
fn has_index(opts: &TableOpts<'_>, headers: &[String]) -> bool {
|
||||
let with_index = match opts.config.table_index_mode {
|
||||
let with_index = match opts.config.table.index_mode {
|
||||
TableIndexMode::Always => true,
|
||||
TableIndexMode::Never => false,
|
||||
TableIndexMode::Auto => headers.iter().any(|header| header == INDEX_COLUMN_NAME),
|
||||
|
Loading…
Reference in New Issue
Block a user