Refactor rarely changing engine state into its own struct (#3612)

* WIP

* Finish up EngineState refactor

* Fix Windows calls

* Fix Windows calls

* Fix Windows calls
This commit is contained in:
JT 2021-06-14 15:19:12 +12:00 committed by GitHub
parent 774be79321
commit de99e35106
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 133 additions and 93 deletions

View file

@ -167,7 +167,7 @@ pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn E
//Configure rustyline //Configure rustyline
let mut rl = default_rustyline_editor_configuration(); let mut rl = default_rustyline_editor_configuration();
let history_path = if let Some(cfg) = &context.configs.lock().global_config { let history_path = if let Some(cfg) = &context.configs().lock().global_config {
let _ = configure_rustyline_editor(&mut rl, cfg); let _ = configure_rustyline_editor(&mut rl, cfg);
let helper = Some(nu_line_editor_helper(&context, cfg)); let helper = Some(nu_line_editor_helper(&context, cfg));
rl.set_helper(helper); rl.set_helper(helper);
@ -182,7 +182,8 @@ pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn E
} }
//set vars from cfg if present //set vars from cfg if present
let (skip_welcome_message, prompt) = if let Some(cfg) = &context.configs.lock().global_config { let (skip_welcome_message, prompt) = if let Some(cfg) = &context.configs().lock().global_config
{
( (
cfg.var("skip_welcome_message") cfg.var("skip_welcome_message")
.map(|x| x.is_true()) .map(|x| x.is_true())
@ -217,12 +218,12 @@ pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn E
let mut ctrlcbreak = false; let mut ctrlcbreak = false;
loop { loop {
if context.ctrl_c.load(Ordering::SeqCst) { if context.ctrl_c().load(Ordering::SeqCst) {
context.ctrl_c.store(false, Ordering::SeqCst); context.ctrl_c().store(false, Ordering::SeqCst);
continue; continue;
} }
let cwd = context.shell_manager.path(); let cwd = context.shell_manager().path();
let colored_prompt = { let colored_prompt = {
if let Some(prompt) = &prompt { if let Some(prompt) = &prompt {
@ -266,14 +267,14 @@ pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn E
} }
} }
Err(e) => { Err(e) => {
context.host.lock().print_err(e, &Text::from(prompt_line)); context.host().lock().print_err(e, &Text::from(prompt_line));
context.clear_errors(); context.clear_errors();
"> ".to_string() "> ".to_string()
} }
}, },
Err(e) => { Err(e) => {
context.host.lock().print_err(e, &Text::from(prompt_line)); context.host().lock().print_err(e, &Text::from(prompt_line));
context.clear_errors(); context.clear_errors();
"> ".to_string() "> ".to_string()
@ -360,7 +361,7 @@ pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn E
} }
context context
.host .host()
.lock() .lock()
.print_err(err, &Text::from(session_text.clone())); .print_err(err, &Text::from(session_text.clone()));
@ -374,7 +375,7 @@ pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn E
LineResult::CtrlC => { LineResult::CtrlC => {
let config_ctrlc_exit = context let config_ctrlc_exit = context
.configs .configs()
.lock() .lock()
.global_config .global_config
.as_ref() .as_ref()
@ -400,8 +401,8 @@ pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn E
} }
LineResult::CtrlD => { LineResult::CtrlD => {
context.shell_manager.remove_at_current(); context.shell_manager().remove_at_current();
if context.shell_manager.is_empty() { if context.shell_manager().is_empty() {
break; break;
} }
} }
@ -423,15 +424,15 @@ pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn E
pub fn load_local_cfg_if_present(context: &EvaluationContext) { pub fn load_local_cfg_if_present(context: &EvaluationContext) {
trace!("Loading local cfg if present"); trace!("Loading local cfg if present");
match config::loadable_cfg_exists_in_dir(PathBuf::from(context.shell_manager.path())) { match config::loadable_cfg_exists_in_dir(PathBuf::from(context.shell_manager().path())) {
Ok(Some(cfg_path)) => { Ok(Some(cfg_path)) => {
if let Err(err) = context.load_config(&ConfigPath::Local(cfg_path)) { if let Err(err) = context.load_config(&ConfigPath::Local(cfg_path)) {
context.host.lock().print_err(err, &Text::from("")) context.host().lock().print_err(err, &Text::from(""))
} }
} }
Err(e) => { Err(e) => {
//Report error while checking for local cfg file //Report error while checking for local cfg file
context.host.lock().print_err(e, &Text::from("")) context.host().lock().print_err(e, &Text::from(""))
} }
Ok(None) => { Ok(None) => {
//No local cfg file present in start dir //No local cfg file present in start dir
@ -441,7 +442,7 @@ pub fn load_local_cfg_if_present(context: &EvaluationContext) {
fn load_cfg_as_global_cfg(context: &EvaluationContext, path: PathBuf) { fn load_cfg_as_global_cfg(context: &EvaluationContext, path: PathBuf) {
if let Err(err) = context.load_config(&ConfigPath::Global(path)) { if let Err(err) = context.load_config(&ConfigPath::Global(path)) {
context.host.lock().print_err(err, &Text::from("")); context.host().lock().print_err(err, &Text::from(""));
} }
} }
@ -451,7 +452,7 @@ pub fn load_global_cfg(context: &EvaluationContext) {
load_cfg_as_global_cfg(context, path); load_cfg_as_global_cfg(context, path);
} }
Err(e) => { Err(e) => {
context.host.lock().print_err(e, &Text::from("")); context.host().lock().print_err(e, &Text::from(""));
} }
} }
} }

View file

@ -258,14 +258,14 @@ pub fn rustyline_hinter(
pub fn configure_ctrl_c(_context: &EvaluationContext) -> Result<(), Box<dyn Error>> { pub fn configure_ctrl_c(_context: &EvaluationContext) -> Result<(), Box<dyn Error>> {
#[cfg(feature = "ctrlc")] #[cfg(feature = "ctrlc")]
{ {
let cc = _context.ctrl_c.clone(); let cc = _context.ctrl_c().clone();
ctrlc::set_handler(move || { ctrlc::set_handler(move || {
cc.store(true, Ordering::SeqCst); cc.store(true, Ordering::SeqCst);
})?; })?;
if _context.ctrl_c.load(Ordering::SeqCst) { if _context.ctrl_c().load(Ordering::SeqCst) {
_context.ctrl_c.store(false, Ordering::SeqCst); _context.ctrl_c().store(false, Ordering::SeqCst);
} }
} }

View file

@ -84,7 +84,7 @@ impl rustyline::highlight::Highlighter for Helper {
} }
fn highlight<'l>(&self, line: &'l str, _pos: usize) -> Cow<'l, str> { fn highlight<'l>(&self, line: &'l str, _pos: usize) -> Cow<'l, str> {
let cfg = &self.context.configs.lock(); let cfg = &self.context.configs().lock();
if let Some(palette) = &cfg.syntax_config { if let Some(palette) = &cfg.syntax_config {
Painter::paint_string(line, &self.context.scope, palette) Painter::paint_string(line, &self.context.scope, palette)
} else { } else {

View file

@ -59,7 +59,7 @@ pub fn autoview(args: CommandArgs) -> Result<OutputStream, ShellError> {
if let Some(x) = input_stream.next() { if let Some(x) = input_stream.next() {
match input_stream.next() { match input_stream.next() {
Some(y) => { Some(y) => {
let ctrl_c = context.ctrl_c.clone(); let ctrl_c = context.ctrl_c().clone();
let xy = vec![x, y]; let xy = vec![x, y];
let xy_stream = xy.into_iter().chain(input_stream).interruptible(ctrl_c); let xy_stream = xy.into_iter().chain(input_stream).interruptible(ctrl_c);
@ -192,7 +192,7 @@ pub fn autoview(args: CommandArgs) -> Result<OutputStream, ShellError> {
} => { } => {
let pivot_mode = configuration.pivot_mode(); let pivot_mode = configuration.pivot_mode();
let term_width = context.host.lock().width(); let term_width = context.host().lock().width();
if pivot_mode.is_always() if pivot_mode.is_always()
|| (pivot_mode.is_auto() || (pivot_mode.is_auto()
&& (row && (row

View file

@ -27,7 +27,7 @@ pub(crate) fn run_external_command(
trace!(target: "nu::run::external", "-> {}", command.name); trace!(target: "nu::run::external", "-> {}", command.name);
context.sync_path_to_env(); context.sync_path_to_env();
if !context.host.lock().is_external_cmd(&command.name) { if !context.host().lock().is_external_cmd(&command.name) {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"Command not found", "Command not found",
format!("command {} not found", &command.name), format!("command {} not found", &command.name),
@ -59,7 +59,7 @@ fn run_with_stdin(
input: InputStream, input: InputStream,
external_redirection: ExternalRedirection, external_redirection: ExternalRedirection,
) -> Result<InputStream, ShellError> { ) -> Result<InputStream, ShellError> {
let path = context.shell_manager.path(); let path = context.shell_manager().path();
let mut command_args = vec![]; let mut command_args = vec![];
for arg in command.args.iter() { for arg in command.args.iter() {

View file

@ -41,7 +41,7 @@ pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
let column_path = args.req(0)?; let column_path = args.req(0)?;
let result = if let Some(global_cfg) = &ctx.configs.lock().global_config { let result = if let Some(global_cfg) = &ctx.configs().lock().global_config {
let result = UntaggedValue::row(global_cfg.vars.clone()).into_value(&name); let result = UntaggedValue::row(global_cfg.vars.clone()).into_value(&name);
let value = crate::commands::get::get_column_path(&column_path, &result)?; let value = crate::commands::get::get_column_path(&column_path, &result)?;
Ok(match value { Ok(match value {

View file

@ -43,7 +43,7 @@ pub fn remove(args: CommandArgs) -> Result<OutputStream, ShellError> {
let key = remove.to_string(); let key = remove.to_string();
let result = if let Some(global_cfg) = &mut ctx.configs.lock().global_config { let result = if let Some(global_cfg) = &mut ctx.configs().lock().global_config {
if global_cfg.vars.contains_key(&key) { if global_cfg.vars.contains_key(&key) {
global_cfg.vars.swap_remove(&key); global_cfg.vars.swap_remove(&key);
global_cfg.write()?; global_cfg.write()?;

View file

@ -57,7 +57,7 @@ pub fn set(args: CommandArgs) -> Result<OutputStream, ShellError> {
let column_path = args.req(0)?; let column_path = args.req(0)?;
let mut value: Value = args.req(1)?; let mut value: Value = args.req(1)?;
let result = if let Some(global_cfg) = &mut ctx.configs.lock().global_config { let result = if let Some(global_cfg) = &mut ctx.configs().lock().global_config {
let configuration = UntaggedValue::row(global_cfg.vars.clone()).into_value(&name); let configuration = UntaggedValue::row(global_cfg.vars.clone()).into_value(&name);
if let UntaggedValue::Table(rows) = &value.value { if let UntaggedValue::Table(rows) = &value.value {

View file

@ -45,7 +45,7 @@ pub fn set_into(args: CommandArgs) -> Result<OutputStream, ShellError> {
let rows: Vec<Value> = args.input.collect(); let rows: Vec<Value> = args.input.collect();
let key = set_into.to_string(); let key = set_into.to_string();
let result = if let Some(global_cfg) = &mut ctx.configs.lock().global_config { let result = if let Some(global_cfg) = &mut ctx.configs().lock().global_config {
if rows.is_empty() { if rows.is_empty() {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"No values given for set_into", "No values given for set_into",

View file

@ -31,6 +31,7 @@ impl WholeStreamCommand for DataFrame {
} }
} }
#[allow(clippy::needless_collect)]
fn command(mut args: CommandArgs) -> Result<OutputStream, ShellError> { fn command(mut args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone(); let tag = args.call_info.name_tag.clone();

View file

@ -73,7 +73,7 @@ fn enter(args: CommandArgs) -> Result<ActionStream, ShellError> {
let head = args.call_info.args.head.clone(); let head = args.call_info.args.head.clone();
let context = args.context.clone(); let context = args.context.clone();
let scope = args.scope().clone(); let scope = args.scope().clone();
let path = args.context.shell_manager.path(); let path = args.context.shell_manager().path();
let location: Tagged<PathBuf> = args.req(0)?; let location: Tagged<PathBuf> = args.req(0)?;
let encoding: Option<Tagged<String>> = args.get_flag("encoding")?; let encoding: Option<Tagged<String>> = args.get_flag("encoding")?;

View file

@ -31,7 +31,7 @@ fn history(args: CommandArgs) -> Result<ActionStream, ShellError> {
let clear = args.has_flag("clear"); let clear = args.has_flag("clear");
let path = if let Some(global_cfg) = &ctx.configs.lock().global_config { let path = if let Some(global_cfg) = &ctx.configs().lock().global_config {
nu_data::config::path::history_path_or_default(global_cfg) nu_data::config::path::history_path_or_default(global_cfg)
} else { } else {
nu_data::config::path::default_history_path() nu_data::config::path::default_history_path()

View file

@ -102,7 +102,7 @@ impl WholeStreamCommand for RunExternalCommand {
}; };
let result = external_context let result = external_context
.shell_manager .shell_manager()
.cd(cd_args, args.call_info.name_tag); .cd(cd_args, args.call_info.name_tag);
return Ok(result?.to_action_stream()); return Ok(result?.to_action_stream());
@ -138,7 +138,7 @@ fn maybe_autocd_dir(cmd: &ExternalCommand, ctx: &mut EvaluationContext) -> Optio
|| (cmd.args.is_empty() || (cmd.args.is_empty()
&& PathBuf::from(name).is_dir() && PathBuf::from(name).is_dir()
&& dunce::canonicalize(name).is_ok() && dunce::canonicalize(name).is_ok()
&& !ctx.host.lock().is_external_cmd(name)) && !ctx.host().lock().is_external_cmd(name))
{ {
Some(name) Some(name)
} else { } else {
@ -151,11 +151,11 @@ fn maybe_autocd_dir(cmd: &ExternalCommand, ctx: &mut EvaluationContext) -> Optio
if name.ends_with(':') { if name.ends_with(':') {
// This looks like a drive shortcut. We need to a) switch drives and b) go back to the previous directory we were viewing on that drive // This looks like a drive shortcut. We need to a) switch drives and b) go back to the previous directory we were viewing on that drive
// But first, we need to save where we are now // But first, we need to save where we are now
let current_path = ctx.shell_manager.path(); let current_path = ctx.shell_manager().path();
let split_path: Vec<_> = current_path.split(':').collect(); let split_path: Vec<_> = current_path.split(':').collect();
if split_path.len() > 1 { if split_path.len() > 1 {
ctx.windows_drives_previous_cwd ctx.windows_drives_previous_cwd()
.lock() .lock()
.insert(split_path[0].to_string(), current_path); .insert(split_path[0].to_string(), current_path);
} }
@ -163,7 +163,7 @@ fn maybe_autocd_dir(cmd: &ExternalCommand, ctx: &mut EvaluationContext) -> Optio
let name = name.to_uppercase(); let name = name.to_uppercase();
let new_drive: Vec<_> = name.split(':').collect(); let new_drive: Vec<_> = name.split(':').collect();
if let Some(val) = ctx.windows_drives_previous_cwd.lock().get(new_drive[0]) { if let Some(val) = ctx.windows_drives_previous_cwd().lock().get(new_drive[0]) {
val.to_string() val.to_string()
} else { } else {
name name

View file

@ -27,23 +27,23 @@ impl CommandArgs {
} }
pub fn host(&self) -> Arc<parking_lot::Mutex<Box<dyn Host>>> { pub fn host(&self) -> Arc<parking_lot::Mutex<Box<dyn Host>>> {
self.context.host.clone() self.context.host().clone()
} }
pub fn current_errors(&self) -> Arc<Mutex<Vec<ShellError>>> { pub fn current_errors(&self) -> Arc<Mutex<Vec<ShellError>>> {
self.context.current_errors.clone() self.context.current_errors().clone()
} }
pub fn ctrl_c(&self) -> Arc<AtomicBool> { pub fn ctrl_c(&self) -> Arc<AtomicBool> {
self.context.ctrl_c.clone() self.context.ctrl_c().clone()
} }
pub fn configs(&self) -> Arc<Mutex<ConfigHolder>> { pub fn configs(&self) -> Arc<Mutex<ConfigHolder>> {
self.context.configs.clone() self.context.configs().clone()
} }
pub fn shell_manager(&self) -> ShellManager { pub fn shell_manager(&self) -> ShellManager {
self.context.shell_manager.clone() self.context.shell_manager().clone()
} }
pub fn nth(&self, pos: usize) -> Option<&SpannedExpression> { pub fn nth(&self, pos: usize) -> Option<&SpannedExpression> {

View file

@ -60,7 +60,7 @@ pub fn run_block(
ctx.clear_errors(); ctx.clear_errors();
return Err(err.clone()); return Err(err.clone());
} }
if ctx.ctrl_c.load(Ordering::SeqCst) { if ctx.ctrl_c().load(Ordering::SeqCst) {
return Ok(InputStream::empty()); return Ok(InputStream::empty());
} }
} }
@ -96,7 +96,7 @@ pub fn run_block(
ctx.clear_errors(); ctx.clear_errors();
return Err(err.clone()); return Err(err.clone());
} }
if ctx.ctrl_c.load(Ordering::SeqCst) { if ctx.ctrl_c().load(Ordering::SeqCst) {
// This early return doesn't return the result // This early return doesn't return the result
// we have so far, but breaking out of this loop // we have so far, but breaking out of this loop
// causes lifetime issues. A future contribution // causes lifetime issues. A future contribution

View file

@ -79,7 +79,7 @@ impl Iterator for InternalIterator {
match item { match item {
Ok(ReturnSuccess::Action(action)) => match action { Ok(ReturnSuccess::Action(action)) => match action {
CommandAction::ChangePath(path) => { CommandAction::ChangePath(path) => {
self.context.shell_manager.set_path(path); self.context.shell_manager().set_path(path);
} }
CommandAction::Exit(code) => std::process::exit(code), // TODO: save history.txt CommandAction::Exit(code) => std::process::exit(code), // TODO: save history.txt
CommandAction::Error(err) => { CommandAction::Error(err) => {
@ -135,16 +135,16 @@ impl Iterator for InternalIterator {
} }
CommandAction::EnterValueShell(value) => { CommandAction::EnterValueShell(value) => {
self.context self.context
.shell_manager .shell_manager()
.insert_at_current(Box::new(ValueShell::new(value))); .insert_at_current(Box::new(ValueShell::new(value)));
} }
CommandAction::EnterShell(location) => { CommandAction::EnterShell(location) => {
let mode = if self.context.shell_manager.is_interactive() { let mode = if self.context.shell_manager().is_interactive() {
FilesystemShellMode::Cli FilesystemShellMode::Cli
} else { } else {
FilesystemShellMode::Script FilesystemShellMode::Script
}; };
self.context.shell_manager.insert_at_current(Box::new( self.context.shell_manager().insert_at_current(Box::new(
match FilesystemShell::with_location(location, mode) { match FilesystemShell::with_location(location, mode) {
Ok(v) => v, Ok(v) => v,
Err(err) => { Err(err) => {
@ -172,14 +172,14 @@ impl Iterator for InternalIterator {
} }
} }
CommandAction::PreviousShell => { CommandAction::PreviousShell => {
self.context.shell_manager.prev(); self.context.shell_manager().prev();
} }
CommandAction::NextShell => { CommandAction::NextShell => {
self.context.shell_manager.next(); self.context.shell_manager().next();
} }
CommandAction::LeaveShell(code) => { CommandAction::LeaveShell(code) => {
self.context.shell_manager.remove_at_current(); self.context.shell_manager().remove_at_current();
if self.context.shell_manager.is_empty() { if self.context.shell_manager().is_empty() {
std::process::exit(code); // TODO: save history.txt std::process::exit(code); // TODO: save history.txt
} }
} }

View file

@ -30,7 +30,7 @@ pub fn nu(
UntaggedValue::filepath(default_history_path()).into_value(&tag), UntaggedValue::filepath(default_history_path()).into_value(&tag),
); );
if let Some(global_cfg) = &ctx.configs.lock().global_config { if let Some(global_cfg) = &ctx.configs().lock().global_config {
nu_dict.insert_value( nu_dict.insert_value(
"config", "config",
UntaggedValue::row(global_cfg.vars.clone()).into_value(&tag), UntaggedValue::row(global_cfg.vars.clone()).into_value(&tag),

View file

@ -20,8 +20,7 @@ use std::sync::atomic::AtomicBool;
use std::{path::Path, sync::Arc}; use std::{path::Path, sync::Arc};
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct EvaluationContext { pub struct EngineState {
pub scope: Scope,
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>, pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
pub current_errors: Arc<Mutex<Vec<ShellError>>>, pub current_errors: Arc<Mutex<Vec<ShellError>>>,
pub ctrl_c: Arc<AtomicBool>, pub ctrl_c: Arc<AtomicBool>,
@ -31,6 +30,11 @@ pub struct EvaluationContext {
/// Windows-specific: keep track of previous cwd on each drive /// Windows-specific: keep track of previous cwd on each drive
pub windows_drives_previous_cwd: Arc<Mutex<std::collections::HashMap<String, String>>>, pub windows_drives_previous_cwd: Arc<Mutex<std::collections::HashMap<String, String>>>,
} }
#[derive(Clone, Default)]
pub struct EvaluationContext {
pub scope: Scope,
engine_state: Arc<EngineState>,
}
impl EvaluationContext { impl EvaluationContext {
pub fn new( pub fn new(
@ -44,12 +48,14 @@ impl EvaluationContext {
) -> Self { ) -> Self {
Self { Self {
scope, scope,
engine_state: Arc::new(EngineState {
host, host,
current_errors, current_errors,
ctrl_c, ctrl_c,
configs, configs,
shell_manager, shell_manager,
windows_drives_previous_cwd, windows_drives_previous_cwd,
}),
} }
} }
@ -61,12 +67,14 @@ impl EvaluationContext {
EvaluationContext { EvaluationContext {
scope, scope,
engine_state: Arc::new(EngineState {
host: Arc::new(parking_lot::Mutex::new(Box::new(host))), host: Arc::new(parking_lot::Mutex::new(Box::new(host))),
current_errors: Arc::new(Mutex::new(vec![])), current_errors: Arc::new(Mutex::new(vec![])),
ctrl_c: Arc::new(AtomicBool::new(false)), ctrl_c: Arc::new(AtomicBool::new(false)),
configs: Arc::new(Mutex::new(ConfigHolder::new())), configs: Arc::new(Mutex::new(ConfigHolder::new())),
shell_manager: ShellManager::basic(), shell_manager: ShellManager::basic(),
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())), windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
}),
} }
} }
@ -74,12 +82,38 @@ impl EvaluationContext {
self.with_errors(|errors| errors.push(error)) self.with_errors(|errors| errors.push(error))
} }
pub fn host(&self) -> &Arc<parking_lot::Mutex<Box<dyn Host>>> {
&self.engine_state.host
}
pub fn current_errors(&self) -> &Arc<Mutex<Vec<ShellError>>> {
&self.engine_state.current_errors
}
pub fn ctrl_c(&self) -> &Arc<AtomicBool> {
&self.engine_state.ctrl_c
}
pub fn configs(&self) -> &Arc<Mutex<ConfigHolder>> {
&self.engine_state.configs
}
pub fn shell_manager(&self) -> &ShellManager {
&self.engine_state.shell_manager
}
pub fn windows_drives_previous_cwd(
&self,
) -> &Arc<Mutex<std::collections::HashMap<String, String>>> {
&self.engine_state.windows_drives_previous_cwd
}
pub fn clear_errors(&self) { pub fn clear_errors(&self) {
self.current_errors.lock().clear() self.engine_state.current_errors.lock().clear()
} }
pub fn get_errors(&self) -> Vec<ShellError> { pub fn get_errors(&self) -> Vec<ShellError> {
self.current_errors.lock().clone() self.engine_state.current_errors.lock().clone()
} }
pub fn configure<T>( pub fn configure<T>(
@ -91,13 +125,13 @@ impl EvaluationContext {
} }
pub fn with_host<T>(&self, block: impl FnOnce(&mut dyn Host) -> T) -> T { pub fn with_host<T>(&self, block: impl FnOnce(&mut dyn Host) -> T) -> T {
let mut host = self.host.lock(); let mut host = self.engine_state.host.lock();
block(&mut *host) block(&mut *host)
} }
pub fn with_errors<T>(&self, block: impl FnOnce(&mut Vec<ShellError>) -> T) -> T { pub fn with_errors<T>(&self, block: impl FnOnce(&mut Vec<ShellError>) -> T) -> T {
let mut errors = self.current_errors.lock(); let mut errors = self.engine_state.current_errors.lock();
block(&mut *errors) block(&mut *errors)
} }
@ -209,9 +243,9 @@ impl EvaluationContext {
self.scope.set_exit_scripts(exit_scripts); self.scope.set_exit_scripts(exit_scripts);
match cfg_path { match cfg_path {
ConfigPath::Global(_) => self.configs.lock().set_global_cfg(cfg), ConfigPath::Global(_) => self.engine_state.configs.lock().set_global_cfg(cfg),
ConfigPath::Local(_) => { ConfigPath::Local(_) => {
self.configs.lock().add_local_cfg(cfg); self.engine_state.configs.lock().add_local_cfg(cfg);
} }
} }
@ -221,7 +255,7 @@ impl EvaluationContext {
// folder as the config.toml // folder as the config.toml
// Let's open the config // Let's open the config
let global_config = self.configs.lock().global_config(); let global_config = self.engine_state.configs.lock().global_config();
// Get the root syntax_theme value // Get the root syntax_theme value
let syntax_theme = global_config.var("syntax_theme"); let syntax_theme = global_config.var("syntax_theme");
// If we have a syntax_theme let's process it // If we have a syntax_theme let's process it
@ -246,16 +280,18 @@ impl EvaluationContext {
let mut reader = BufReader::new(syntax_theme_file); let mut reader = BufReader::new(syntax_theme_file);
let theme = ThemedPalette::new(&mut reader).unwrap_or_default(); let theme = ThemedPalette::new(&mut reader).unwrap_or_default();
// eprintln!("Theme: [{:?}]", theme); // eprintln!("Theme: [{:?}]", theme);
self.configs.lock().set_syntax_colors(theme); self.engine_state.configs.lock().set_syntax_colors(theme);
} else { } else {
// If the file was missing, use the default // If the file was missing, use the default
self.configs self.engine_state
.configs
.lock() .lock()
.set_syntax_colors(ThemedPalette::default()) .set_syntax_colors(ThemedPalette::default())
} }
} else { } else {
// if there's no syntax_theme, use the default // if there's no syntax_theme, use the default
self.configs self.engine_state
.configs
.lock() .lock()
.set_syntax_colors(ThemedPalette::default()) .set_syntax_colors(ThemedPalette::default())
}; };
@ -336,7 +372,7 @@ impl EvaluationContext {
} }
//Unload config //Unload config
self.configs.lock().remove_cfg(cfg_path); self.engine_state.configs.lock().remove_cfg(cfg_path);
self.scope.exit_scope_with_tag(&tag); self.scope.exit_scope_with_tag(&tag);
} }
@ -353,7 +389,7 @@ impl EvaluationContext {
e e
)); ));
let text = script.into(); let text = script.into();
self.host.lock().print_err(err, &text); self.engine_state.host.lock().print_err(err, &text);
} }
} }
} }

View file

@ -3,14 +3,14 @@ use nu_source::Text;
use crate::EvaluationContext; use crate::EvaluationContext;
pub fn maybe_print_errors(context: &EvaluationContext, source: Text) -> bool { pub fn maybe_print_errors(context: &EvaluationContext, source: Text) -> bool {
let errors = context.current_errors.clone(); let errors = context.current_errors().clone();
let mut errors = errors.lock(); let mut errors = errors.lock();
if errors.len() > 0 { if errors.len() > 0 {
let error = errors[0].clone(); let error = errors[0].clone();
*errors = vec![]; *errors = vec![];
context.host.lock().print_err(error, &source); context.host().lock().print_err(error, &source);
true true
} else { } else {
false false

View file

@ -42,12 +42,12 @@ pub fn run_script_in_dir(
ctx: &EvaluationContext, ctx: &EvaluationContext,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
//Save path before to switch back to it after executing script //Save path before to switch back to it after executing script
let path_before = ctx.shell_manager.path(); let path_before = ctx.shell_manager().path();
ctx.shell_manager ctx.shell_manager()
.set_path(dir.to_string_lossy().to_string()); .set_path(dir.to_string_lossy().to_string());
run_script_standalone(script, false, ctx, false)?; run_script_standalone(script, false, ctx, false)?;
ctx.shell_manager.set_path(path_before); ctx.shell_manager().set_path(path_before);
Ok(()) Ok(())
} }
@ -118,9 +118,9 @@ pub fn process_script(
.as_ref() .as_ref()
.map(NamedArguments::is_empty) .map(NamedArguments::is_empty)
.unwrap_or(true) .unwrap_or(true)
&& canonicalize(ctx.shell_manager.path(), name).is_ok() && canonicalize(ctx.shell_manager().path(), name).is_ok()
&& Path::new(&name).is_dir() && Path::new(&name).is_dir()
&& !ctx.host.lock().is_external_cmd(name) && !ctx.host().lock().is_external_cmd(name)
{ {
let tag = Tag { let tag = Tag {
anchor: Some(AnchorLocation::Source(line.into())), anchor: Some(AnchorLocation::Source(line.into())),
@ -133,11 +133,11 @@ pub fn process_script(
if name.ends_with(':') { if name.ends_with(':') {
// This looks like a drive shortcut. We need to a) switch drives and b) go back to the previous directory we were viewing on that drive // This looks like a drive shortcut. We need to a) switch drives and b) go back to the previous directory we were viewing on that drive
// But first, we need to save where we are now // But first, we need to save where we are now
let current_path = ctx.shell_manager.path(); let current_path = ctx.shell_manager().path();
let split_path: Vec<_> = current_path.split(':').collect(); let split_path: Vec<_> = current_path.split(':').collect();
if split_path.len() > 1 { if split_path.len() > 1 {
ctx.windows_drives_previous_cwd ctx.windows_drives_previous_cwd()
.lock() .lock()
.insert(split_path[0].to_string(), current_path); .insert(split_path[0].to_string(), current_path);
} }
@ -146,7 +146,7 @@ pub fn process_script(
let new_drive: Vec<_> = name.split(':').collect(); let new_drive: Vec<_> = name.split(':').collect();
if let Some(val) = if let Some(val) =
ctx.windows_drives_previous_cwd.lock().get(new_drive[0]) ctx.windows_drives_previous_cwd().lock().get(new_drive[0])
{ {
val.to_string() val.to_string()
} else { } else {
@ -169,7 +169,7 @@ pub fn process_script(
}), }),
}; };
return match ctx.shell_manager.cd(cd_args, tag) { return match ctx.shell_manager().cd(cd_args, tag) {
Err(e) => LineResult::Error(line.to_string(), e), Err(e) => LineResult::Error(line.to_string(), e),
Ok(stream) => { Ok(stream) => {
let iter = InternalIterator { let iter = InternalIterator {
@ -244,7 +244,7 @@ pub fn process_script(
.. ..
}) => return LineResult::Error(line.to_string(), e), }) => return LineResult::Error(line.to_string(), e),
Some(_item) => { Some(_item) => {
if ctx.ctrl_c.load(Ordering::SeqCst) { if ctx.ctrl_c().load(Ordering::SeqCst) {
break; break;
} }
} }
@ -267,7 +267,7 @@ pub fn run_script_standalone(
exit_on_error: bool, exit_on_error: bool,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
context context
.shell_manager .shell_manager()
.enter_script_mode() .enter_script_mode()
.map_err(Box::new)?; .map_err(Box::new)?;
let line = process_script(&script_text, context, redirect_stdin, 0, false); let line = process_script(&script_text, context, redirect_stdin, 0, false);
@ -275,7 +275,7 @@ pub fn run_script_standalone(
match line { match line {
LineResult::Success(line) => { LineResult::Success(line) => {
let error_code = { let error_code = {
let errors = context.current_errors.clone(); let errors = context.current_errors().clone();
let errors = errors.lock(); let errors = errors.lock();
if errors.len() > 0 { if errors.len() > 0 {
@ -293,7 +293,7 @@ pub fn run_script_standalone(
LineResult::Error(line, err) => { LineResult::Error(line, err) => {
context context
.host .host()
.lock() .lock()
.print_err(err, &Text::from(line.clone())); .print_err(err, &Text::from(line.clone()));
@ -307,7 +307,7 @@ pub fn run_script_standalone(
} }
//exit script mode shell //exit script mode shell
context.shell_manager.remove_at_current(); context.shell_manager().remove_at_current();
Ok(()) Ok(())
} }

View file

@ -134,6 +134,7 @@ impl NuDataFrame {
from_parsed_columns(column_values, tag) from_parsed_columns(column_values, tag)
} }
#[allow(clippy::clippy::wrong_self_convention)]
pub fn to_value(self, tag: Tag) -> Value { pub fn to_value(self, tag: Tag) -> Value {
Value { Value {
value: UntaggedValue::DataFrame(PolarsData::EagerDataFrame(self)), value: UntaggedValue::DataFrame(PolarsData::EagerDataFrame(self)),

View file

@ -97,6 +97,7 @@ impl NuSeries {
from_parsed_vector(vec_values, name) from_parsed_vector(vec_values, name)
} }
#[allow(clippy::clippy::wrong_self_convention)]
pub fn to_value(self, tag: Tag) -> Value { pub fn to_value(self, tag: Tag) -> Value {
Value { Value {
value: UntaggedValue::DataFrame(PolarsData::Series(self)), value: UntaggedValue::DataFrame(PolarsData::Series(self)),