mirror of
https://github.com/nushell/nushell.git
synced 2025-05-21 10:20:46 +02:00
# Description Our config exists both as a `Config` struct for internal consumption and as a `Value`. The latter is exposed through `$env.config` and can be both set and read. Thus we have a complex bug-prone mechanism, that reads a `Value` and then tries to plug anything where the value is unrepresentable in `Config` with the correct state from `Config`. The parsing involves therefore mutation of the `Value` in a nested `Record` structure. Previously this was wholy done manually, with indices. To enable deletion for example, things had to be iterated over from the back. Also things were indexed in a bunch of places. This was hard to read and an invitation for bugs. With #10876 we can now use `Record::retain_mut` to traverse the records, modify anything that needs fixing, and drop invalid fields. # Parts: - Error messages now consistently use the correct spans pointing to the problematic value and the paths displayed in some messages are also aligned with the keys used for lookup. - Reconstruction of values has been fixed for: - `table.padding` - `buffer_editor` - `hooks.command_not_found` - `datetime_format` (partial solution) - Fix validation of `table.padding` input so value is not set (and underflows `usize` causing `table` to run forever with negative values) - New proper types for settings. Fully validated enums instead of strings: - `config.edit_mode` -> `EditMode` - Don't fall back to vi-mode on invalid string - `config.table.mode` -> `TableMode` - there is still a fall back to `rounded` if given an invalid `TableMode` as argument to the `nu` binary - `config.completions.algorithm` -> `CompletionAlgorithm` - `config.error_style` -> `ErrorStyle` - don't implicitly fall back to `fancy` when given an invalid value. - This should also shrink the size of `Config` as instead of 4x24 bytes those fields now need only 4x1 bytes in `Config` - Completely removed macros relying on the scope of `Value::into_config` so we can break it up into smaller parts in the future. - Factored everything into smaller files with the types and helpers for particular topics. - `NuCursorShape` now explicitly expresses the `Inherit` setting. conversion to option only happens at the interface to `reedline`
74 lines
2.3 KiB
Rust
74 lines
2.3 KiB
Rust
use log::info;
|
|
use miette::Result;
|
|
use nu_engine::{convert_env_values, eval_block};
|
|
use nu_parser::parse;
|
|
use nu_protocol::engine::Stack;
|
|
use nu_protocol::report_error;
|
|
use nu_protocol::{
|
|
engine::{EngineState, StateWorkingSet},
|
|
PipelineData, Spanned, Value,
|
|
};
|
|
|
|
/// Run a command (or commands) given to us by the user
|
|
pub fn evaluate_commands(
|
|
commands: &Spanned<String>,
|
|
engine_state: &mut EngineState,
|
|
stack: &mut Stack,
|
|
input: PipelineData,
|
|
table_mode: Option<Value>,
|
|
) -> Result<Option<i64>> {
|
|
// Translate environment variables from Strings to Values
|
|
if let Some(e) = convert_env_values(engine_state, stack) {
|
|
let working_set = StateWorkingSet::new(engine_state);
|
|
report_error(&working_set, &e);
|
|
std::process::exit(1);
|
|
}
|
|
|
|
// Parse the source code
|
|
let (block, delta) = {
|
|
if let Some(ref t_mode) = table_mode {
|
|
let mut config = engine_state.get_config().clone();
|
|
config.table_mode = t_mode.as_string()?.parse().unwrap_or_default();
|
|
engine_state.set_config(config);
|
|
}
|
|
|
|
let mut working_set = StateWorkingSet::new(engine_state);
|
|
|
|
let output = parse(&mut working_set, None, commands.item.as_bytes(), false);
|
|
if let Some(err) = working_set.parse_errors.first() {
|
|
report_error(&working_set, err);
|
|
|
|
std::process::exit(1);
|
|
}
|
|
|
|
(output, working_set.render())
|
|
};
|
|
|
|
// Update permanent state
|
|
if let Err(err) = engine_state.merge_delta(delta) {
|
|
let working_set = StateWorkingSet::new(engine_state);
|
|
report_error(&working_set, &err);
|
|
}
|
|
|
|
// Run the block
|
|
let exit_code = match eval_block(engine_state, stack, &block, input, false, false) {
|
|
Ok(pipeline_data) => {
|
|
let mut config = engine_state.get_config().clone();
|
|
if let Some(t_mode) = table_mode {
|
|
config.table_mode = t_mode.as_string()?.parse().unwrap_or_default();
|
|
}
|
|
crate::eval_file::print_table_or_error(engine_state, stack, pipeline_data, &mut config)
|
|
}
|
|
Err(err) => {
|
|
let working_set = StateWorkingSet::new(engine_state);
|
|
|
|
report_error(&working_set, &err);
|
|
std::process::exit(1);
|
|
}
|
|
};
|
|
|
|
info!("evaluate {}:{}:{}", file!(), line!(), column!());
|
|
|
|
Ok(exit_code)
|
|
}
|