Context cleanup (#2581)

* Specialize 'Context' to EvaluationContext and CompletionContext

* Specialize 'Context' to EvaluationContext and CompletionContext

* fmt
This commit is contained in:
Jonathan Turner 2020-09-20 09:29:51 +12:00 committed by GitHub
parent 798766b4b5
commit 1882a32b83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
77 changed files with 433 additions and 461 deletions

View File

@ -1,6 +1,6 @@
use crate::commands::classified::block::run_block;
use crate::commands::classified::maybe_text_codec::{MaybeTextCodec, StringOrBinary};
use crate::context::Context;
use crate::evaluation_context::EvaluationContext;
use crate::path::canonicalize;
use crate::prelude::*;
#[cfg(feature = "rustyline-support")]
@ -56,8 +56,8 @@ pub fn search_paths() -> Vec<std::path::PathBuf> {
search_paths
}
pub fn create_default_context(interactive: bool) -> Result<Context, Box<dyn Error>> {
let mut context = Context::basic()?;
pub fn create_default_context(interactive: bool) -> Result<EvaluationContext, Box<dyn Error>> {
let mut context = EvaluationContext::basic()?;
{
use crate::commands::*;
@ -325,7 +325,7 @@ fn convert_rustyline_result_to_string(input: Result<String, ReadlineError>) -> L
/// The entry point for the CLI. Will register all known internal commands, load experimental commands, load plugins, then prepare the prompt and line reader for input.
#[cfg(feature = "rustyline-support")]
pub async fn cli(mut context: Context) -> Result<(), Box<dyn Error>> {
pub async fn cli(mut context: EvaluationContext) -> Result<(), Box<dyn Error>> {
let mut syncer = EnvironmentSyncer::new();
let configuration = syncer.get_config();
@ -538,7 +538,7 @@ pub async fn cli(mut context: Context) -> Result<(), Box<dyn Error>> {
Ok(())
}
pub fn register_plugins(context: &mut Context) -> Result<(), ShellError> {
pub fn register_plugins(context: &mut EvaluationContext) -> Result<(), ShellError> {
if let Ok(plugins) = crate::plugin::scan(search_paths()) {
context.add_commands(
plugins
@ -551,7 +551,7 @@ pub fn register_plugins(context: &mut Context) -> Result<(), ShellError> {
Ok(())
}
fn configure_ctrl_c(_context: &mut Context) -> Result<(), Box<dyn Error>> {
fn configure_ctrl_c(_context: &mut EvaluationContext) -> Result<(), Box<dyn Error>> {
#[cfg(feature = "ctrlc")]
{
let cc = _context.ctrl_c.clone();
@ -569,7 +569,7 @@ fn configure_ctrl_c(_context: &mut Context) -> Result<(), Box<dyn Error>> {
}
async fn run_startup_commands(
context: &mut Context,
context: &mut EvaluationContext,
config: &dyn nu_data::config::Conf,
) -> Result<(), ShellError> {
if let Some(commands) = config.var("startup") {
@ -599,7 +599,7 @@ async fn run_startup_commands(
pub async fn run_pipeline_standalone(
pipeline: String,
redirect_stdin: bool,
context: &mut Context,
context: &mut EvaluationContext,
exit_on_error: bool,
) -> Result<(), Box<dyn Error>> {
let line = process_line(&pipeline, context, redirect_stdin, false).await;
@ -798,7 +798,7 @@ fn configure_rustyline_editor(
#[cfg(feature = "rustyline-support")]
fn nu_line_editor_helper(
context: &mut Context,
context: &mut EvaluationContext,
config: &dyn nu_data::config::Conf,
) -> crate::shell::Helper {
let hinter = rustyline_hinter(config);
@ -834,7 +834,7 @@ pub enum LineResult {
Break,
}
pub async fn parse_and_eval(line: &str, ctx: &mut Context) -> Result<String, ShellError> {
pub async fn parse_and_eval(line: &str, ctx: &mut EvaluationContext) -> Result<String, ShellError> {
let line = if line.ends_with('\n') {
&line[..line.len() - 1]
} else {
@ -867,7 +867,7 @@ pub async fn parse_and_eval(line: &str, ctx: &mut Context) -> Result<String, She
/// Process the line by parsing the text to turn it into commands, classify those commands so that we understand what is being called in the pipeline, and then run this pipeline
pub async fn process_line(
line: &str,
ctx: &mut Context,
ctx: &mut EvaluationContext,
redirect_stdin: bool,
cli_mode: bool,
) -> LineResult {
@ -1085,7 +1085,7 @@ mod tests {
#[quickcheck]
fn quickcheck_parse(data: String) -> bool {
if let Ok(lite_block) = nu_parser::lite_parse(&data, 0) {
let context = crate::context::Context::basic().unwrap();
let context = crate::evaluation_context::EvaluationContext::basic().unwrap();
let _ = nu_parser::classify_block(&lite_block, context.registry());
}
true

View File

@ -0,0 +1,64 @@
use crate::commands::Command;
use indexmap::IndexMap;
use nu_errors::ShellError;
use nu_parser::SignatureRegistry;
use nu_protocol::Signature;
use parking_lot::Mutex;
use std::sync::Arc;
#[derive(Debug, Clone, Default)]
pub struct CommandRegistry {
registry: Arc<Mutex<IndexMap<String, Command>>>,
}
impl SignatureRegistry for CommandRegistry {
fn has(&self, name: &str) -> bool {
let registry = self.registry.lock();
registry.contains_key(name)
}
fn get(&self, name: &str) -> Option<Signature> {
let registry = self.registry.lock();
registry.get(name).map(|command| command.signature())
}
fn clone_box(&self) -> Box<dyn SignatureRegistry> {
Box::new(self.clone())
}
}
impl CommandRegistry {
pub fn new() -> CommandRegistry {
CommandRegistry {
registry: Arc::new(Mutex::new(IndexMap::default())),
}
}
}
impl CommandRegistry {
pub fn get_command(&self, name: &str) -> Option<Command> {
let registry = self.registry.lock();
registry.get(name).cloned()
}
pub fn expect_command(&self, name: &str) -> Result<Command, ShellError> {
self.get_command(name).ok_or_else(|| {
ShellError::untagged_runtime_error(format!("Could not load command: {}", name))
})
}
pub fn has(&self, name: &str) -> bool {
let registry = self.registry.lock();
registry.contains_key(name)
}
pub fn insert(&mut self, name: impl Into<String>, command: Command) {
let mut registry = self.registry.lock();
registry.insert(name.into(), command);
}
pub fn names(&self) -> Vec<String> {
let registry = self.registry.lock();
registry.keys().cloned().collect()
}
}

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_data::config;
use nu_errors::ShellError;

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};

View File

@ -58,7 +58,7 @@ async fn benchmark(
let registry = registry.clone();
let tag = raw_args.call_info.args.span;
let mut context = Context::from_raw(&raw_args, &registry);
let mut context = EvaluationContext::from_raw(&raw_args, &registry);
let scope = raw_args.call_info.scope.clone();
let (BenchmarkArgs { block }, input) = raw_args.process(&registry).await?;
@ -114,7 +114,7 @@ async fn benchmark(
let registry = registry.clone();
let tag = raw_args.call_info.args.span;
let mut context = Context::from_raw(&raw_args, &registry);
let mut context = EvaluationContext::from_raw(&raw_args, &registry);
let scope = raw_args.call_info.scope.clone();
let (BenchmarkArgs { block }, input) = raw_args.process(&registry).await?;

View File

@ -1,6 +1,6 @@
use crate::commands::classified::expr::run_expression_block;
use crate::commands::classified::internal::run_internal_command;
use crate::context::Context;
use crate::evaluation_context::EvaluationContext;
use crate::prelude::*;
use crate::stream::InputStream;
use futures::stream::TryStreamExt;
@ -11,7 +11,7 @@ use std::sync::atomic::Ordering;
pub(crate) async fn run_block(
block: &Block,
ctx: &mut Context,
ctx: &mut EvaluationContext,
mut input: InputStream,
it: &Value,
vars: &IndexMap<String, Value>,
@ -64,7 +64,7 @@ pub(crate) async fn run_block(
async fn run_pipeline(
commands: &Commands,
ctx: &mut Context,
ctx: &mut EvaluationContext,
mut input: InputStream,
it: &Value,
vars: &IndexMap<String, Value>,

View File

@ -10,7 +10,7 @@ use nu_protocol::Value;
pub(crate) async fn run_expression_block(
expr: SpannedExpression,
context: &mut Context,
context: &mut EvaluationContext,
it: &Value,
vars: &IndexMap<String, Value>,
env: &IndexMap<String, String>,

View File

@ -19,7 +19,7 @@ use nu_source::Tag;
pub(crate) async fn run_external_command(
command: ExternalCommand,
context: &mut Context,
context: &mut EvaluationContext,
input: InputStream,
scope: &Scope,
external_redirection: ExternalRedirection,
@ -39,7 +39,7 @@ pub(crate) async fn run_external_command(
async fn run_with_stdin(
command: ExternalCommand,
context: &mut Context,
context: &mut EvaluationContext,
input: InputStream,
scope: &Scope,
external_redirection: ExternalRedirection,
@ -543,7 +543,7 @@ mod tests {
add_quotes, argument_contains_whitespace, argument_is_quoted, expand_tilde, remove_quotes,
};
#[cfg(feature = "which")]
use super::{run_external_command, Context, InputStream};
use super::{run_external_command, EvaluationContext, InputStream};
#[cfg(feature = "which")]
use futures::executor::block_on;
@ -573,7 +573,8 @@ mod tests {
let cmd = ExternalBuilder::for_name("i_dont_exist.exe").build();
let input = InputStream::empty();
let mut ctx = Context::basic().expect("There was a problem creating a basic context.");
let mut ctx =
EvaluationContext::basic().expect("There was a problem creating a basic context.");
assert!(run_external_command(
cmd,
@ -591,7 +592,7 @@ mod tests {
// async fn failure_run() -> Result<(), ShellError> {
// let cmd = ExternalBuilder::for_name("fail").build();
// let mut ctx = Context::basic().expect("There was a problem creating a basic context.");
// let mut ctx = EvaluationContext::basic().expect("There was a problem creating a basic context.");
// let stream = run_external_command(cmd, &mut ctx, None, false)
// .await?
// .expect("There was a problem running the external command.");

View File

@ -9,7 +9,7 @@ use nu_protocol::{CommandAction, Primitive, ReturnSuccess, Scope, UntaggedValue,
pub(crate) async fn run_internal_command(
command: InternalCommand,
context: &mut Context,
context: &mut EvaluationContext,
input: InputStream,
it: &Value,
vars: &IndexMap<String, Value>,

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use futures::stream::StreamExt;
use nu_errors::ShellError;

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::help::get_help;
use crate::context::CommandRegistry;
use crate::deserializer::ConfigDeserializer;
use crate::evaluate::evaluate_args::evaluate_args;
use crate::prelude::*;

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use futures::future;
use futures::stream::StreamExt;

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use futures::stream::StreamExt;
use nu_errors::ShellError;

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};

View File

@ -65,7 +65,7 @@ async fn do_(
let registry = registry.clone();
let external_redirection = raw_args.call_info.args.external_redirection;
let mut context = Context::from_raw(&raw_args, &registry);
let mut context = EvaluationContext::from_raw(&raw_args, &registry);
let scope = raw_args.call_info.scope.clone();
let (
DoArgs {

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape, UntaggedValue};

View File

@ -1,6 +1,6 @@
use crate::command_registry::CommandRegistry;
use crate::commands::classified::block::run_block;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use futures::stream::once;
@ -84,7 +84,7 @@ pub async fn process_row(
block: Arc<Block>,
scope: Arc<Scope>,
head: Arc<Box<SpannedExpression>>,
mut context: Arc<Context>,
mut context: Arc<EvaluationContext>,
input: Value,
) -> Result<OutputStream, ShellError> {
let input_clone = input.clone();
@ -120,7 +120,7 @@ async fn each(
let registry = registry.clone();
let head = Arc::new(raw_args.call_info.args.head.clone());
let scope = Arc::new(raw_args.call_info.scope.clone());
let context = Arc::new(Context::from_raw(&raw_args, &registry));
let context = Arc::new(EvaluationContext::from_raw(&raw_args, &registry));
let (each_args, input): (EachArgs, _) = raw_args.process(&registry).await?;
let block = Arc::new(each_args.block);

View File

@ -54,7 +54,7 @@ impl WholeStreamCommand for EachGroup {
let registry = registry.clone();
let head = Arc::new(raw_args.call_info.args.head.clone());
let scope = Arc::new(raw_args.call_info.scope.clone());
let context = Arc::new(Context::from_raw(&raw_args, &registry));
let context = Arc::new(EvaluationContext::from_raw(&raw_args, &registry));
let (each_args, input): (EachGroupArgs, _) = raw_args.process(&registry).await?;
let block = Arc::new(each_args.block);
@ -79,7 +79,7 @@ pub(crate) fn run_block_on_vec(
block: Arc<Block>,
scope: Arc<Scope>,
head: Arc<Box<SpannedExpression>>,
context: Arc<Context>,
context: Arc<EvaluationContext>,
) -> impl Future<Output = OutputStream> {
let value = Value {
value: UntaggedValue::Table(input),

View File

@ -58,7 +58,7 @@ impl WholeStreamCommand for EachWindow {
let registry = registry.clone();
let head = Arc::new(raw_args.call_info.args.head.clone());
let scope = Arc::new(raw_args.call_info.scope.clone());
let context = Arc::new(Context::from_raw(&raw_args, &registry));
let context = Arc::new(EvaluationContext::from_raw(&raw_args, &registry));
let (each_args, mut input): (EachWindowArgs, _) = raw_args.process(&registry).await?;
let block = Arc::new(each_args.block);

View File

@ -1,6 +1,6 @@
use crate::command_registry::CommandRegistry;
use crate::commands::UnevaluatedCallInfo;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::hir::ExternalRedirection;

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::command::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{CommandAction, ReturnSuccess, Signature};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape, UntaggedValue};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::evaluate::evaluate_baseline_expr;
use crate::prelude::*;
use nu_errors::ShellError;

View File

@ -96,7 +96,7 @@ pub async fn group_by(
let registry = registry.clone();
let head = Arc::new(args.call_info.args.head.clone());
let scope = Arc::new(args.call_info.scope.clone());
let context = Arc::new(Context::from_raw(&args, &registry));
let context = Arc::new(EvaluationContext::from_raw(&args, &registry));
let (GroupByArgs { grouper }, input) = args.process(&registry).await?;
let values: Vec<Value> = input.collect().await;

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use futures::stream::StreamExt;
use indexmap::IndexMap;

View File

@ -1,6 +1,6 @@
use crate::command_registry::CommandRegistry;
use crate::commands::classified::block::run_block;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::evaluate::evaluate_baseline_expr;
use crate::prelude::*;
use nu_errors::ShellError;
@ -74,7 +74,7 @@ async fn if_command(
let registry = Arc::new(registry.clone());
let scope = Arc::new(raw_args.call_info.scope.clone());
let tag = raw_args.call_info.name_tag.clone();
let context = Arc::new(Context::from_raw(&raw_args, &registry));
let context = Arc::new(EvaluationContext::from_raw(&raw_args, &registry));
let (
IfArgs {

View File

@ -1,6 +1,6 @@
use crate::command_registry::CommandRegistry;
use crate::commands::classified::block::run_block;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{
@ -48,7 +48,7 @@ impl WholeStreamCommand for Insert {
async fn process_row(
scope: Arc<Scope>,
mut context: Arc<Context>,
mut context: Arc<EvaluationContext>,
input: Value,
mut value: Arc<Value>,
field: Arc<ColumnPath>,
@ -136,7 +136,7 @@ async fn insert(
) -> Result<OutputStream, ShellError> {
let registry = registry.clone();
let scope = Arc::new(raw_args.call_info.scope.clone());
let context = Arc::new(Context::from_raw(&raw_args, &registry));
let context = Arc::new(EvaluationContext::from_raw(&raw_args, &registry));
let (InsertArgs { column, value }, input) = raw_args.process(&registry).await?;
let value = Arc::new(value);
let column = Arc::new(column);

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ColumnPath, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape, UntaggedValue};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};

View File

@ -1,6 +1,6 @@
use crate::command_registry::CommandRegistry;
use crate::commands::classified::block::run_block;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_data::value::merge_values;
@ -55,7 +55,7 @@ async fn merge(
) -> Result<OutputStream, ShellError> {
let registry = registry.clone();
let scope = raw_args.call_info.scope.clone();
let mut context = Context::from_raw(&raw_args, &registry);
let mut context = EvaluationContext::from_raw(&raw_args, &registry);
let name_tag = raw_args.call_info.name_tag.clone();
let (merge_args, input): (MergeArgs, _) = raw_args.process(&registry).await?;
let block = merge_args.block;

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_data::base::select_fields;
use nu_errors::ShellError;

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, Value};

View File

@ -1,7 +1,7 @@
use std::path::PathBuf;
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::path::canonicalize;
use crate::prelude::*;

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::deserializer::NumericRange;
use crate::prelude::*;
use nu_errors::ShellError;

View File

@ -81,7 +81,7 @@ impl WholeStreamCommand for Reduce {
async fn process_row(
block: Arc<Block>,
scope: Arc<Scope>,
mut context: Arc<Context>,
mut context: Arc<EvaluationContext>,
row: Value,
) -> Result<InputStream, ShellError> {
let row_clone = row.clone();
@ -104,7 +104,7 @@ async fn reduce(
) -> Result<OutputStream, ShellError> {
let registry = registry.clone();
let base_scope = raw_args.call_info.scope.clone();
let context = Arc::new(Context::from_raw(&raw_args, &registry));
let context = Arc::new(EvaluationContext::from_raw(&raw_args, &registry));
let (reduce_args, mut input): (ReduceArgs, _) = raw_args.process(&registry).await?;
let block = Arc::new(reduce_args.block);
let (ioffset, start) = match reduce_args.fold {

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape};

View File

@ -44,7 +44,7 @@ impl WholeStreamCommand for AliasCommand {
block.set_redirect(call_info.args.external_redirection);
let alias_command = self.clone();
let mut context = Context::from_args(&args, &registry);
let mut context = EvaluationContext::from_args(&args, &registry);
let input = args.input;
let mut scope = call_info.scope.clone();

View File

@ -84,32 +84,15 @@ impl WholeStreamCommand for RunExternalCommand {
.and_then(spanned_expression_to_string)?;
let mut external_context = {
#[cfg(windows)]
{
Context {
registry: registry.clone(),
host: args.host.clone(),
user_recently_used_autoenv_untrust: false,
shell_manager: args.shell_manager.clone(),
ctrl_c: args.ctrl_c.clone(),
current_errors: Arc::new(Mutex::new(vec![])),
windows_drives_previous_cwd: Arc::new(Mutex::new(
std::collections::HashMap::new(),
)),
raw_input: String::default(),
}
}
#[cfg(not(windows))]
{
Context {
registry: registry.clone(),
user_recently_used_autoenv_untrust: false,
host: args.host.clone(),
shell_manager: args.shell_manager.clone(),
ctrl_c: args.ctrl_c.clone(),
current_errors: Arc::new(Mutex::new(vec![])),
raw_input: String::default(),
}
EvaluationContext {
registry: registry.clone(),
host: args.host.clone(),
user_recently_used_autoenv_untrust: false,
shell_manager: args.shell_manager.clone(),
ctrl_c: args.ctrl_c.clone(),
current_errors: Arc::new(Mutex::new(vec![])),
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
raw_input: String::default(),
}
};
@ -160,7 +143,10 @@ impl WholeStreamCommand for RunExternalCommand {
}
#[allow(unused_variables)]
async fn maybe_autocd_dir<'a>(cmd: &ExternalCommand, ctx: &mut Context) -> Option<String> {
async fn maybe_autocd_dir<'a>(
cmd: &ExternalCommand,
ctx: &mut EvaluationContext,
) -> Option<String> {
// We will "auto cd" if
// - the command name ends in a path separator, or
// - it's not a command on the path and no arguments were given.

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Value};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape, UntaggedValue};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Signature, SyntaxShape, UntaggedValue};

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use indexmap::indexmap;
use indexmap::map::IndexMap;

View File

@ -1,6 +1,6 @@
use crate::command_registry::CommandRegistry;
use crate::commands::classified::block::run_block;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{
@ -53,7 +53,7 @@ impl WholeStreamCommand for Update {
async fn process_row(
scope: Arc<Scope>,
mut context: Arc<Context>,
mut context: Arc<EvaluationContext>,
input: Value,
mut replacement: Arc<Value>,
field: Arc<ColumnPath>,
@ -161,7 +161,7 @@ async fn update(
let registry = registry.clone();
let name_tag = Arc::new(raw_args.call_info.name_tag.clone());
let scope = Arc::new(raw_args.call_info.scope.clone());
let context = Arc::new(Context::from_raw(&raw_args, &registry));
let context = Arc::new(EvaluationContext::from_raw(&raw_args, &registry));
let (UpdateArgs { field, replacement }, input) = raw_args.process(&registry).await?;
let replacement = Arc::new(replacement);
let field = Arc::new(field);

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::evaluate::evaluate_baseline_expr;
use crate::prelude::*;
use nu_errors::ShellError;

View File

@ -76,7 +76,7 @@ async fn with_env(
) -> Result<OutputStream, ShellError> {
let registry = registry.clone();
let mut context = Context::from_raw(&raw_args, &registry);
let mut context = EvaluationContext::from_raw(&raw_args, &registry);
let mut scope = raw_args.call_info.scope.clone();
let (WithEnvArgs { variable, block }, input) = raw_args.process(&registry).await?;

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry;
use crate::prelude::*;
use indexmap::{indexmap, IndexMap};
use nu_errors::ShellError;

View File

@ -4,14 +4,19 @@ use std::path::Path;
use indexmap::set::IndexSet;
use super::matchers::Matcher;
use crate::completion::{Completer, Context, Suggestion};
use crate::context;
use crate::completion::{Completer, CompletionContext, Suggestion};
use crate::evaluation_context::EvaluationContext;
pub struct CommandCompleter;
impl Completer for CommandCompleter {
fn complete(&self, ctx: &Context<'_>, partial: &str, matcher: &dyn Matcher) -> Vec<Suggestion> {
let context: &context::Context = ctx.as_ref();
fn complete(
&self,
ctx: &CompletionContext<'_>,
partial: &str,
matcher: &dyn Matcher,
) -> Vec<Suggestion> {
let context: &EvaluationContext = ctx.as_ref();
let mut commands: IndexSet<String> = IndexSet::from_iter(context.registry.names());
// Command suggestions can come from three possible sets:

View File

@ -1,14 +1,19 @@
use super::matchers::Matcher;
use crate::completion::{Completer, Context, Suggestion};
use crate::context;
use crate::completion::{Completer, CompletionContext, Suggestion};
use crate::evaluation_context::EvaluationContext;
pub struct FlagCompleter {
pub(crate) cmd: String,
}
impl Completer for FlagCompleter {
fn complete(&self, ctx: &Context<'_>, partial: &str, matcher: &dyn Matcher) -> Vec<Suggestion> {
let context: &context::Context = ctx.as_ref();
fn complete(
&self,
ctx: &CompletionContext<'_>,
partial: &str,
matcher: &dyn Matcher,
) -> Vec<Suggestion> {
let context: &EvaluationContext = ctx.as_ref();
if let Some(cmd) = context.registry.get_command(&self.cmd) {
let sig = cmd.signature();

View File

@ -4,7 +4,7 @@ pub(crate) mod flag;
pub(crate) mod matchers;
pub(crate) mod path;
use crate::context;
use crate::evaluation_context::EvaluationContext;
use matchers::Matcher;
#[derive(Debug, Eq, PartialEq)]
@ -13,20 +13,25 @@ pub struct Suggestion {
pub replacement: String,
}
pub struct Context<'a>(&'a context::Context);
pub struct CompletionContext<'a>(&'a EvaluationContext);
impl<'a> Context<'a> {
pub fn new(a: &'a context::Context) -> Context<'a> {
Context(a)
impl<'a> CompletionContext<'a> {
pub fn new(a: &'a EvaluationContext) -> CompletionContext<'a> {
CompletionContext(a)
}
}
impl<'a> AsRef<context::Context> for Context<'a> {
fn as_ref(&self) -> &context::Context {
impl<'a> AsRef<EvaluationContext> for CompletionContext<'a> {
fn as_ref(&self) -> &EvaluationContext {
self.0
}
}
pub trait Completer {
fn complete(&self, ctx: &Context<'_>, partial: &str, matcher: &dyn Matcher) -> Vec<Suggestion>;
fn complete(
&self,
ctx: &CompletionContext<'_>,
partial: &str,
matcher: &dyn Matcher,
) -> Vec<Suggestion>;
}

View File

@ -1,7 +1,7 @@
use std::path::PathBuf;
use super::matchers::Matcher;
use crate::completion::{Completer, Context, Suggestion};
use crate::completion::{Completer, CompletionContext, Suggestion};
const SEP: char = std::path::MAIN_SEPARATOR;
@ -76,7 +76,7 @@ impl PathCompleter {
impl Completer for PathCompleter {
fn complete(
&self,
_ctx: &Context<'_>,
_ctx: &CompletionContext<'_>,
partial: &str,
matcher: &dyn Matcher,
) -> Vec<Suggestion> {

View File

@ -1,297 +0,0 @@
use crate::commands::{command::CommandArgs, Command, UnevaluatedCallInfo};
use crate::env::host::Host;
use crate::shell::shell_manager::ShellManager;
use crate::stream::{InputStream, OutputStream};
use indexmap::IndexMap;
use nu_errors::ShellError;
use nu_parser::SignatureRegistry;
use nu_protocol::{hir, Scope, Signature};
use nu_source::{Tag, Text};
use parking_lot::Mutex;
use std::error::Error;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
#[derive(Debug, Clone, Default)]
pub struct CommandRegistry {
registry: Arc<Mutex<IndexMap<String, Command>>>,
}
impl SignatureRegistry for CommandRegistry {
fn has(&self, name: &str) -> bool {
let registry = self.registry.lock();
registry.contains_key(name)
}
fn get(&self, name: &str) -> Option<Signature> {
let registry = self.registry.lock();
registry.get(name).map(|command| command.signature())
}
fn clone_box(&self) -> Box<dyn SignatureRegistry> {
Box::new(self.clone())
}
}
impl CommandRegistry {
pub fn new() -> CommandRegistry {
CommandRegistry {
registry: Arc::new(Mutex::new(IndexMap::default())),
}
}
}
impl CommandRegistry {
pub fn get_command(&self, name: &str) -> Option<Command> {
let registry = self.registry.lock();
registry.get(name).cloned()
}
pub fn expect_command(&self, name: &str) -> Result<Command, ShellError> {
self.get_command(name).ok_or_else(|| {
ShellError::untagged_runtime_error(format!("Could not load command: {}", name))
})
}
pub fn has(&self, name: &str) -> bool {
let registry = self.registry.lock();
registry.contains_key(name)
}
pub fn insert(&mut self, name: impl Into<String>, command: Command) {
let mut registry = self.registry.lock();
registry.insert(name.into(), command);
}
pub fn names(&self) -> Vec<String> {
let registry = self.registry.lock();
registry.keys().cloned().collect()
}
}
#[derive(Clone)]
pub struct Context {
pub registry: CommandRegistry,
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
pub ctrl_c: Arc<AtomicBool>,
pub raw_input: String,
pub user_recently_used_autoenv_untrust: bool,
pub(crate) shell_manager: ShellManager,
#[cfg(windows)]
pub windows_drives_previous_cwd: Arc<Mutex<std::collections::HashMap<String, String>>>,
}
impl Context {
pub(crate) fn registry(&self) -> &CommandRegistry {
&self.registry
}
pub(crate) fn from_raw(raw_args: &CommandArgs, registry: &CommandRegistry) -> Context {
#[cfg(windows)]
{
Context {
registry: registry.clone(),
host: raw_args.host.clone(),
current_errors: raw_args.current_errors.clone(),
ctrl_c: raw_args.ctrl_c.clone(),
shell_manager: raw_args.shell_manager.clone(),
user_recently_used_autoenv_untrust: false,
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
raw_input: String::default(),
}
}
#[cfg(not(windows))]
{
Context {
registry: registry.clone(),
host: raw_args.host.clone(),
current_errors: raw_args.current_errors.clone(),
ctrl_c: raw_args.ctrl_c.clone(),
shell_manager: raw_args.shell_manager.clone(),
user_recently_used_autoenv_untrust: false,
raw_input: String::default(),
}
}
}
pub(crate) fn from_args(args: &CommandArgs, registry: &CommandRegistry) -> Context {
#[cfg(windows)]
{
Context {
registry: registry.clone(),
host: args.host.clone(),
current_errors: args.current_errors.clone(),
ctrl_c: args.ctrl_c.clone(),
shell_manager: args.shell_manager.clone(),
user_recently_used_autoenv_untrust: false,
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
raw_input: String::default(),
}
}
#[cfg(not(windows))]
{
Context {
registry: registry.clone(),
host: args.host.clone(),
current_errors: args.current_errors.clone(),
ctrl_c: args.ctrl_c.clone(),
user_recently_used_autoenv_untrust: false,
shell_manager: args.shell_manager.clone(),
raw_input: String::default(),
}
}
}
pub fn basic() -> Result<Context, Box<dyn Error>> {
let registry = CommandRegistry::new();
#[cfg(windows)]
{
Ok(Context {
registry,
host: Arc::new(parking_lot::Mutex::new(Box::new(
crate::env::host::BasicHost,
))),
current_errors: Arc::new(Mutex::new(vec![])),
ctrl_c: Arc::new(AtomicBool::new(false)),
user_recently_used_autoenv_untrust: false,
shell_manager: ShellManager::basic()?,
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
raw_input: String::default(),
})
}
#[cfg(not(windows))]
{
Ok(Context {
registry,
host: Arc::new(parking_lot::Mutex::new(Box::new(
crate::env::host::BasicHost,
))),
current_errors: Arc::new(Mutex::new(vec![])),
ctrl_c: Arc::new(AtomicBool::new(false)),
user_recently_used_autoenv_untrust: false,
shell_manager: ShellManager::basic()?,
raw_input: String::default(),
})
}
}
pub(crate) fn error(&mut self, error: ShellError) {
self.with_errors(|errors| errors.push(error))
}
pub(crate) fn clear_errors(&mut self) {
self.current_errors.lock().clear()
}
pub(crate) fn get_errors(&self) -> Vec<ShellError> {
self.current_errors.lock().clone()
}
pub(crate) fn add_error(&self, err: ShellError) {
self.current_errors.lock().push(err);
}
pub(crate) fn maybe_print_errors(&mut self, source: Text) -> bool {
let errors = self.current_errors.clone();
let mut errors = errors.lock();
if errors.len() > 0 {
let error = errors[0].clone();
*errors = vec![];
crate::cli::print_err(error, &source);
true
} else {
false
}
}
pub(crate) fn configure<T>(
&mut self,
config: &dyn nu_data::config::Conf,
block: impl FnOnce(&dyn nu_data::config::Conf, &mut Self) -> T,
) {
block(config, &mut *self);
}
pub(crate) fn with_host<T>(&mut self, block: impl FnOnce(&mut dyn Host) -> T) -> T {
let mut host = self.host.lock();
block(&mut *host)
}
pub(crate) fn with_errors<T>(&mut self, block: impl FnOnce(&mut Vec<ShellError>) -> T) -> T {
let mut errors = self.current_errors.lock();
block(&mut *errors)
}
pub fn add_commands(&mut self, commands: Vec<Command>) {
for command in commands {
self.registry.insert(command.name().to_string(), command);
}
}
#[allow(unused)]
pub(crate) fn get_command(&self, name: &str) -> Option<Command> {
self.registry.get_command(name)
}
pub(crate) fn is_command_registered(&self, name: &str) -> bool {
self.registry.has(name)
}
pub(crate) fn expect_command(&self, name: &str) -> Result<Command, ShellError> {
self.registry.expect_command(name)
}
pub(crate) async fn run_command(
&mut self,
command: Command,
name_tag: Tag,
args: hir::Call,
scope: &Scope,
input: InputStream,
) -> Result<OutputStream, ShellError> {
let command_args = self.command_args(args, input, name_tag, scope);
command.run(command_args, self.registry()).await
}
fn call_info(&self, args: hir::Call, name_tag: Tag, scope: &Scope) -> UnevaluatedCallInfo {
UnevaluatedCallInfo {
args,
name_tag,
scope: scope.clone(),
}
}
fn command_args(
&self,
args: hir::Call,
input: InputStream,
name_tag: Tag,
scope: &Scope,
) -> CommandArgs {
CommandArgs {
host: self.host.clone(),
ctrl_c: self.ctrl_c.clone(),
current_errors: self.current_errors.clone(),
shell_manager: self.shell_manager.clone(),
call_info: self.call_info(args, name_tag, scope),
input,
raw_input: self.raw_input.clone(),
}
}
pub fn get_env(&self) -> IndexMap<String, String> {
let mut output = IndexMap::new();
for (var, value) in self.host.lock().vars() {
output.insert(var, value);
}
output
}
}

View File

@ -1,5 +1,5 @@
use crate::context::Context;
use crate::env::environment::{Env, Environment};
use crate::evaluation_context::EvaluationContext;
use nu_data::config::{Conf, NuConfig};
use nu_errors::ShellError;
use parking_lot::Mutex;
@ -61,14 +61,14 @@ impl EnvironmentSyncer {
environment.morph(&*config);
}
pub fn autoenv(&self, ctx: &mut Context) -> Result<(), ShellError> {
pub fn autoenv(&self, ctx: &mut EvaluationContext) -> Result<(), ShellError> {
let mut environment = self.env.lock();
let auto = environment.autoenv(ctx.user_recently_used_autoenv_untrust);
ctx.user_recently_used_autoenv_untrust = false;
auto
}
pub fn sync_env_vars(&mut self, ctx: &mut Context) {
pub fn sync_env_vars(&mut self, ctx: &mut EvaluationContext) {
let mut environment = self.env.lock();
if environment.env().is_some() {
@ -99,7 +99,7 @@ impl EnvironmentSyncer {
}
}
pub fn sync_path_vars(&mut self, ctx: &mut Context) {
pub fn sync_path_vars(&mut self, ctx: &mut EvaluationContext) {
let mut environment = self.env.lock();
if environment.path().is_some() {
@ -131,7 +131,7 @@ impl EnvironmentSyncer {
}
#[cfg(test)]
pub fn clear_env_vars(&mut self, ctx: &mut Context) {
pub fn clear_env_vars(&mut self, ctx: &mut EvaluationContext) {
for (key, _value) in ctx.with_host(|host| host.vars()) {
if key != "path" && key != "PATH" {
ctx.with_host(|host| host.env_rm(std::ffi::OsString::from(key)));
@ -140,7 +140,7 @@ impl EnvironmentSyncer {
}
#[cfg(test)]
pub fn clear_path_var(&mut self, ctx: &mut Context) {
pub fn clear_path_var(&mut self, ctx: &mut EvaluationContext) {
ctx.with_host(|host| host.env_rm(std::ffi::OsString::from("PATH")));
}
}
@ -148,8 +148,8 @@ impl EnvironmentSyncer {
#[cfg(test)]
mod tests {
use super::EnvironmentSyncer;
use crate::context::Context;
use crate::env::environment::Env;
use crate::evaluation_context::EvaluationContext;
use indexmap::IndexMap;
use nu_data::config::tests::FakeConfig;
use nu_errors::ShellError;
@ -166,7 +166,7 @@ mod tests {
#[test]
fn syncs_env_if_new_env_entry_is_added_to_an_existing_configuration() -> Result<(), ShellError>
{
let mut ctx = Context::basic()?;
let mut ctx = EvaluationContext::basic()?;
ctx.host = Arc::new(Mutex::new(Box::new(crate::env::host::FakeHost::new())));
let mut expected = IndexMap::new();
@ -269,7 +269,7 @@ mod tests {
#[test]
fn syncs_env_if_new_env_entry_in_session_is_not_in_configuration_file() -> Result<(), ShellError>
{
let mut ctx = Context::basic()?;
let mut ctx = EvaluationContext::basic()?;
ctx.host = Arc::new(Mutex::new(Box::new(crate::env::host::FakeHost::new())));
let mut expected = IndexMap::new();
@ -368,7 +368,7 @@ mod tests {
#[test]
fn nu_envs_have_higher_priority_and_does_not_get_overwritten() -> Result<(), ShellError> {
let mut ctx = Context::basic()?;
let mut ctx = EvaluationContext::basic()?;
ctx.host = Arc::new(Mutex::new(Box::new(crate::env::host::FakeHost::new())));
let mut expected = IndexMap::new();
@ -444,7 +444,7 @@ mod tests {
#[test]
fn syncs_path_if_new_path_entry_in_session_is_not_in_configuration_file(
) -> Result<(), ShellError> {
let mut ctx = Context::basic()?;
let mut ctx = EvaluationContext::basic()?;
ctx.host = Arc::new(Mutex::new(Box::new(crate::env::host::FakeHost::new())));
let expected = std::env::join_paths(vec![
@ -531,7 +531,7 @@ mod tests {
#[test]
fn nu_paths_have_higher_priority_and_new_paths_get_appended_to_the_end(
) -> Result<(), ShellError> {
let mut ctx = Context::basic()?;
let mut ctx = EvaluationContext::basic()?;
ctx.host = Arc::new(Mutex::new(Box::new(crate::env::host::FakeHost::new())));
let expected = std::env::join_paths(vec![

View File

@ -1,5 +1,5 @@
// TODO: Temporary redirect
use crate::context::CommandRegistry;
use crate::command_registry::CommandRegistry;
use crate::evaluate::evaluate_baseline_expr;
use indexmap::IndexMap;
use nu_errors::ShellError;

View File

@ -1,5 +1,5 @@
use crate::command_registry::CommandRegistry;
use crate::commands::classified::block::run_block;
use crate::context::CommandRegistry;
use crate::evaluate::operator::apply_operator;
use crate::prelude::*;
use async_recursion::async_recursion;
@ -241,7 +241,7 @@ async fn evaluate_invocation(
env: &IndexMap<String, String>,
) -> Result<Value, ShellError> {
// FIXME: we should use a real context here
let mut context = Context::basic()?;
let mut context = EvaluationContext::basic()?;
context.registry = registry.clone();
let input = InputStream::one(it.clone());

View File

@ -0,0 +1,195 @@
use crate::command_registry::CommandRegistry;
use crate::commands::{command::CommandArgs, Command, UnevaluatedCallInfo};
use crate::env::host::Host;
use crate::shell::shell_manager::ShellManager;
use crate::stream::{InputStream, OutputStream};
use indexmap::IndexMap;
use nu_errors::ShellError;
use nu_protocol::{hir, Scope};
use nu_source::{Tag, Text};
use parking_lot::Mutex;
use std::error::Error;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
#[derive(Clone)]
pub struct EvaluationContext {
pub registry: CommandRegistry,
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
pub ctrl_c: Arc<AtomicBool>,
pub raw_input: String,
pub user_recently_used_autoenv_untrust: bool,
pub(crate) shell_manager: ShellManager,
/// Windows-specific: keep track of previous cwd on each drive
pub windows_drives_previous_cwd: Arc<Mutex<std::collections::HashMap<String, String>>>,
}
impl EvaluationContext {
pub(crate) fn registry(&self) -> &CommandRegistry {
&self.registry
}
pub(crate) fn from_raw(
raw_args: &CommandArgs,
registry: &CommandRegistry,
) -> EvaluationContext {
EvaluationContext {
registry: registry.clone(),
host: raw_args.host.clone(),
current_errors: raw_args.current_errors.clone(),
ctrl_c: raw_args.ctrl_c.clone(),
shell_manager: raw_args.shell_manager.clone(),
user_recently_used_autoenv_untrust: false,
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
raw_input: String::default(),
}
}
pub(crate) fn from_args(args: &CommandArgs, registry: &CommandRegistry) -> EvaluationContext {
EvaluationContext {
registry: registry.clone(),
host: args.host.clone(),
current_errors: args.current_errors.clone(),
ctrl_c: args.ctrl_c.clone(),
shell_manager: args.shell_manager.clone(),
user_recently_used_autoenv_untrust: false,
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
raw_input: String::default(),
}
}
pub fn basic() -> Result<EvaluationContext, Box<dyn Error>> {
let registry = CommandRegistry::new();
Ok(EvaluationContext {
registry,
host: Arc::new(parking_lot::Mutex::new(Box::new(
crate::env::host::BasicHost,
))),
current_errors: Arc::new(Mutex::new(vec![])),
ctrl_c: Arc::new(AtomicBool::new(false)),
user_recently_used_autoenv_untrust: false,
shell_manager: ShellManager::basic()?,
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
raw_input: String::default(),
})
}
pub(crate) fn error(&mut self, error: ShellError) {
self.with_errors(|errors| errors.push(error))
}
pub(crate) fn clear_errors(&mut self) {
self.current_errors.lock().clear()
}
pub(crate) fn get_errors(&self) -> Vec<ShellError> {
self.current_errors.lock().clone()
}
pub(crate) fn add_error(&self, err: ShellError) {
self.current_errors.lock().push(err);
}
pub(crate) fn maybe_print_errors(&mut self, source: Text) -> bool {
let errors = self.current_errors.clone();
let mut errors = errors.lock();
if errors.len() > 0 {
let error = errors[0].clone();
*errors = vec![];
crate::cli::print_err(error, &source);
true
} else {
false
}
}
pub(crate) fn configure<T>(
&mut self,
config: &dyn nu_data::config::Conf,
block: impl FnOnce(&dyn nu_data::config::Conf, &mut Self) -> T,
) {
block(config, &mut *self);
}
pub(crate) fn with_host<T>(&mut self, block: impl FnOnce(&mut dyn Host) -> T) -> T {
let mut host = self.host.lock();
block(&mut *host)
}
pub(crate) fn with_errors<T>(&mut self, block: impl FnOnce(&mut Vec<ShellError>) -> T) -> T {
let mut errors = self.current_errors.lock();
block(&mut *errors)
}
pub fn add_commands(&mut self, commands: Vec<Command>) {
for command in commands {
self.registry.insert(command.name().to_string(), command);
}
}
#[allow(unused)]
pub(crate) fn get_command(&self, name: &str) -> Option<Command> {
self.registry.get_command(name)
}
pub(crate) fn is_command_registered(&self, name: &str) -> bool {
self.registry.has(name)
}
pub(crate) fn expect_command(&self, name: &str) -> Result<Command, ShellError> {
self.registry.expect_command(name)
}
pub(crate) async fn run_command(
&mut self,
command: Command,
name_tag: Tag,
args: hir::Call,
scope: &Scope,
input: InputStream,
) -> Result<OutputStream, ShellError> {
let command_args = self.command_args(args, input, name_tag, scope);
command.run(command_args, self.registry()).await
}
fn call_info(&self, args: hir::Call, name_tag: Tag, scope: &Scope) -> UnevaluatedCallInfo {
UnevaluatedCallInfo {
args,
name_tag,
scope: scope.clone(),
}
}
fn command_args(
&self,
args: hir::Call,
input: InputStream,
name_tag: Tag,
scope: &Scope,
) -> CommandArgs {
CommandArgs {
host: self.host.clone(),
ctrl_c: self.ctrl_c.clone(),
current_errors: self.current_errors.clone(),
shell_manager: self.shell_manager.clone(),
call_info: self.call_info(args, name_tag, scope),
input,
raw_input: self.raw_input.clone(),
}
}
pub fn get_env(&self) -> IndexMap<String, String> {
let mut output = IndexMap::new();
for (var, value) in self.host.lock().vars() {
output.insert(var, value);
}
output
}
}

View File

@ -7,13 +7,13 @@ use nu_protocol::{ShellTypeName, Value};
use crate::commands::classified::block::run_block;
use crate::commands::{whole_stream_command, BuildString, Each, Echo, StrCollect};
use crate::context::Context;
use crate::evaluation_context::EvaluationContext;
use crate::stream::InputStream;
use crate::WholeStreamCommand;
pub fn test(cmd: impl WholeStreamCommand + 'static) {
let examples = cmd.examples();
let mut base_context = Context::basic().expect("could not create basic context");
let mut base_context = EvaluationContext::basic().expect("could not create basic context");
base_context.add_commands(vec![
whole_stream_command(Echo {}),
@ -58,7 +58,10 @@ pub fn test(cmd: impl WholeStreamCommand + 'static) {
}
/// Parse and run a nushell pipeline
fn parse_line(line: &'static str, ctx: &mut Context) -> Result<ClassifiedBlock, ShellError> {
fn parse_line(
line: &'static str,
ctx: &mut EvaluationContext,
) -> Result<ClassifiedBlock, ShellError> {
let line = if line.ends_with('\n') {
&line[..line.len() - 1]
} else {
@ -75,7 +78,7 @@ fn parse_line(line: &'static str, ctx: &mut Context) -> Result<ClassifiedBlock,
async fn evaluate_block(
block: ClassifiedBlock,
ctx: &mut Context,
ctx: &mut EvaluationContext,
) -> Result<Vec<Value>, ShellError> {
let input_stream = InputStream::empty();
let env = ctx.get_env();

View File

@ -14,14 +14,15 @@ extern crate quickcheck;
extern crate quickcheck_macros;
mod cli;
mod command_registry;
mod commands;
#[cfg(feature = "rustyline-support")]
mod completion;
mod context;
mod deserializer;
mod documentation;
mod env;
mod evaluate;
mod evaluation_context;
mod format;
mod futures;
#[cfg(feature = "rustyline-support")]
@ -44,13 +45,14 @@ pub use crate::cli::{
create_default_context, parse_and_eval, process_line, register_plugins,
run_pipeline_standalone, run_vec_of_pipelines, LineResult,
};
pub use crate::command_registry::CommandRegistry;
pub use crate::commands::command::{
whole_stream_command, CommandArgs, EvaluatedWholeStreamCommandArgs, Example, WholeStreamCommand,
};
pub use crate::commands::help::get_help;
pub use crate::context::{CommandRegistry, Context};
pub use crate::env::environment_syncer::EnvironmentSyncer;
pub use crate::env::host::BasicHost;
pub use crate::evaluation_context::EvaluationContext;
pub use crate::prelude::ToOutputStream;
pub use crate::stream::{InputStream, InterruptibleStream, OutputStream};
pub use nu_data::config;

View File

@ -71,10 +71,10 @@ macro_rules! trace_out_stream {
pub(crate) use nu_protocol::{errln, out, outln};
use nu_source::HasFallibleSpan;
pub(crate) use crate::command_registry::CommandRegistry;
pub(crate) use crate::commands::command::{CommandArgs, RawCommandArgs, RunnableContext};
pub(crate) use crate::commands::Example;
pub(crate) use crate::context::CommandRegistry;
pub(crate) use crate::context::Context;
pub(crate) use crate::evaluation_context::EvaluationContext;
pub(crate) use nu_data::config;
pub(crate) use nu_data::value;
// pub(crate) use crate::env::host::handle_unexpected;

View File

@ -4,7 +4,7 @@ use crate::completion::matchers;
use crate::completion::matchers::Matcher;
use crate::completion::path::{PathCompleter, PathSuggestion};
use crate::completion::{self, Completer, Suggestion};
use crate::context;
use crate::evaluation_context::EvaluationContext;
use nu_source::Tag;
use std::borrow::Cow;
@ -18,11 +18,11 @@ impl NuCompleter {
&self,
line: &str,
pos: usize,
context: &completion::Context,
context: &completion::CompletionContext,
) -> (usize, Vec<Suggestion>) {
use completion::engine::LocationType;
let nu_context: &context::Context = context.as_ref();
let nu_context: &EvaluationContext = context.as_ref();
let lite_block = match nu_parser::lite_parse(line, 0) {
Ok(block) => Some(block),
Err(result) => result.partial,

View File

@ -4,7 +4,7 @@ use nu_parser::SignatureRegistry;
use nu_source::{Tag, Tagged};
use crate::completion;
use crate::context::Context;
use crate::evaluation_context::EvaluationContext;
use crate::shell::completer::NuCompleter;
use crate::shell::painter::Painter;
use crate::shell::palette::DefaultPalette;
@ -12,13 +12,16 @@ use crate::shell::palette::DefaultPalette;
pub struct Helper {
completer: NuCompleter,
hinter: Option<rustyline::hint::HistoryHinter>,
context: Context,
context: EvaluationContext,
pub colored_prompt: String,
validator: NuValidator,
}
impl Helper {
pub(crate) fn new(context: Context, hinter: Option<rustyline::hint::HistoryHinter>) -> Helper {
pub(crate) fn new(
context: EvaluationContext,
hinter: Option<rustyline::hint::HistoryHinter>,
) -> Helper {
Helper {
completer: NuCompleter {},
hinter,
@ -48,7 +51,7 @@ impl rustyline::completion::Completer for Helper {
pos: usize,
_ctx: &rustyline::Context<'_>,
) -> Result<(usize, Vec<Self::Candidate>), rustyline::error::ReadlineError> {
let ctx = completion::Context::new(&self.context);
let ctx = completion::CompletionContext::new(&self.context);
Ok(self.completer.complete(line, pos, &ctx))
}