Move Value to helpers, separate span call (#10121)

# Description

As part of the refactor to split spans off of Value, this moves to using
helper functions to create values, and using `.span()` instead of
matching span out of Value directly.

Hoping to get a few more helping hands to finish this, as there are a
lot of commands to update :)

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->

---------

Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
Co-authored-by: WindSoilder <windsoilder@outlook.com>
This commit is contained in:
JT
2023-09-04 02:27:29 +12:00
committed by GitHub
parent af79eb2943
commit 6cdfee3573
372 changed files with 5811 additions and 7448 deletions

View File

@ -102,7 +102,7 @@ impl Command for Commandline {
repl.buffer = cmd.as_string()?;
repl.cursor_pos = repl.buffer.len();
}
Ok(Value::Nothing { span: call.head }.into_pipeline_data())
Ok(Value::nothing(call.head).into_pipeline_data())
} else {
let repl = engine_state.repl_state.lock().expect("repl state mutex");
if call.has_flag("cursor") {
@ -112,17 +112,9 @@ impl Command for Commandline {
.chain(std::iter::once((repl.buffer.len(), "")))
.position(|(i, _c)| i == repl.cursor_pos)
.expect("Cursor position isn't on a grapheme boundary");
Ok(Value::String {
val: char_pos.to_string(),
span: call.head,
}
.into_pipeline_data())
Ok(Value::string(char_pos.to_string(), call.head).into_pipeline_data())
} else {
Ok(Value::String {
val: repl.buffer.to_string(),
span: call.head,
}
.into_pipeline_data())
Ok(Value::string(repl.buffer.to_string(), call.head).into_pipeline_data())
}
}
}

View File

