diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml index ca4cb04a2c..f86d7572a2 100644 --- a/.github/workflows/nightly-build.yml +++ b/.github/workflows/nightly-build.yml @@ -39,7 +39,7 @@ jobs: uses: hustcer/setup-nu@v3.10 if: github.repository == 'nushell/nightly' with: - version: 0.91.0 + version: 0.93.0 # Synchronize the main branch of nightly repo with the main branch of Nushell official repo - name: Prepare for Nightly Release @@ -141,7 +141,7 @@ jobs: - name: Setup Nushell uses: hustcer/setup-nu@v3.10 with: - version: 0.91.0 + version: 0.93.0 - name: Release Nu Binary id: nu @@ -253,7 +253,7 @@ jobs: - name: Setup Nushell uses: hustcer/setup-nu@v3.10 with: - version: 0.91.0 + version: 0.93.0 - name: Release Nu Binary id: nu @@ -317,7 +317,7 @@ jobs: - name: Setup Nushell uses: hustcer/setup-nu@v3.10 with: - version: 0.91.0 + version: 0.93.0 # Keep the last a few releases - name: Delete Older Releases diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e08b96cb0f..fce38d9b4b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -89,7 +89,7 @@ jobs: - name: Setup Nushell uses: hustcer/setup-nu@v3.10 with: - version: 0.91.0 + version: 0.93.0 - name: Release Nu Binary id: nu @@ -179,7 +179,7 @@ jobs: - name: Setup Nushell uses: hustcer/setup-nu@v3.10 with: - version: 0.91.0 + version: 0.93.0 - name: Release Nu Binary id: nu diff --git a/Cargo.lock b/Cargo.lock index 1edea413ed..2d232ffd1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -240,30 +240,6 @@ dependencies = [ "wait-timeout", ] -[[package]] -name = "async-channel" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" -dependencies = [ - "concurrent-queue", - "event-listener 5.3.0", - "event-listener-strategy 0.5.1", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-lock" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" -dependencies = [ - "event-listener 4.0.3", - "event-listener-strategy 0.4.0", - "pin-project-lite", -] - [[package]] name = "async-stream" version = "0.3.5" @@ -286,12 +262,6 @@ dependencies = [ "syn 2.0.58", ] -[[package]] -name = "async-task" -version = "4.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" - [[package]] name = "async-trait" version = "0.1.79" @@ -318,12 +288,6 @@ version = "0.15.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ae037714f313c1353189ead58ef9eec30a8e8dc101b2622d461418fd59e28a9" -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - [[package]] name = "autocfg" version = "1.2.0" @@ -472,22 +436,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "blocking" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" -dependencies = [ - "async-channel", - "async-lock", - "async-task", - "fastrand", - "futures-io", - "futures-lite", - "piper", - "tracing", -] - [[package]] name = "borsh" version = "1.4.0" @@ -905,15 +853,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "concurrent-queue" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "condtype" version = "1.3.0" @@ -1446,48 +1385,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" -[[package]] -name = "event-listener" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d9944b8ca13534cdfb2800775f8dd4902ff3fc75a50101466decadfdf322a24" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" -dependencies = [ - "event-listener 4.0.3", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "332f51cb23d20b0de8458b86580878211da09bcd4503cb579c225b3d124cabb3" -dependencies = [ - "event-listener 5.3.0", - "pin-project-lite", -] - [[package]] name = "fallible-iterator" version = "0.3.0" @@ -1704,16 +1601,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" -[[package]] -name = "futures-lite" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" -dependencies = [ - "futures-core", - "pin-project-lite", -] - [[package]] name = "futures-macro" version = "0.3.30" @@ -2135,30 +2022,16 @@ dependencies = [ [[package]] name = "interprocess" -version = "1.2.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f2533f3be42fffe3b5e63b71aeca416c1c3bc33e4e27be018521e76b1f38fb" +checksum = "6d5f0e3c218e7a86a6712fd3adc84672304f9e839402b866685b9117a077c37f" dependencies = [ - "blocking", - "cfg-if", - "futures-core", - "futures-io", - "intmap", "libc", - "once_cell", - "rustc_version", - "spinning", - "thiserror", - "to_method", - "winapi", + "recvmsg", + "widestring", + "windows-sys 0.52.0", ] -[[package]] -name = "intmap" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae52f28f45ac2bc96edb7714de995cffc174a395fb0abf5bff453587c980d7b9" - [[package]] name = "inventory" version = "0.3.15" @@ -3364,6 +3237,7 @@ dependencies = [ "serde_json", "strum", "strum_macros 0.26.2", + "tempfile", "thiserror", "typetag", ] @@ -3840,12 +3714,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "parking" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" - [[package]] name = "parking_lot" version = "0.12.1" @@ -4069,17 +3937,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "piper" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - [[package]] name = "pkg-config" version = "0.3.30" @@ -4875,6 +4732,12 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "recvmsg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3edd4d5d42c92f0a659926464d4cce56b562761267ecf0f469d85b7de384175" + [[package]] name = "redox_syscall" version = "0.4.1" @@ -5615,15 +5478,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "spinning" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d4f0e86297cad2658d92a707320d87bf4e6ae1050287f51d19b67ef3f153a7b" -dependencies = [ - "lock_api", -] - [[package]] name = "sqlparser" version = "0.39.0" @@ -6061,12 +5915,6 @@ dependencies = [ "regex", ] -[[package]] -name = "to_method" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8" - [[package]] name = "tokio" version = "1.37.0" @@ -6772,6 +6620,12 @@ dependencies = [ "winsafe", ] +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + [[package]] name = "wild" version = "2.2.1" diff --git a/Cargo.toml b/Cargo.toml index 8382ebec4a..7fbc95a239 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,7 +94,7 @@ heck = "0.5.0" human-date-parser = "0.1.1" indexmap = "2.2" indicatif = "0.17" -interprocess = "1.2.1" +interprocess = "2.0.0" is_executable = "1.0" itertools = "0.12" libc = "0.2" diff --git a/benches/benchmarks.rs b/benches/benchmarks.rs index 84c0e4b02e..e6bec2e163 100644 --- a/benches/benchmarks.rs +++ b/benches/benchmarks.rs @@ -21,6 +21,7 @@ fn load_bench_commands() -> EngineState { } fn canonicalize_path(engine_state: &EngineState, path: &Path) -> PathBuf { + #[allow(deprecated)] let cwd = engine_state.current_work_dir(); if path.exists() { diff --git a/crates/nu-cli/src/completions/directory_completions.rs b/crates/nu-cli/src/completions/directory_completions.rs index f8ab2f400e..e8d463c19f 100644 --- a/crates/nu-cli/src/completions/directory_completions.rs +++ b/crates/nu-cli/src/completions/directory_completions.rs @@ -43,6 +43,7 @@ impl Completer for DirectoryCompletion { let AdjustView { prefix, span, .. } = adjust_if_intermediate(&prefix, working_set, span); // Filter only the folders + #[allow(deprecated)] let output: Vec<_> = directory_completion( span, &prefix, diff --git a/crates/nu-cli/src/completions/dotnu_completions.rs b/crates/nu-cli/src/completions/dotnu_completions.rs index 3c8abd93ff..8927738491 100644 --- a/crates/nu-cli/src/completions/dotnu_completions.rs +++ b/crates/nu-cli/src/completions/dotnu_completions.rs @@ -84,6 +84,7 @@ impl Completer for DotNuCompletion { partial = base_dir_partial; } else { // Fetch the current folder + #[allow(deprecated)] let current_folder = self.engine_state.current_work_dir(); is_current_folder = true; diff --git a/crates/nu-cli/src/completions/file_completions.rs b/crates/nu-cli/src/completions/file_completions.rs index d862975f86..1a99c995db 100644 --- a/crates/nu-cli/src/completions/file_completions.rs +++ b/crates/nu-cli/src/completions/file_completions.rs @@ -47,6 +47,7 @@ impl Completer for FileCompletion { readjusted, } = adjust_if_intermediate(&prefix, working_set, span); + #[allow(deprecated)] let output: Vec<_> = complete_item( readjusted, span, diff --git a/crates/nu-cli/src/completions/variable_completions.rs b/crates/nu-cli/src/completions/variable_completions.rs index c8cadc0d0b..b869e9f972 100644 --- a/crates/nu-cli/src/completions/variable_completions.rs +++ b/crates/nu-cli/src/completions/variable_completions.rs @@ -267,24 +267,6 @@ fn nested_suggestions( output } - Value::LazyRecord { val, .. } => { - // Add all the columns as completion - for column_name in val.column_names() { - output.push(SemanticSuggestion { - suggestion: Suggestion { - value: column_name.to_string(), - description: None, - style: None, - extra: None, - span: current_span, - append_whitespace: false, - }, - kind: Some(kind.clone()), - }); - } - - output - } Value::List { vals, .. } => { for column_name in get_columns(vals.as_slice()) { output.push(SemanticSuggestion { @@ -321,17 +303,6 @@ fn recursive_value(val: &Value, sublevels: &[Vec]) -> Result { Err(span) } } - Value::LazyRecord { val, .. } => { - for col in val.column_names() { - if col.as_bytes() == *sublevel { - let val = val.get_column_value(col).map_err(|_| span)?; - return recursive_value(&val, next_sublevels); - } - } - - // Current sublevel value not found - Err(span) - } Value::List { vals, .. } => { for col in get_columns(vals.as_slice()) { if col.as_bytes() == *sublevel { diff --git a/crates/nu-cli/src/config_files.rs b/crates/nu-cli/src/config_files.rs index 3876272893..775d76382b 100644 --- a/crates/nu-cli/src/config_files.rs +++ b/crates/nu-cli/src/config_files.rs @@ -177,6 +177,7 @@ pub fn add_plugin_file( use std::path::Path; let working_set = StateWorkingSet::new(engine_state); + #[allow(deprecated)] let cwd = working_set.get_cwd(); if let Some(plugin_file) = plugin_file { @@ -235,6 +236,7 @@ pub fn eval_config_contents( engine_state.file = prev_file; // Merge the environment in case env vars changed in the config + #[allow(deprecated)] match nu_engine::env::current_dir(engine_state, stack) { Ok(cwd) => { if let Err(e) = engine_state.merge_env(stack, cwd) { @@ -272,6 +274,7 @@ pub fn migrate_old_plugin_file(engine_state: &EngineState, storage_path: &str) - let start_time = std::time::Instant::now(); + #[allow(deprecated)] let cwd = engine_state.current_work_dir(); let Some(config_dir) = nu_path::config_dir().and_then(|mut dir| { diff --git a/crates/nu-cli/src/eval_file.rs b/crates/nu-cli/src/eval_file.rs index 85b07d629d..90b1e840ee 100644 --- a/crates/nu-cli/src/eval_file.rs +++ b/crates/nu-cli/src/eval_file.rs @@ -1,6 +1,7 @@ use crate::util::eval_source; use log::{info, trace}; use miette::{IntoDiagnostic, Result}; +#[allow(deprecated)] use nu_engine::{convert_env_values, current_dir, eval_block}; use nu_parser::parse; use nu_path::canonicalize_with; @@ -29,6 +30,7 @@ pub fn evaluate_file( std::process::exit(1); } + #[allow(deprecated)] let cwd = current_dir(engine_state, stack)?; let file_path = canonicalize_with(&path, cwd).unwrap_or_else(|e| { diff --git a/crates/nu-cli/src/prompt.rs b/crates/nu-cli/src/prompt.rs index 0ecdae1aaf..a2045a201c 100644 --- a/crates/nu-cli/src/prompt.rs +++ b/crates/nu-cli/src/prompt.rs @@ -1,4 +1,10 @@ -use crate::prompt_update::{POST_PROMPT_MARKER, PRE_PROMPT_MARKER}; +use crate::prompt_update::{ + POST_PROMPT_MARKER, PRE_PROMPT_MARKER, VSCODE_POST_PROMPT_MARKER, VSCODE_PRE_PROMPT_MARKER, +}; +use nu_protocol::{ + engine::{EngineState, Stack}, + Value, +}; #[cfg(windows)] use nu_utils::enable_vt_processing; use reedline::{ @@ -10,7 +16,8 @@ use std::borrow::Cow; /// Nushell prompt definition #[derive(Clone)] pub struct NushellPrompt { - shell_integration: bool, + shell_integration_osc133: bool, + shell_integration_osc633: bool, left_prompt_string: Option, right_prompt_string: Option, default_prompt_indicator: Option, @@ -18,12 +25,20 @@ pub struct NushellPrompt { default_vi_normal_prompt_indicator: Option, default_multiline_indicator: Option, render_right_prompt_on_last_line: bool, + engine_state: EngineState, + stack: Stack, } impl NushellPrompt { - pub fn new(shell_integration: bool) -> NushellPrompt { + pub fn new( + shell_integration_osc133: bool, + shell_integration_osc633: bool, + engine_state: EngineState, + stack: Stack, + ) -> NushellPrompt { NushellPrompt { - shell_integration, + shell_integration_osc133, + shell_integration_osc633, left_prompt_string: None, right_prompt_string: None, default_prompt_indicator: None, @@ -31,6 +46,8 @@ impl NushellPrompt { default_vi_normal_prompt_indicator: None, default_multiline_indicator: None, render_right_prompt_on_last_line: false, + engine_state, + stack, } } @@ -106,7 +123,17 @@ impl Prompt for NushellPrompt { .to_string() .replace('\n', "\r\n"); - if self.shell_integration { + if self.shell_integration_osc633 { + if self.stack.get_env_var(&self.engine_state, "TERM_PROGRAM") + == Some(Value::test_string("vscode")) + { + // We're in vscode and we have osc633 enabled + format!("{VSCODE_PRE_PROMPT_MARKER}{prompt}{VSCODE_POST_PROMPT_MARKER}").into() + } else { + // If we're in VSCode but we don't find the env var, just return the regular markers + format!("{PRE_PROMPT_MARKER}{prompt}{POST_PROMPT_MARKER}").into() + } + } else if self.shell_integration_osc133 { format!("{PRE_PROMPT_MARKER}{prompt}{POST_PROMPT_MARKER}").into() } else { prompt.into() diff --git a/crates/nu-cli/src/prompt_update.rs b/crates/nu-cli/src/prompt_update.rs index 4c7cb7fcfe..0c5641378b 100644 --- a/crates/nu-cli/src/prompt_update.rs +++ b/crates/nu-cli/src/prompt_update.rs @@ -23,10 +23,37 @@ pub(crate) const TRANSIENT_PROMPT_INDICATOR_VI_NORMAL: &str = "TRANSIENT_PROMPT_INDICATOR_VI_NORMAL"; pub(crate) const TRANSIENT_PROMPT_MULTILINE_INDICATOR: &str = "TRANSIENT_PROMPT_MULTILINE_INDICATOR"; + +// Store all these Ansi Escape Markers here so they can be reused easily // According to Daniel Imms @Tyriar, we need to do these this way: // <133 A><133 B><133 C> pub(crate) const PRE_PROMPT_MARKER: &str = "\x1b]133;A\x1b\\"; pub(crate) const POST_PROMPT_MARKER: &str = "\x1b]133;B\x1b\\"; +pub(crate) const PRE_EXECUTION_MARKER: &str = "\x1b]133;C\x1b\\"; +#[allow(dead_code)] +pub(crate) const POST_EXECUTION_MARKER_PREFIX: &str = "\x1b]133;D;"; +#[allow(dead_code)] +pub(crate) const POST_EXECUTION_MARKER_SUFFIX: &str = "\x1b\\"; + +// OSC633 is the same as OSC133 but specifically for VSCode +pub(crate) const VSCODE_PRE_PROMPT_MARKER: &str = "\x1b]633;A\x1b\\"; +pub(crate) const VSCODE_POST_PROMPT_MARKER: &str = "\x1b]633;B\x1b\\"; +#[allow(dead_code)] +pub(crate) const VSCODE_PRE_EXECUTION_MARKER: &str = "\x1b]633;C\x1b\\"; +#[allow(dead_code)] +//"\x1b]633;D;{}\x1b\\" +pub(crate) const VSCODE_POST_EXECUTION_MARKER_PREFIX: &str = "\x1b]633;D;"; +#[allow(dead_code)] +pub(crate) const VSCODE_POST_EXECUTION_MARKER_SUFFIX: &str = "\x1b\\"; +#[allow(dead_code)] +pub(crate) const VSCODE_COMMANDLINE_MARKER: &str = "\x1b]633;E\x1b\\"; +#[allow(dead_code)] +// "\x1b]633;P;Cwd={}\x1b\\" +pub(crate) const VSCODE_CWD_PROPERTY_MARKER_PREFIX: &str = "\x1b]633;P;Cwd="; +#[allow(dead_code)] +pub(crate) const VSCODE_CWD_PROPERTY_MARKER_SUFFIX: &str = "\x1b\\"; + +pub(crate) const RESET_APPLICATION_MODE: &str = "\x1b[?1l"; fn get_prompt_string( prompt: &str, @@ -85,16 +112,46 @@ pub(crate) fn update_prompt( // Now that we have the prompt string lets ansify it. // <133 A><133 B><133 C> - let left_prompt_string = if config.shell_integration { - if let Some(prompt_string) = left_prompt_string { + let left_prompt_string_133 = if config.shell_integration_osc133 { + if let Some(prompt_string) = left_prompt_string.clone() { Some(format!( "{PRE_PROMPT_MARKER}{prompt_string}{POST_PROMPT_MARKER}" )) } else { - left_prompt_string + left_prompt_string.clone() } } else { - left_prompt_string + left_prompt_string.clone() + }; + + let left_prompt_string_633 = if config.shell_integration_osc633 { + if let Some(prompt_string) = left_prompt_string.clone() { + if stack.get_env_var(engine_state, "TERM_PROGRAM") == Some(Value::test_string("vscode")) + { + // If the user enabled osc633 and we're in vscode, use the vscode markers + Some(format!( + "{VSCODE_PRE_PROMPT_MARKER}{prompt_string}{VSCODE_POST_PROMPT_MARKER}" + )) + } else { + // otherwise, use the regular osc133 markers + Some(format!( + "{PRE_PROMPT_MARKER}{prompt_string}{POST_PROMPT_MARKER}" + )) + } + } else { + left_prompt_string.clone() + } + } else { + left_prompt_string.clone() + }; + + let left_prompt_string = match (left_prompt_string_133, left_prompt_string_633) { + (None, None) => left_prompt_string, + (None, Some(l633)) => Some(l633), + (Some(l133), None) => Some(l133), + // If both are set, it means we're in vscode, so use the vscode markers + // and even if we're not actually in vscode atm, the regular 133 markers are used + (Some(_l133), Some(l633)) => Some(l633), }; let right_prompt_string = get_prompt_string(PROMPT_COMMAND_RIGHT, config, engine_state, stack); diff --git a/crates/nu-cli/src/reedline_config.rs b/crates/nu-cli/src/reedline_config.rs index b49dad878c..3f920a00cb 100644 --- a/crates/nu-cli/src/reedline_config.rs +++ b/crates/nu-cli/src/reedline_config.rs @@ -1,6 +1,7 @@ use crate::{menus::NuMenuCompleter, NuHelpCompleter}; use crossterm::event::{KeyCode, KeyModifiers}; use log::trace; +use nu_ansi_term::Style; use nu_color_config::{color_record_to_nustyle, lookup_ansi_color_style}; use nu_engine::eval_block; use nu_parser::parse; @@ -158,21 +159,14 @@ fn add_menu( } } -macro_rules! add_style { - // first arm match add!(1,2), add!(2,3) etc - ($name:expr, $record: expr, $span:expr, $config: expr, $menu:expr, $f:expr) => { - $menu = match extract_value($name, $record, $span) { - Ok(text) => { - let style = match text { - Value::String { val, .. } => lookup_ansi_color_style(&val), - Value::Record { .. } => color_record_to_nustyle(&text), - _ => lookup_ansi_color_style("green"), - }; - $f($menu, style) - } - Err(_) => $menu, - }; - }; +fn get_style(record: &Record, name: &str, span: Span) -> Option