@ -151,8 +151,8 @@ fn create_history_record(idx: usize, entry: HistoryItem, long: bool, head: Span)
//1. Format all the values
//2. Create a record of either short or long columns and values
let item_id_value = Value::Int {
val: match entry.id {
let item_id_value = Value::int(
match entry.id {
Some(id) => {
let ids = id.to_string();
match ids.parse::<i64>() {
@ -162,21 +162,18 @@ fn create_history_record(idx: usize, entry: HistoryItem, long: bool, head: Span)
}
None => 0i64,
},
span: head,
};
let start_timestamp_value = Value::String {
val: match entry.start_timestamp {
head,
);
let start_timestamp_value = Value::string(
match entry.start_timestamp {
Some(time) => time.to_string(),
None => "".into(),
},
span: head,
};
let command_value = Value::String {
val: entry.command_line,
span: head,
};
let session_id_value = Value::Int {
val: match entry.session_id {
head,
);
let command_value = Value::string(entry.command_line, head);
let session_id_value = Value::int(
match entry.session_id {
Some(sid) => {
let sids = sid.to_string();
match sids.parse::<i64>() {
@ -186,29 +183,29 @@ fn create_history_record(idx: usize, entry: HistoryItem, long: bool, head: Span)
}
None => 0i64,
},
span: head,
};
let hostname_value = Value::String {
val: match entry.hostname {
head,
);
let hostname_value = Value::string(
match entry.hostname {
Some(host) => host,
None => "".into(),
},
span: head,
};
let cwd_value = Value::String {
val: match entry.cwd {
head,
);
let cwd_value = Value::string(
match entry.cwd {
Some(cwd) => cwd,
None => "".into(),
},
span: head,
};
let duration_value = Value::Duration {
val: match entry.duration {
head,
);
let duration_value = Value::duration(
match entry.duration {
Some(d) => d.as_nanos().try_into().unwrap_or(0),
None => 0,
},
span: head,
};
head,
);
let exit_status_value = Value::int(entry.exit_status.unwrap_or(0), head);
let index_value = Value::int(idx as i64, head);
if long {

View File

@ -41,16 +41,16 @@ For more information on input and keybindings, check:
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
Ok(Value::String {
val: get_full_help(
Ok(Value::string(
get_full_help(
&Keybindings.signature(),
&Keybindings.examples(),
engine_state,
stack,
self.is_parser_keyword(),
),
span: call.head,
}
call.head,
)
.into_pipeline_data())
}
}

View File

@ -53,10 +53,6 @@ impl Command for KeybindingsDefault {
})
.collect();
Ok(Value::List {
vals: records,
span: call.head,
}
.into_pipeline_data())
Ok(Value::list(records, call.head).into_pipeline_data())
}
}

View File

@ -71,11 +71,7 @@ impl Command for KeybindingsList {
.collect()
};
Ok(Value::List {
vals: records,
span: call.head,
}
.into_pipeline_data())
Ok(Value::list(records, call.head).into_pipeline_data())
}
}

View File

@ -74,13 +74,13 @@ impl NuCompleter {
if let Some(var_id) = pos_arg.var_id {
callee_stack.add_var(
var_id,
Value::List {
vals: spans
Value::list(
spans
.iter()
.map(|it| Value::string(it, Span::unknown()))
.collect(),
span: Span::unknown(),
},
Span::unknown(),
),
);
}
}
@ -97,7 +97,7 @@ impl NuCompleter {
match result {
Ok(pd) => {
let value = pd.into_value(span);
if let Value::List { vals, span: _ } = value {
if let Value::List { vals, .. } = value {
let result =
map_value_completions(vals.iter(), Span::new(span.start, span.end), offset);

View File

@ -263,7 +263,7 @@ fn nested_suggestions(
output
}
Value::List { vals, span: _ } => {
Value::List { vals, .. } => {
for column_name in get_columns(vals.as_slice()) {
output.push(Suggestion {
value: column_name,
@ -284,6 +284,7 @@ fn nested_suggestions(
fn recursive_value(val: Value, sublevels: Vec<Vec<u8>>) -> Value {
// Go to next sublevel
if let Some(next_sublevel) = sublevels.clone().into_iter().next() {
let span = val.span();
match val {
Value::Record { val, .. } => {
for item in val {
@ -295,11 +296,9 @@ fn recursive_value(val: Value, sublevels: Vec<Vec<u8>>) -> Value {
}
// Current sublevel value not found
return Value::Nothing {
span: Span::unknown(),
};
return Value::nothing(span);
}
Value::LazyRecord { val, span: _ } => {
Value::LazyRecord { val, .. } => {
for col in val.column_names() {
if col.as_bytes().to_vec() == next_sublevel {
return recursive_value(
@ -310,15 +309,13 @@ fn recursive_value(val: Value, sublevels: Vec<Vec<u8>>) -> Value {
}
// Current sublevel value not found
return Value::Nothing {
span: Span::unknown(),
};
return Value::nothing(span);
}
Value::List { vals, span } => {
Value::List { vals, .. } => {
for col in get_columns(vals.as_slice()) {
if col.as_bytes().to_vec() == next_sublevel {
return recursive_value(
Value::List { vals, span }
Value::list(vals, span)
.get_data_by_key(&col)
.unwrap_or_default(),
sublevels.into_iter().skip(1).collect(),
@ -327,9 +324,7 @@ fn recursive_value(val: Value, sublevels: Vec<Vec<u8>>) -> Value {
}
// Current sublevel value not found
return Value::Nothing {
span: Span::unknown(),
};
return Value::nothing(span);
}
_ => return val,
}

View File

@ -48,15 +48,9 @@ impl Command for NuHighlight {
Ok(line) => {
let highlights = highlighter.highlight(&line, line.len());
Value::String {
val: highlights.render_simple(),
span: head,
}
Value::string(highlights.render_simple(), head)
}
Err(err) => Value::Error {
error: Box::new(err),
span: head,
},
Err(err) => Value::error(err, head),
},
ctrlc,
)

View File

@ -131,8 +131,9 @@ fn add_menu(
stack: &Stack,
config: &Config,
) -> Result<Reedline, ShellError> {
if let Value::Record { val, span } = &menu.menu_type {
let layout = extract_value("layout", val, *span)?.into_string("", config);
let span = menu.menu_type.span();
if let Value::Record { val, .. } = &menu.menu_type {
let layout = extract_value("layout", val, span)?.into_string("", config);
match layout.as_str() {
"columnar" => add_columnar_menu(line_editor, menu, engine_state, stack, config),
@ -156,7 +157,7 @@ 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) {
$menu = match extract_value($name, $record, $span) {
Ok(text) => {
let style = match text {
Value::String { val, .. } => lookup_ansi_color_style(&val),
@ -178,11 +179,12 @@ pub(crate) fn add_columnar_menu(
stack: &Stack,
config: &Config,
) -> Result<Reedline, ShellError> {
let span = menu.menu_type.span();
let name = menu.name.into_string("", config);
let mut columnar_menu = ColumnarMenu::default().with_name(&name);
if let Value::Record { val, span } = &menu.menu_type {
columnar_menu = match extract_value("columns", val, *span) {
if let Value::Record { val, .. } = &menu.menu_type {
columnar_menu = match extract_value("columns", val, span) {
Ok(columns) => {
let columns = columns.as_int()?;
columnar_menu.with_columns(columns as u16)
@ -190,7 +192,7 @@ pub(crate) fn add_columnar_menu(
Err(_) => columnar_menu,
};
columnar_menu = match extract_value("col_width", val, *span) {
columnar_menu = match extract_value("col_width", val, span) {
Ok(col_width) => {
let col_width = col_width.as_int()?;
columnar_menu.with_column_width(Some(col_width as usize))
@ -198,7 +200,7 @@ pub(crate) fn add_columnar_menu(
Err(_) => columnar_menu.with_column_width(None),
};
columnar_menu = match extract_value("col_padding", val, *span) {
columnar_menu = match extract_value("col_padding", val, span) {
Ok(col_padding) => {
let col_padding = col_padding.as_int()?;
columnar_menu.with_column_padding(col_padding as usize)
@ -207,7 +209,8 @@ pub(crate) fn add_columnar_menu(
};
}
if let Value::Record { val, span } = &menu.style {
let span = menu.style.span();
if let Value::Record { val, .. } = &menu.style {
add_style!(
"text",
val,
@ -240,18 +243,15 @@ pub(crate) fn add_columnar_menu(
let only_buffer_difference = menu.only_buffer_difference.as_bool()?;
columnar_menu = columnar_menu.with_only_buffer_difference(only_buffer_difference);
let span = menu.source.span();
match &menu.source {
Value::Nothing { .. } => {
Ok(line_editor.with_menu(ReedlineMenu::EngineCompleter(Box::new(columnar_menu))))
}
Value::Closure {
val,
captures,
span,
} => {
Value::Closure { val, captures, .. } => {
let menu_completer = NuMenuCompleter::new(
*val,
*span,
span,
stack.captures_to_stack(captures),
engine_state,
only_buffer_difference,
@ -264,7 +264,7 @@ pub(crate) fn add_columnar_menu(
_ => Err(ShellError::UnsupportedConfigValue(
"block or omitted value".to_string(),
menu.source.into_abbreviated_string(config),
menu.source.span(),
span,
)),
}
}
@ -280,8 +280,9 @@ pub(crate) fn add_list_menu(
let name = menu.name.into_string("", config);
let mut list_menu = ListMenu::default().with_name(&name);
if let Value::Record { val, span } = &menu.menu_type {
list_menu = match extract_value("page_size", val, *span) {
let span = menu.menu_type.span();
if let Value::Record { val, .. } = &menu.menu_type {
list_menu = match extract_value("page_size", val, span) {
Ok(page_size) => {
let page_size = page_size.as_int()?;
list_menu.with_page_size(page_size as usize)
@ -290,7 +291,8 @@ pub(crate) fn add_list_menu(
};
}
if let Value::Record { val, span } = &menu.style {
let span = menu.style.span();
if let Value::Record { val, .. } = &menu.style {
add_style!(
"text",
val,
@ -323,18 +325,15 @@ pub(crate) fn add_list_menu(
let only_buffer_difference = menu.only_buffer_difference.as_bool()?;
list_menu = list_menu.with_only_buffer_difference(only_buffer_difference);
let span = menu.source.span();
match &menu.source {
Value::Nothing { .. } => {
Ok(line_editor.with_menu(ReedlineMenu::HistoryMenu(Box::new(list_menu))))
}
Value::Closure {
val,
captures,
span,
} => {
Value::Closure { val, captures, .. } => {
let menu_completer = NuMenuCompleter::new(
*val,
*span,
span,
stack.captures_to_stack(captures),
engine_state,
only_buffer_difference,
@ -363,8 +362,9 @@ pub(crate) fn add_description_menu(
let name = menu.name.into_string("", config);
let mut description_menu = DescriptionMenu::default().with_name(&name);
if let Value::Record { val, span } = &menu.menu_type {
description_menu = match extract_value("columns", val, *span) {
let span = menu.menu_type.span();
if let Value::Record { val, .. } = &menu.menu_type {
description_menu = match extract_value("columns", val, span) {
Ok(columns) => {
let columns = columns.as_int()?;
description_menu.with_columns(columns as u16)
@ -372,7 +372,7 @@ pub(crate) fn add_description_menu(
Err(_) => description_menu,
};
description_menu = match extract_value("col_width", val, *span) {
description_menu = match extract_value("col_width", val, span) {
Ok(col_width) => {
let col_width = col_width.as_int()?;
description_menu.with_column_width(Some(col_width as usize))
@ -380,7 +380,7 @@ pub(crate) fn add_description_menu(
Err(_) => description_menu.with_column_width(None),
};
description_menu = match extract_value("col_padding", val, *span) {
description_menu = match extract_value("col_padding", val, span) {
Ok(col_padding) => {
let col_padding = col_padding.as_int()?;
description_menu.with_column_padding(col_padding as usize)
@ -388,7 +388,7 @@ pub(crate) fn add_description_menu(
Err(_) => description_menu,
};
description_menu = match extract_value("selection_rows", val, *span) {
description_menu = match extract_value("selection_rows", val, span) {
Ok(selection_rows) => {
let selection_rows = selection_rows.as_int()?;
description_menu.with_selection_rows(selection_rows as u16)
@ -396,7 +396,7 @@ pub(crate) fn add_description_menu(
Err(_) => description_menu,
};
description_menu = match extract_value("description_rows", val, *span) {
description_menu = match extract_value("description_rows", val, span) {
Ok(description_rows) => {
let description_rows = description_rows.as_int()?;
description_menu.with_description_rows(description_rows as usize)
@ -405,7 +405,8 @@ pub(crate) fn add_description_menu(
};
}
if let Value::Record { val, span } = &menu.style {
let span = menu.style.span();
if let Value::Record { val, .. } = &menu.style {
add_style!(
"text",
val,
@ -438,6 +439,7 @@ pub(crate) fn add_description_menu(
let only_buffer_difference = menu.only_buffer_difference.as_bool()?;
description_menu = description_menu.with_only_buffer_difference(only_buffer_difference);
let span = menu.source.span();
match &menu.source {
Value::Nothing { .. } => {
let completer = Box::new(NuHelpCompleter::new(engine_state));
@ -446,14 +448,10 @@ pub(crate) fn add_description_menu(
completer,
}))
}
Value::Closure {
val,
captures,
span,
} => {
Value::Closure { val, captures, .. } => {
let menu_completer = NuMenuCompleter::new(
*val,
*span,
span,
stack.captures_to_stack(captures),
engine_state,
only_buffer_difference,
@ -575,15 +573,16 @@ fn add_keybinding(
insert_keybindings: &mut Keybindings,
normal_keybindings: &mut Keybindings,
) -> Result<(), ShellError> {
let span = mode.span();
match &mode {
Value::String { val, span } => match val.as_str() {
Value::String { val, .. } => match val.as_str() {
"emacs" => add_parsed_keybinding(emacs_keybindings, keybinding, config),
"vi_insert" => add_parsed_keybinding(insert_keybindings, keybinding, config),
"vi_normal" => add_parsed_keybinding(normal_keybindings, keybinding, config),
m => Err(ShellError::UnsupportedConfigValue(
"emacs, vi_insert or vi_normal".to_string(),
m.to_string(),
*span,
span,
)),
},
Value::List { vals, .. } => {
@ -724,13 +723,14 @@ impl<'config> EventType<'config> {
}
fn parse_event(value: &Value, config: &Config) -> Result<Option<ReedlineEvent>, ShellError> {
let span = value.span();
match value {
Value::Record { val: record, span } => match EventType::try_from_record(record, *span)? {
Value::Record { val: record, .. } => match EventType::try_from_record(record, span)? {
EventType::Send(value) => event_from_record(
value.into_string("", config).to_lowercase().as_str(),
record,
config,
*span,
span,
)
.map(Some),
EventType::Edit(value) => {
@ -738,7 +738,7 @@ fn parse_event(value: &Value, config: &Config) -> Result<Option<ReedlineEvent>,
value.into_string("", config).to_lowercase().as_str(),
record,
config,
*span,
span,
)?;
Ok(Some(ReedlineEvent::Edit(vec![edit])))
}
@ -1056,10 +1056,10 @@ mod test {
// Until event
let cols = vec!["until".to_string()];
let vals = vec![Value::List {
vals: vec![menu_event, enter_event],
span: Span::test_data(),
}];
let vals = vec![Value::list(
vec![menu_event, enter_event],
Span::test_data(),
)];
let event = Record { cols, vals };
let span = Span::test_data();
@ -1097,10 +1097,7 @@ mod test {
let enter_event = Value::test_record(Record { cols, vals });
// Multiple event
let event = Value::List {
vals: vec![menu_event, enter_event],
span: Span::test_data(),
};
let event = Value::list(vec![menu_event, enter_event], Span::test_data());
let config = Config::default();
let parsed_event = parse_event(&event, &config).unwrap();

View File

@ -514,24 +514,12 @@ pub fn evaluate_repl(
(path.to_string_lossy().to_string(), tokens.0[0].span)
};
stack.add_env_var(
"OLDPWD".into(),
Value::String {
val: cwd.clone(),
span: Span::unknown(),
},
);
stack.add_env_var("OLDPWD".into(), Value::string(cwd.clone(), Span::unknown()));
//FIXME: this only changes the current scope, but instead this environment variable
//should probably be a block that loads the information from the state in the overlay
stack.add_env_var(
"PWD".into(),
Value::String {
val: path.clone(),
span: Span::unknown(),
},
);
let cwd = Value::String { val: cwd, span };
stack.add_env_var("PWD".into(), Value::string(path.clone(), Span::unknown()));
let cwd = Value::string(cwd, span);
let shells = stack.get_env_var(engine_state, "NUSHELL_SHELLS");
let mut shells = if let Some(v) = shells {
@ -556,15 +544,12 @@ pub fn evaluate_repl(
0
};
shells[current_shell] = Value::String { val: path, span };
shells[current_shell] = Value::string(path, span);
stack.add_env_var("NUSHELL_SHELLS".into(), Value::List { vals: shells, span });
stack.add_env_var("NUSHELL_SHELLS".into(), Value::list(shells, span));
stack.add_env_var(
"NUSHELL_LAST_SHELL".into(),
Value::Int {
val: last_shell as i64,
span,
},
Value::int(last_shell as i64, span),
);
} else if !s.trim().is_empty() {
trace!("eval source: {}", s);
@ -607,10 +592,7 @@ pub fn evaluate_repl(
stack.add_env_var(
"CMD_DURATION_MS".into(),
Value::String {
val: format!("{}", cmd_duration.as_millis()),
span: Span::unknown(),
},
Value::string(format!("{}", cmd_duration.as_millis()), Span::unknown()),
);
if history_supports_meta && !s.is_empty() && line_editor.has_last_command_context()

View File

@ -185,10 +185,7 @@ fn gather_env_vars(
continue;
}
Value::String {
val: bytes,
span: *span,
}
Value::string(bytes, *span)
} else {
report_capture_error(
engine_state,