mirror of
https://github.com/nushell/nushell.git
synced 2024-12-22 15:13:01 +01:00
WIP
This commit is contained in:
parent
397a31e69c
commit
b5965ee8ef
@ -10,19 +10,20 @@ use reedline::Completer;
|
||||
|
||||
const SEP: char = std::path::MAIN_SEPARATOR;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NuCompleter {
|
||||
engine_state: Box<EngineState>,
|
||||
engine_state: EngineState,
|
||||
}
|
||||
|
||||
impl NuCompleter {
|
||||
pub fn new(engine_state: Box<EngineState>) -> Self {
|
||||
pub fn new(engine_state: EngineState) -> Self {
|
||||
Self { engine_state }
|
||||
}
|
||||
}
|
||||
|
||||
impl Completer for NuCompleter {
|
||||
fn complete(&self, line: &str, pos: usize) -> Vec<(reedline::Span, String)> {
|
||||
let mut working_set = StateWorkingSet::new(&*self.engine_state);
|
||||
let mut working_set = StateWorkingSet::new(&self.engine_state);
|
||||
let offset = working_set.next_span_start();
|
||||
let pos = offset + pos;
|
||||
let (output, _err) = parse(&mut working_set, Some("completer"), line.as_bytes(), false);
|
||||
@ -71,11 +72,10 @@ impl Completer for NuCompleter {
|
||||
|
||||
let (block, ..) =
|
||||
parse(&mut working_set, None, custom_completion.as_bytes(), false);
|
||||
let context = EvaluationContext {
|
||||
engine_state: self.engine_state.clone(),
|
||||
stack: Stack::default(),
|
||||
};
|
||||
let result = eval_block(&context, &block, PipelineData::new());
|
||||
|
||||
let mut stack = Stack::default();
|
||||
let result =
|
||||
eval_block(&self.engine_state, &mut stack, &block, PipelineData::new());
|
||||
|
||||
let v: Vec<_> = match result {
|
||||
Ok(pd) => pd
|
||||
|
@ -2,21 +2,19 @@ use nu_ansi_term::Style;
|
||||
use nu_parser::{flatten_block, parse, FlatShape};
|
||||
use nu_protocol::engine::{EngineState, StateWorkingSet};
|
||||
use reedline::{Highlighter, StyledText};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
pub struct NuHighlighter {
|
||||
pub engine_state: Rc<RefCell<EngineState>>,
|
||||
pub engine_state: EngineState,
|
||||
}
|
||||
|
||||
impl Highlighter for NuHighlighter {
|
||||
fn highlight(&self, line: &str) -> StyledText {
|
||||
let (shapes, global_span_offset) = {
|
||||
let engine_state = self.engine_state.borrow();
|
||||
let mut working_set = StateWorkingSet::new(&*engine_state);
|
||||
let mut working_set = StateWorkingSet::new(&self.engine_state);
|
||||
let (block, _) = parse(&mut working_set, None, line.as_bytes(), false);
|
||||
|
||||
let shapes = flatten_block(&working_set, &block);
|
||||
(shapes, engine_state.next_span_start())
|
||||
(shapes, self.engine_state.next_span_start())
|
||||
};
|
||||
|
||||
let mut output = StyledText::default();
|
||||
|
@ -5,13 +5,12 @@ use nu_protocol::engine::{EngineState, StateWorkingSet};
|
||||
use reedline::{ValidationResult, Validator};
|
||||
|
||||
pub struct NuValidator {
|
||||
pub engine_state: Rc<RefCell<EngineState>>,
|
||||
pub engine_state: EngineState,
|
||||
}
|
||||
|
||||
impl Validator for NuValidator {
|
||||
fn validate(&self, line: &str) -> ValidationResult {
|
||||
let engine_state = self.engine_state.borrow();
|
||||
let mut working_set = StateWorkingSet::new(&*engine_state);
|
||||
let mut working_set = StateWorkingSet::new(&self.engine_state);
|
||||
let (_, err) = parse(&mut working_set, None, line.as_bytes(), false);
|
||||
|
||||
if matches!(err, Some(ParseError::UnexpectedEof(..))) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack},
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
|
||||
@ -26,11 +26,12 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
into_binary(context, call, input)
|
||||
into_binary(call, input)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -85,7 +86,6 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn into_binary(
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use nu_engine::get_full_help;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack},
|
||||
IntoPipelineData, PipelineData, Signature, Value,
|
||||
};
|
||||
|
||||
@ -23,12 +23,13 @@ impl Command for Into {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
Ok(Value::String {
|
||||
val: get_full_help(&Into.signature(), &[], context),
|
||||
val: get_full_help(&Into.signature(), &[], engine_state),
|
||||
span: call.head,
|
||||
}
|
||||
.into_pipeline_data())
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack},
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
|
||||
@ -26,11 +26,12 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
into_filesize(context, call, input)
|
||||
into_filesize(call, input)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -113,7 +114,6 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn into_filesize(
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack},
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
|
||||
@ -26,11 +26,12 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
into_int(context, call, input)
|
||||
into_int(call, input)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -89,7 +90,6 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn into_int(
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -26,7 +26,8 @@ impl Command for Alias {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -27,7 +27,8 @@ impl Command for Def {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::{eval_block, CallExt};
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -28,18 +28,19 @@ impl Command for Do {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let block_id = call.positional[0]
|
||||
.as_block()
|
||||
.expect("internal error: expected block");
|
||||
let rest: Vec<Value> = call.rest(context, 1)?;
|
||||
let rest: Vec<Value> = call.rest(engine_state, stack, 1)?;
|
||||
|
||||
let block = context.engine_state.get_block(block_id);
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
||||
let mut state = context.enter_scope();
|
||||
let mut stack = stack.enter_scope();
|
||||
|
||||
let params: Vec<_> = block
|
||||
.signature
|
||||
@ -50,7 +51,7 @@ impl Command for Do {
|
||||
|
||||
for param in params.iter().zip(&rest) {
|
||||
if let Some(var_id) = param.0.var_id {
|
||||
state.add_var(var_id, param.1.clone())
|
||||
stack.add_var(var_id, param.1.clone())
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +69,7 @@ impl Command for Do {
|
||||
call.head
|
||||
};
|
||||
|
||||
state.add_var(
|
||||
stack.add_var(
|
||||
param
|
||||
.var_id
|
||||
.expect("Internal error: rest positional parameter lacks var_id"),
|
||||
@ -79,6 +80,6 @@ impl Command for Do {
|
||||
)
|
||||
}
|
||||
}
|
||||
eval_block(&state, block, input)
|
||||
eval_block(&engine_state, &mut stack, block, input)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -27,7 +27,8 @@ impl Command for ExportDef {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::{eval_block, eval_expression};
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -37,7 +37,8 @@ impl Command for For {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
@ -48,25 +49,25 @@ impl Command for For {
|
||||
let keyword_expr = call.positional[1]
|
||||
.as_keyword()
|
||||
.expect("internal error: missing keyword");
|
||||
let values = eval_expression(context, keyword_expr)?;
|
||||
let values = eval_expression(engine_state, stack, keyword_expr)?;
|
||||
|
||||
let block = call.positional[2]
|
||||
.as_block()
|
||||
.expect("internal error: expected block");
|
||||
|
||||
let context = context.clone();
|
||||
let engine_state = engine_state.clone();
|
||||
let mut stack = stack.enter_scope();
|
||||
|
||||
match values {
|
||||
Value::List { vals, span } => Ok(vals
|
||||
.into_iter()
|
||||
.map(move |x| {
|
||||
let block = context.engine_state.get_block(block);
|
||||
let block = engine_state.get_block(block);
|
||||
|
||||
let mut state = context.enter_scope();
|
||||
let mut stack = stack.clone();
|
||||
stack.add_var(var_id, x);
|
||||
|
||||
state.add_var(var_id, x);
|
||||
|
||||
match eval_block(&state, block, PipelineData::new()) {
|
||||
match eval_block(&engine_state, &mut stack, block, PipelineData::new()) {
|
||||
Ok(value) => Value::List {
|
||||
vals: value.collect(),
|
||||
span,
|
||||
@ -78,13 +79,13 @@ impl Command for For {
|
||||
Value::Range { val, span } => Ok(val
|
||||
.into_range_iter()?
|
||||
.map(move |x| {
|
||||
let block = context.engine_state.get_block(block);
|
||||
let block = engine_state.get_block(block);
|
||||
|
||||
let mut state = context.enter_scope();
|
||||
let mut stack = stack.enter_scope();
|
||||
|
||||
state.add_var(var_id, x);
|
||||
stack.add_var(var_id, x);
|
||||
|
||||
match eval_block(&state, block, PipelineData::new()) {
|
||||
match eval_block(&engine_state, &mut stack, block, PipelineData::new()) {
|
||||
Ok(value) => Value::List {
|
||||
vals: value.collect(),
|
||||
span,
|
||||
@ -94,13 +95,13 @@ impl Command for For {
|
||||
})
|
||||
.into_pipeline_data()),
|
||||
x => {
|
||||
let block = context.engine_state.get_block(block);
|
||||
let block = engine_state.get_block(block);
|
||||
|
||||
let mut state = context.enter_scope();
|
||||
let mut stack = stack.enter_scope();
|
||||
|
||||
state.add_var(var_id, x);
|
||||
stack.add_var(var_id, x);
|
||||
|
||||
eval_block(&state, block, PipelineData::new())
|
||||
eval_block(&engine_state, &mut stack, block, PipelineData::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack},
|
||||
span, Example, IntoPipelineData, PipelineData, ShellError, Signature, Spanned, SyntaxShape,
|
||||
Value,
|
||||
};
|
||||
@ -36,11 +36,12 @@ impl Command for Help {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
help(context, call)
|
||||
help(engine_state, stack, call)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -74,12 +75,16 @@ impl Command for Help {
|
||||
}
|
||||
}
|
||||
|
||||
fn help(context: &EvaluationContext, call: &Call) -> Result<PipelineData, ShellError> {
|
||||
fn help(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let find: Option<Spanned<String>> = call.get_flag(context, "find")?;
|
||||
let rest: Vec<Spanned<String>> = call.rest(context, 0)?;
|
||||
let find: Option<Spanned<String>> = call.get_flag(engine_state, stack, "find")?;
|
||||
let rest: Vec<Spanned<String>> = call.rest(engine_state, stack, 0)?;
|
||||
|
||||
let full_commands = context.get_signatures_with_examples();
|
||||
let full_commands = engine_state.get_signatures_with_examples();
|
||||
|
||||
if let Some(f) = find {
|
||||
let search_string = f.item;
|
||||
@ -164,7 +169,7 @@ fn help(context: &EvaluationContext, call: &Call) -> Result<PipelineData, ShellE
|
||||
|
||||
for cmd in full_commands {
|
||||
if cmd.0.name == name {
|
||||
let help = get_full_help(&cmd.0, &cmd.1, context);
|
||||
let help = get_full_help(&cmd.0, &cmd.1, engine_state);
|
||||
output.push_str(&help);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -20,7 +20,8 @@ impl Command for Hide {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::{eval_block, eval_expression};
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -28,7 +28,8 @@ impl Command for If {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
@ -38,24 +39,26 @@ impl Command for If {
|
||||
.expect("internal error: expected block");
|
||||
let else_case = call.positional.get(2);
|
||||
|
||||
let result = eval_expression(context, cond)?;
|
||||
let result = eval_expression(engine_state, stack, cond)?;
|
||||
match result {
|
||||
Value::Bool { val, span } => {
|
||||
if val {
|
||||
let block = context.engine_state.get_block(then_block);
|
||||
let state = context.enter_scope();
|
||||
eval_block(&state, block, input)
|
||||
let block = engine_state.get_block(then_block);
|
||||
let mut stack = stack.enter_scope();
|
||||
eval_block(&engine_state, &mut stack, block, input)
|
||||
} else if let Some(else_case) = else_case {
|
||||
if let Some(else_expr) = else_case.as_keyword() {
|
||||
if let Some(block_id) = else_expr.as_block() {
|
||||
let block = context.engine_state.get_block(block_id);
|
||||
let state = context.enter_scope();
|
||||
eval_block(&state, block, input)
|
||||
let block = engine_state.get_block(block_id);
|
||||
let mut stack = stack.enter_scope();
|
||||
eval_block(&engine_state, &mut stack, block, input)
|
||||
} else {
|
||||
eval_expression(context, else_expr).map(|x| x.into_pipeline_data())
|
||||
eval_expression(&engine_state, stack, else_expr)
|
||||
.map(|x| x.into_pipeline_data())
|
||||
}
|
||||
} else {
|
||||
eval_expression(context, else_case).map(|x| x.into_pipeline_data())
|
||||
eval_expression(&engine_state, stack, else_case)
|
||||
.map(|x| x.into_pipeline_data())
|
||||
}
|
||||
} else {
|
||||
Ok(PipelineData::new())
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -27,7 +27,8 @@ impl Command for Let {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
@ -39,11 +40,11 @@ impl Command for Let {
|
||||
.as_keyword()
|
||||
.expect("internal error: missing keyword");
|
||||
|
||||
let rhs = eval_expression(context, keyword_expr)?;
|
||||
let rhs = eval_expression(&engine_state, stack, keyword_expr)?;
|
||||
|
||||
//println!("Adding: {:?} to {}", rhs, var_id);
|
||||
|
||||
context.add_var(var_id, rhs);
|
||||
stack.add_var(var_id, rhs);
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -26,7 +26,8 @@ impl Command for Module {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::{eval_block, CallExt};
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, ShellError, Signature, SyntaxShape, Value};
|
||||
|
||||
/// Source a file for environment variables.
|
||||
@ -26,15 +26,16 @@ impl Command for Source {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
// Note: this hidden positional is the block_id that corresponded to the 0th position
|
||||
// it is put here by the parser
|
||||
let block_id: i64 = call.req(context, 1)?;
|
||||
let block_id: i64 = call.req(engine_state, stack, 1)?;
|
||||
|
||||
let block = context.engine_state.get_block(block_id as usize).clone();
|
||||
eval_block(context, &block, input)
|
||||
let block = engine_state.get_block(block_id as usize).clone();
|
||||
eval_block(engine_state, stack, &block, input)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -20,7 +20,8 @@ impl Command for Use {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,5 +1,3 @@
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use nu_protocol::{
|
||||
engine::{EngineState, StateWorkingSet},
|
||||
Signature,
|
||||
@ -7,11 +5,10 @@ use nu_protocol::{
|
||||
|
||||
use crate::*;
|
||||
|
||||
pub fn create_default_context() -> Rc<RefCell<EngineState>> {
|
||||
let engine_state = Rc::new(RefCell::new(EngineState::new()));
|
||||
pub fn create_default_context() -> EngineState {
|
||||
let mut engine_state = EngineState::new();
|
||||
let delta = {
|
||||
let engine_state = engine_state.borrow();
|
||||
let mut working_set = StateWorkingSet::new(&*engine_state);
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
macro_rules! bind_command {
|
||||
( $command:expr ) => {
|
||||
@ -90,7 +87,7 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
|
||||
};
|
||||
|
||||
{
|
||||
EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta);
|
||||
EngineState::merge_delta(&mut engine_state, delta);
|
||||
}
|
||||
|
||||
engine_state
|
||||
|
9
crates/nu-command/src/env/let_env.rs
vendored
9
crates/nu-command/src/env/let_env.rs
vendored
@ -1,6 +1,6 @@
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -27,7 +27,8 @@ impl Command for LetEnv {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
@ -39,12 +40,12 @@ impl Command for LetEnv {
|
||||
.as_keyword()
|
||||
.expect("internal error: missing keyword");
|
||||
|
||||
let rhs = eval_expression(context, keyword_expr)?;
|
||||
let rhs = eval_expression(engine_state, stack, keyword_expr)?;
|
||||
let rhs = rhs.as_string()?;
|
||||
|
||||
//println!("Adding: {:?} to {}", rhs, var_id);
|
||||
|
||||
context.add_env_var(env_var, rhs);
|
||||
stack.add_env_var(env_var, rhs);
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use std::{cell::RefCell, rc::Rc};
|
||||
use nu_engine::eval_block;
|
||||
use nu_parser::parse;
|
||||
use nu_protocol::{
|
||||
engine::{Command, EngineState, EvaluationContext, StateWorkingSet},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack, StateWorkingSet},
|
||||
PipelineData, Value,
|
||||
};
|
||||
|
||||
@ -37,7 +37,6 @@ pub fn test_examples(cmd: impl Command + 'static) {
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
let (block, delta) = {
|
||||
let engine_state = engine_state;
|
||||
let mut working_set = StateWorkingSet::new(&*engine_state);
|
||||
let (output, err) = parse(&mut working_set, None, example.example.as_bytes(), false);
|
||||
|
||||
@ -48,14 +47,11 @@ pub fn test_examples(cmd: impl Command + 'static) {
|
||||
(output, working_set.render())
|
||||
};
|
||||
|
||||
EngineState::merge_delta(&mut *engine_state, delta);
|
||||
EngineState::merge_delta(&mut engine_state, delta);
|
||||
|
||||
let state = EvaluationContext {
|
||||
engine_state: engine_state.clone(),
|
||||
stack: nu_protocol::engine::Stack::new(),
|
||||
};
|
||||
let mut stack = Stack::new();
|
||||
|
||||
match eval_block(&state, &block, PipelineData::new()) {
|
||||
match eval_block(&engine_state, &mut stack, &block, PipelineData::new()) {
|
||||
Err(err) => panic!("test eval error in `{}`: {:?}", example.example, err),
|
||||
Ok(result) => {
|
||||
let result = result.into_value();
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -20,7 +20,8 @@ impl Command for Git {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -25,7 +25,8 @@ impl Command for GitCheckout {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
@ -34,7 +35,7 @@ impl Command for GitCheckout {
|
||||
|
||||
let block = &call.positional[0];
|
||||
|
||||
let out = eval_expression(context, block)?;
|
||||
let out = eval_expression(engine_state, stack, block)?;
|
||||
|
||||
let out = out.as_string()?;
|
||||
|
||||
|
@ -4,6 +4,8 @@ use std::process::Command as ProcessCommand;
|
||||
use std::process::Stdio;
|
||||
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::EngineState;
|
||||
use nu_protocol::engine::Stack;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::IntoPipelineData;
|
||||
use nu_protocol::PipelineData;
|
||||
@ -28,7 +30,8 @@ impl Command for ListGitBranches {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -21,11 +21,12 @@ impl Command for Cd {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let path: Option<String> = call.opt(context, 0)?;
|
||||
let path: Option<String> = call.opt(engine_state, stack, 0)?;
|
||||
|
||||
let path = match path {
|
||||
Some(path) => {
|
||||
@ -41,7 +42,7 @@ impl Command for Cd {
|
||||
|
||||
//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
|
||||
context.add_env_var("PWD".into(), path);
|
||||
stack.add_env_var("PWD".into(), path);
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use super::util::get_interactive_confirmation;
|
||||
use nu_engine::CallExt;
|
||||
use nu_path::canonicalize_with;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, ShellError, Signature, SyntaxShape, Value};
|
||||
|
||||
use crate::filesystem::util::FileStructure;
|
||||
@ -38,12 +38,13 @@ impl Command for Cp {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let source: String = call.req(context, 0)?;
|
||||
let destination: String = call.req(context, 1)?;
|
||||
let source: String = call.req(engine_state, stack, 0)?;
|
||||
let destination: String = call.req(engine_state, stack, 1)?;
|
||||
let interactive = call.has_flag("interactive");
|
||||
let force = call.has_flag("force");
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -27,12 +27,13 @@ impl Command for Ls {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let pattern = if let Some(expr) = call.positional.get(0) {
|
||||
let result = eval_expression(context, expr)?;
|
||||
let result = eval_expression(engine_state, stack, expr)?;
|
||||
let mut result = result.as_string()?;
|
||||
|
||||
let path = std::path::Path::new(&result);
|
||||
|
@ -3,7 +3,7 @@ use std::env::current_dir;
|
||||
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{
|
||||
IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value, ValueStream,
|
||||
};
|
||||
@ -32,13 +32,14 @@ impl Command for Mkdir {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let path = current_dir()?;
|
||||
let mut directories = call
|
||||
.rest::<String>(context, 0)?
|
||||
.rest::<String>(engine_state, stack, 0)?
|
||||
.into_iter()
|
||||
.map(|dir| path.join(dir))
|
||||
.peekable();
|
||||
|
@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
|
||||
use super::util::get_interactive_confirmation;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, ShellError, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -38,13 +38,14 @@ impl Command for Mv {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
// TODO: handle invalid directory or insufficient permissions when moving
|
||||
let source: String = call.req(context, 0)?;
|
||||
let destination: String = call.req(context, 1)?;
|
||||
let source: String = call.req(engine_state, stack, 0)?;
|
||||
let destination: String = call.req(engine_state, stack, 1)?;
|
||||
let interactive = call.has_flag("interactive");
|
||||
let force = call.has_flag("force");
|
||||
|
||||
|
@ -7,7 +7,7 @@ use super::util::get_interactive_confirmation;
|
||||
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{
|
||||
IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value, ValueStream,
|
||||
};
|
||||
@ -59,15 +59,20 @@ impl Command for Rm {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
rm(context, call)
|
||||
rm(engine_state, stack, call)
|
||||
}
|
||||
}
|
||||
|
||||
fn rm(context: &EvaluationContext, call: &Call) -> Result<PipelineData, ShellError> {
|
||||
fn rm(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let trash = call.has_flag("trash");
|
||||
let permanent = call.has_flag("permanent");
|
||||
let interactive = call.has_flag("interactive");
|
||||
@ -98,7 +103,7 @@ fn rm(context: &EvaluationContext, call: &Call) -> Result<PipelineData, ShellErr
|
||||
|
||||
let current_path = current_dir()?;
|
||||
let mut paths = call
|
||||
.rest::<String>(context, 0)?
|
||||
.rest::<String>(engine_state, stack, 0)?
|
||||
.into_iter()
|
||||
.map(|path| current_path.join(path))
|
||||
.peekable();
|
||||
|
@ -2,7 +2,7 @@ use std::fs::OpenOptions;
|
||||
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, ShellError, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -29,12 +29,13 @@ impl Command for Touch {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let target: String = call.req(context, 0)?;
|
||||
let rest: Vec<String> = call.rest(context, 1)?;
|
||||
let target: String = call.req(engine_state, stack, 0)?;
|
||||
let rest: Vec<String> = call.rest(engine_state, stack, 1)?;
|
||||
|
||||
for (index, item) in vec![target].into_iter().chain(rest).enumerate() {
|
||||
match OpenOptions::new().write(true).create(true).open(&item) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::eval_block;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -53,7 +53,8 @@ impl Command for Each {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
@ -62,7 +63,8 @@ impl Command for Each {
|
||||
.expect("internal error: expected block");
|
||||
|
||||
let numbered = call.has_flag("numbered");
|
||||
let context = context.clone();
|
||||
let engine_state = engine_state.clone();
|
||||
let mut stack = stack.clone();
|
||||
let span = call.head;
|
||||
|
||||
match input {
|
||||
@ -70,14 +72,14 @@ impl Command for Each {
|
||||
.into_range_iter()?
|
||||
.enumerate()
|
||||
.map(move |(idx, x)| {
|
||||
let block = context.engine_state.get_block(block_id);
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
||||
let state = context.enter_scope();
|
||||
let mut stack = stack.enter_scope();
|
||||
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
if numbered {
|
||||
state.add_var(
|
||||
stack.add_var(
|
||||
*var_id,
|
||||
Value::Record {
|
||||
cols: vec!["index".into(), "item".into()],
|
||||
@ -92,12 +94,12 @@ impl Command for Each {
|
||||
},
|
||||
);
|
||||
} else {
|
||||
state.add_var(*var_id, x);
|
||||
stack.add_var(*var_id, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match eval_block(&state, block, PipelineData::new()) {
|
||||
match eval_block(&engine_state, &mut stack, block, PipelineData::new()) {
|
||||
Ok(v) => v,
|
||||
Err(error) => Value::Error { error }.into_pipeline_data(),
|
||||
}
|
||||
@ -108,13 +110,13 @@ impl Command for Each {
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(move |(idx, x)| {
|
||||
let block = context.engine_state.get_block(block_id);
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
||||
let state = context.enter_scope();
|
||||
let mut stack = stack.enter_scope();
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
if numbered {
|
||||
state.add_var(
|
||||
stack.add_var(
|
||||
*var_id,
|
||||
Value::Record {
|
||||
cols: vec!["index".into(), "item".into()],
|
||||
@ -129,12 +131,12 @@ impl Command for Each {
|
||||
},
|
||||
);
|
||||
} else {
|
||||
state.add_var(*var_id, x);
|
||||
stack.add_var(*var_id, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match eval_block(&state, block, PipelineData::new()) {
|
||||
match eval_block(&engine_state, &mut stack, block, PipelineData::new()) {
|
||||
Ok(v) => v,
|
||||
Err(error) => Value::Error { error }.into_pipeline_data(),
|
||||
}
|
||||
@ -144,13 +146,13 @@ impl Command for Each {
|
||||
PipelineData::Stream(stream) => Ok(stream
|
||||
.enumerate()
|
||||
.map(move |(idx, x)| {
|
||||
let block = context.engine_state.get_block(block_id);
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
||||
let state = context.enter_scope();
|
||||
let mut stack = stack.enter_scope();
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
if numbered {
|
||||
state.add_var(
|
||||
stack.add_var(
|
||||
*var_id,
|
||||
Value::Record {
|
||||
cols: vec!["index".into(), "item".into()],
|
||||
@ -165,12 +167,12 @@ impl Command for Each {
|
||||
},
|
||||
);
|
||||
} else {
|
||||
state.add_var(*var_id, x);
|
||||
stack.add_var(*var_id, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match eval_block(&state, block, PipelineData::new()) {
|
||||
match eval_block(&engine_state, &mut stack, block, PipelineData::new()) {
|
||||
Ok(v) => v,
|
||||
Err(error) => Value::Error { error }.into_pipeline_data(),
|
||||
}
|
||||
@ -182,12 +184,12 @@ impl Command for Each {
|
||||
let mut output_vals = vec![];
|
||||
|
||||
for (col, val) in cols.into_iter().zip(vals.into_iter()) {
|
||||
let block = context.engine_state.get_block(block_id);
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
||||
let state = context.enter_scope();
|
||||
let mut stack = stack.enter_scope();
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
state.add_var(
|
||||
stack.add_var(
|
||||
*var_id,
|
||||
Value::Record {
|
||||
cols: vec!["column".into(), "value".into()],
|
||||
@ -204,7 +206,7 @@ impl Command for Each {
|
||||
}
|
||||
}
|
||||
|
||||
match eval_block(&state, block, PipelineData::new())? {
|
||||
match eval_block(&engine_state, &mut stack, block, PipelineData::new())? {
|
||||
PipelineData::Value(Value::Record {
|
||||
mut cols, mut vals, ..
|
||||
}) => {
|
||||
@ -227,16 +229,16 @@ impl Command for Each {
|
||||
.into_pipeline_data())
|
||||
}
|
||||
PipelineData::Value(x) => {
|
||||
let block = context.engine_state.get_block(block_id);
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
||||
let state = context.enter_scope();
|
||||
let mut stack = stack.enter_scope();
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
state.add_var(*var_id, x);
|
||||
stack.add_var(*var_id, x);
|
||||
}
|
||||
}
|
||||
|
||||
eval_block(&state, block, PipelineData::new())
|
||||
eval_block(&engine_state, &mut stack, block, PipelineData::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::{Call, CellPath};
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -25,11 +25,12 @@ impl Command for Get {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let cell_path: CellPath = call.req(context, 0)?;
|
||||
let cell_path: CellPath = call.req(engine_state, stack, 0)?;
|
||||
|
||||
input
|
||||
.follow_cell_path(&cell_path.members)
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -20,7 +20,8 @@ impl Command for Length {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -2,7 +2,7 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, Value, ValueStream};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -25,7 +25,8 @@ impl Command for Lines {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::{Call, CellPath};
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
@ -27,11 +27,12 @@ impl Command for Select {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let columns: Vec<CellPath> = call.rest(context, 0)?;
|
||||
let columns: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
|
||||
let span = call.head;
|
||||
|
||||
select(span, columns, input)
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::{Call, Expr, Expression};
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -21,13 +21,15 @@ impl Command for Where {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let cond = call.positional[0].clone();
|
||||
|
||||
let context = context.enter_scope();
|
||||
let engine_state = engine_state.clone();
|
||||
let mut stack = stack.enter_scope();
|
||||
|
||||
let (var_id, cond) = match cond {
|
||||
Expression {
|
||||
@ -40,9 +42,9 @@ impl Command for Where {
|
||||
match input {
|
||||
PipelineData::Stream(stream) => Ok(stream
|
||||
.filter(move |value| {
|
||||
context.add_var(var_id, value.clone());
|
||||
stack.add_var(var_id, value.clone());
|
||||
|
||||
let result = eval_expression(&context, &cond);
|
||||
let result = eval_expression(&engine_state, &mut stack, &cond);
|
||||
|
||||
match result {
|
||||
Ok(result) => result.is_true(),
|
||||
@ -53,9 +55,9 @@ impl Command for Where {
|
||||
PipelineData::Value(Value::List { vals, span }) => Ok(vals
|
||||
.into_iter()
|
||||
.filter(move |value| {
|
||||
context.add_var(var_id, value.clone());
|
||||
stack.add_var(var_id, value.clone());
|
||||
|
||||
let result = eval_expression(&context, &cond);
|
||||
let result = eval_expression(&engine_state, &mut stack, &cond);
|
||||
|
||||
match result {
|
||||
Ok(result) => result.is_true(),
|
||||
@ -64,9 +66,9 @@ impl Command for Where {
|
||||
})
|
||||
.into_pipeline_data()),
|
||||
PipelineData::Value(x) => {
|
||||
context.add_var(var_id, x.clone());
|
||||
stack.add_var(var_id, x.clone());
|
||||
|
||||
let result = eval_expression(&context, &cond)?;
|
||||
let result = eval_expression(&engine_state, &mut stack, &cond)?;
|
||||
|
||||
if result.is_true() {
|
||||
Ok(x.into_pipeline_data())
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -21,12 +21,13 @@ impl Command for Wrap {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let span = call.head;
|
||||
let name: String = call.req(context, 0)?;
|
||||
let name: String = call.req(engine_state, stack, 0)?;
|
||||
|
||||
match input {
|
||||
PipelineData::Value(Value::List { vals, .. }) => Ok(vals
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, ShellError, Signature, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -20,7 +20,8 @@ impl Command for From {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
_call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, ShellError> {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -68,7 +68,8 @@ impl Command for FromJson {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, ShellError> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
@ -44,14 +44,15 @@ impl Command for BuildString {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let output = call
|
||||
.positional
|
||||
.iter()
|
||||
.map(|expr| eval_expression(context, expr).map(|val| val.into_string()))
|
||||
.map(|expr| eval_expression(engine_state, stack, expr).map(|val| val.into_string()))
|
||||
.collect::<Result<Vec<String>, ShellError>>()?;
|
||||
|
||||
Ok(Value::String {
|
||||
|
@ -3,7 +3,7 @@ extern crate unicode_segmentation;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
@ -26,11 +26,12 @@ impl Command for Size {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
size(context, call, input)
|
||||
size(call, input)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -101,11 +102,7 @@ impl Command for Size {
|
||||
}
|
||||
}
|
||||
|
||||
fn size(
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
fn size(call: &Call, input: PipelineData) -> Result<PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
Ok(input
|
||||
.map(move |v| match v.as_string() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack},
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
|
||||
@ -39,7 +39,8 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack},
|
||||
IntoPipelineData, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
@ -34,22 +34,24 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
split_column(context, call, input)
|
||||
split_column(engine_state, stack, call, input)
|
||||
}
|
||||
}
|
||||
|
||||
fn split_column(
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let name_span = call.head;
|
||||
let separator: Spanned<String> = call.req(context, 0)?;
|
||||
let rest: Vec<Spanned<String>> = call.rest(context, 1)?;
|
||||
let separator: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
let rest: Vec<Spanned<String>> = call.rest(engine_state, stack, 1)?;
|
||||
let collapse_empty = call.has_flag("collapse-empty");
|
||||
|
||||
Ok(input
|
||||
|
@ -1,7 +1,7 @@
|
||||
use nu_engine::get_full_help;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack},
|
||||
IntoPipelineData, PipelineData, Signature, Value,
|
||||
};
|
||||
|
||||
@ -23,12 +23,17 @@ impl Command for SplitCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
Ok(Value::String {
|
||||
val: get_full_help(&SplitCommand.signature(), &SplitCommand.examples(), context),
|
||||
val: get_full_help(
|
||||
&SplitCommand.signature(),
|
||||
&SplitCommand.examples(),
|
||||
engine_state,
|
||||
),
|
||||
span: call.head,
|
||||
}
|
||||
.into_pipeline_data())
|
||||
|
@ -1,7 +1,7 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack},
|
||||
IntoPipelineData, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
@ -27,21 +27,23 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
split_row(context, call, input)
|
||||
split_row(engine_state, stack, call, input)
|
||||
}
|
||||
}
|
||||
|
||||
fn split_row(
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let name_span = call.head;
|
||||
let separator: Spanned<String> = call.req(context, 0)?;
|
||||
let separator: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
|
||||
Ok(input
|
||||
.flat_map(move |x| split_row_helper(&x, &separator, name_span))
|
||||
|
@ -2,7 +2,7 @@ use std::time::Instant;
|
||||
|
||||
use nu_engine::eval_block;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -27,18 +27,19 @@ impl Command for Benchmark {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let block = call.positional[0]
|
||||
.as_block()
|
||||
.expect("internal error: expected block");
|
||||
let block = context.engine_state.get_block(block);
|
||||
let block = engine_state.get_block(block);
|
||||
|
||||
let state = context.enter_scope();
|
||||
let mut stack = stack.enter_scope();
|
||||
let start_time = Instant::now();
|
||||
eval_block(&state, block, PipelineData::new())?;
|
||||
eval_block(&engine_state, &mut stack, block, PipelineData::new())?;
|
||||
let end_time = Instant::now();
|
||||
println!("{} ms", (end_time - start_time).as_millis());
|
||||
Ok(PipelineData::new())
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack},
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Value,
|
||||
};
|
||||
use sysinfo::{ProcessExt, System, SystemExt};
|
||||
@ -30,7 +30,8 @@ impl Command for Ps {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,19 +1,21 @@
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::io::{BufRead, BufReader, Write};
|
||||
use std::process::{ChildStdin, Command as CommandSys, Stdio};
|
||||
use std::rc::Rc;
|
||||
use std::sync::mpsc;
|
||||
|
||||
use nu_protocol::engine::{EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
ast::{Call, Expression},
|
||||
engine::{Command, EvaluationContext},
|
||||
ShellError, Signature, SyntaxShape, Value,
|
||||
};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Span, ValueStream};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Span, Spanned, ValueStream};
|
||||
|
||||
use nu_engine::eval_expression;
|
||||
use nu_engine::{eval_expression, CallExt};
|
||||
|
||||
const OUTPUT_BUFFER_SIZE: usize = 8192;
|
||||
|
||||
@ -37,52 +39,34 @@ impl Command for External {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let command = ExternalCommand::try_new(call, context)?;
|
||||
let name: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
let args: Vec<String> = call.rest(engine_state, stack, 1)?;
|
||||
let last_expression = call.has_flag("last_expression");
|
||||
let env_vars = stack.get_env_vars();
|
||||
|
||||
let command = ExternalCommand {
|
||||
name,
|
||||
args,
|
||||
last_expression,
|
||||
env_vars,
|
||||
};
|
||||
command.run_with_input(input)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExternalCommand<'call, 'contex> {
|
||||
pub name: &'call Expression,
|
||||
pub args: &'call [Expression],
|
||||
pub context: &'contex EvaluationContext,
|
||||
pub struct ExternalCommand {
|
||||
pub name: Spanned<String>,
|
||||
pub args: Vec<String>,
|
||||
pub last_expression: bool,
|
||||
pub env_vars: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl<'call, 'contex> ExternalCommand<'call, 'contex> {
|
||||
pub fn try_new(
|
||||
call: &'call Call,
|
||||
context: &'contex EvaluationContext,
|
||||
) -> Result<Self, ShellError> {
|
||||
if call.positional.is_empty() {
|
||||
return Err(ShellError::ExternalNotSupported(call.head));
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
name: &call.positional[0],
|
||||
args: &call.positional[1..],
|
||||
context,
|
||||
last_expression: call.has_flag("last_expression"),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> Result<String, ShellError> {
|
||||
let value = eval_expression(self.context, self.name)?;
|
||||
value.as_string()
|
||||
}
|
||||
|
||||
pub fn get_args(&self) -> Vec<String> {
|
||||
self.args
|
||||
.iter()
|
||||
.filter_map(|expr| eval_expression(self.context, expr).ok())
|
||||
.filter_map(|value| value.as_string().ok())
|
||||
.collect()
|
||||
}
|
||||
|
||||
impl ExternalCommand {
|
||||
pub fn run_with_input(&self, input: PipelineData) -> Result<PipelineData, ShellError> {
|
||||
let mut process = self.create_command();
|
||||
|
||||
@ -91,8 +75,7 @@ impl<'call, 'contex> ExternalCommand<'call, 'contex> {
|
||||
let path = env::current_dir().unwrap();
|
||||
process.current_dir(path);
|
||||
|
||||
let envs = self.context.stack.get_env_vars();
|
||||
process.envs(envs);
|
||||
process.envs(&self.env_vars);
|
||||
|
||||
// If the external is not the last command, its output will get piped
|
||||
// either as a string or binary
|
||||
@ -195,8 +178,8 @@ impl<'call, 'contex> ExternalCommand<'call, 'contex> {
|
||||
// for minimal builds cwd is unused
|
||||
let mut process = CommandSys::new("cmd");
|
||||
process.arg("/c");
|
||||
process.arg(&self.get_name().unwrap());
|
||||
for arg in self.get_args() {
|
||||
process.arg(&self.name.item);
|
||||
for arg in &self.args {
|
||||
// Clean the args before we use them:
|
||||
// https://stackoverflow.com/questions/1200235/how-to-pass-a-quoted-pipe-character-to-cmd-exe
|
||||
// cmd.exe needs to have a caret to escape a pipe
|
||||
@ -205,7 +188,7 @@ impl<'call, 'contex> ExternalCommand<'call, 'contex> {
|
||||
}
|
||||
process
|
||||
} else {
|
||||
let cmd_with_args = vec![self.get_name().unwrap(), self.get_args().join(" ")].join(" ");
|
||||
let cmd_with_args = vec![self.name.item.clone(), self.args.join(" ")].join(" ");
|
||||
let mut process = CommandSys::new("sh");
|
||||
process.arg("-c").arg(cmd_with_args);
|
||||
process
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack},
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Value,
|
||||
};
|
||||
use sysinfo::{ComponentExt, DiskExt, NetworkExt, ProcessorExt, System, SystemExt, UserExt};
|
||||
@ -25,7 +25,8 @@ impl Command for Sys {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -2,7 +2,7 @@ use lscolors::{LsColors, Style};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::{Call, PathMember},
|
||||
engine::{Command, EvaluationContext},
|
||||
engine::{Command, EngineState, EvaluationContext, Stack},
|
||||
IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
use nu_term_grid::grid::{Alignment, Cell, Direction, Filling, Grid, GridOptions};
|
||||
@ -48,13 +48,14 @@ prints out the list properly."#
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let width_param: Option<String> = call.get_flag(context, "width")?;
|
||||
let width_param: Option<String> = call.get_flag(engine_state, stack, "width")?;
|
||||
let color_param: bool = call.has_flag("color");
|
||||
let separator_param: Option<String> = call.get_flag(context, "separator")?;
|
||||
let separator_param: Option<String> = call.get_flag(engine_state, stack, "separator")?;
|
||||
|
||||
match input {
|
||||
PipelineData::Value(Value::List { vals, .. }) => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_protocol::ast::{Call, PathMember};
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::{Command, EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, Span, Value};
|
||||
use nu_table::StyledString;
|
||||
use std::collections::HashMap;
|
||||
@ -24,7 +24,8 @@ impl Command for Table {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,37 +1,50 @@
|
||||
use nu_protocol::{ast::Call, engine::EvaluationContext, ShellError};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{EngineState, EvaluationContext, Stack},
|
||||
ShellError,
|
||||
};
|
||||
|
||||
use crate::{eval_expression, FromValue};
|
||||
|
||||
pub trait CallExt {
|
||||
fn get_flag<T: FromValue>(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
name: &str,
|
||||
) -> Result<Option<T>, ShellError>;
|
||||
|
||||
fn rest<T: FromValue>(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
starting_pos: usize,
|
||||
) -> Result<Vec<T>, ShellError>;
|
||||
|
||||
fn opt<T: FromValue>(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
pos: usize,
|
||||
) -> Result<Option<T>, ShellError>;
|
||||
|
||||
fn req<T: FromValue>(&self, context: &EvaluationContext, pos: usize) -> Result<T, ShellError>;
|
||||
fn req<T: FromValue>(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
pos: usize,
|
||||
) -> Result<T, ShellError>;
|
||||
}
|
||||
|
||||
impl CallExt for Call {
|
||||
fn get_flag<T: FromValue>(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
name: &str,
|
||||
) -> Result<Option<T>, ShellError> {
|
||||
if let Some(expr) = self.get_flag_expr(name) {
|
||||
let result = eval_expression(context, &expr)?;
|
||||
let result = eval_expression(engine_state, stack, &expr)?;
|
||||
FromValue::from_value(&result).map(Some)
|
||||
} else {
|
||||
Ok(None)
|
||||
@ -40,13 +53,14 @@ impl CallExt for Call {
|
||||
|
||||
fn rest<T: FromValue>(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
starting_pos: usize,
|
||||
) -> Result<Vec<T>, ShellError> {
|
||||
let mut output = vec![];
|
||||
|
||||
for expr in self.positional.iter().skip(starting_pos) {
|
||||
let result = eval_expression(context, expr)?;
|
||||
let result = eval_expression(engine_state, stack, expr)?;
|
||||
output.push(FromValue::from_value(&result)?);
|
||||
}
|
||||
|
||||
@ -55,20 +69,26 @@ impl CallExt for Call {
|
||||
|
||||
fn opt<T: FromValue>(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
pos: usize,
|
||||
) -> Result<Option<T>, ShellError> {
|
||||
if let Some(expr) = self.nth(pos) {
|
||||
let result = eval_expression(context, &expr)?;
|
||||
let result = eval_expression(engine_state, stack, &expr)?;
|
||||
FromValue::from_value(&result).map(Some)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn req<T: FromValue>(&self, context: &EvaluationContext, pos: usize) -> Result<T, ShellError> {
|
||||
fn req<T: FromValue>(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
pos: usize,
|
||||
) -> Result<T, ShellError> {
|
||||
if let Some(expr) = self.nth(pos) {
|
||||
let result = eval_expression(context, &expr)?;
|
||||
let result = eval_expression(engine_state, stack, &expr)?;
|
||||
FromValue::from_value(&result)
|
||||
} else {
|
||||
Err(ShellError::AccessBeyondEnd(
|
||||
|
@ -1,5 +1,8 @@
|
||||
use itertools::Itertools;
|
||||
use nu_protocol::{engine::EvaluationContext, Example, Signature, Span, Value};
|
||||
use nu_protocol::{
|
||||
engine::{EngineState, EvaluationContext},
|
||||
Example, Signature, Span, Value,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
const COMMANDS_DOCS_DIR: &str = "docs/commands";
|
||||
@ -22,14 +25,13 @@ impl Default for DocumentationConfig {
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_doc(name: &str, context: &EvaluationContext) -> (Vec<String>, Vec<Value>) {
|
||||
fn generate_doc(name: &str, engine_state: &EngineState) -> (Vec<String>, Vec<Value>) {
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
|
||||
let command = context
|
||||
.engine_state
|
||||
let command = engine_state
|
||||
.find_decl(name.as_bytes())
|
||||
.map(|decl_id| context.engine_state.get_decl(decl_id))
|
||||
.map(|decl_id| engine_state.get_decl(decl_id))
|
||||
.unwrap_or_else(|| panic!("Expected command '{}' from names to be in registry", name));
|
||||
|
||||
cols.push("name".to_string());
|
||||
@ -57,7 +59,7 @@ fn generate_doc(name: &str, context: &EvaluationContext) -> (Vec<String>, Vec<Va
|
||||
val: get_documentation(
|
||||
&command.signature(),
|
||||
&command.examples(),
|
||||
context,
|
||||
engine_state,
|
||||
&DocumentationConfig {
|
||||
no_subcommands: true,
|
||||
no_color: true,
|
||||
@ -71,8 +73,8 @@ fn generate_doc(name: &str, context: &EvaluationContext) -> (Vec<String>, Vec<Va
|
||||
}
|
||||
|
||||
// generate_docs gets the documentation from each command and returns a Table as output
|
||||
pub fn generate_docs(context: &EvaluationContext) -> Value {
|
||||
let signatures = context.get_signatures();
|
||||
pub fn generate_docs(engine_state: &EngineState) -> Value {
|
||||
let signatures = engine_state.get_signatures();
|
||||
|
||||
// cmap will map parent commands to it's subcommands e.g. to -> [to csv, to yaml, to bson]
|
||||
let mut cmap: HashMap<String, Vec<String>> = HashMap::new();
|
||||
@ -98,11 +100,11 @@ pub fn generate_docs(context: &EvaluationContext) -> Value {
|
||||
if !cmap.contains_key(&sig.name) {
|
||||
continue;
|
||||
}
|
||||
let mut row_entries = generate_doc(&sig.name, context);
|
||||
let mut row_entries = generate_doc(&sig.name, engine_state);
|
||||
// Iterate over all the subcommands of the parent command
|
||||
let mut sub_table = Vec::new();
|
||||
for sub_name in cmap.get(&sig.name).unwrap_or(&Vec::new()) {
|
||||
let (cols, vals) = generate_doc(sub_name, context);
|
||||
let (cols, vals) = generate_doc(sub_name, engine_state);
|
||||
sub_table.push(Value::Record {
|
||||
cols,
|
||||
vals,
|
||||
@ -148,7 +150,7 @@ fn retrieve_doc_link(name: &str) -> Option<String> {
|
||||
pub fn get_documentation(
|
||||
sig: &Signature,
|
||||
examples: &[Example],
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
config: &DocumentationConfig,
|
||||
) -> String {
|
||||
let cmd_name = &sig.name;
|
||||
@ -168,7 +170,7 @@ pub fn get_documentation(
|
||||
|
||||
let mut subcommands = vec![];
|
||||
if !config.no_subcommands {
|
||||
let signatures = context.get_signatures();
|
||||
let signatures = engine_state.get_signatures();
|
||||
for sig in signatures {
|
||||
if sig.name.starts_with(&format!("{} ", cmd_name)) {
|
||||
subcommands.push(format!(" {} - {}", sig.name, sig.usage));
|
||||
@ -324,15 +326,11 @@ fn get_flags_section(signature: &Signature) -> String {
|
||||
long_desc
|
||||
}
|
||||
|
||||
pub fn get_brief_help(
|
||||
sig: &Signature,
|
||||
examples: &[Example],
|
||||
context: &EvaluationContext,
|
||||
) -> String {
|
||||
pub fn get_brief_help(sig: &Signature, examples: &[Example], engine_state: &EngineState) -> String {
|
||||
get_documentation(
|
||||
sig,
|
||||
examples,
|
||||
context,
|
||||
engine_state,
|
||||
&DocumentationConfig {
|
||||
no_subcommands: false,
|
||||
no_color: false,
|
||||
@ -341,6 +339,6 @@ pub fn get_brief_help(
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_full_help(sig: &Signature, examples: &[Example], context: &EvaluationContext) -> String {
|
||||
get_documentation(sig, examples, context, &DocumentationConfig::default())
|
||||
pub fn get_full_help(sig: &Signature, examples: &[Example], engine_state: &EngineState) -> String {
|
||||
get_documentation(sig, examples, engine_state, &DocumentationConfig::default())
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_protocol::ast::{Block, Call, Expr, Expression, Operator, Statement};
|
||||
use nu_protocol::engine::EvaluationContext;
|
||||
use nu_protocol::engine::{EngineState, EvaluationContext, Stack};
|
||||
use nu_protocol::{
|
||||
IntoPipelineData, PipelineData, Range, ShellError, Span, Spanned, Type, Unit, Value,
|
||||
};
|
||||
@ -19,32 +19,33 @@ pub fn eval_operator(op: &Expression) -> Result<Operator, ShellError> {
|
||||
}
|
||||
|
||||
fn eval_call(
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let decl = context.engine_state.get_decl(call.decl_id);
|
||||
let decl = engine_state.get_decl(call.decl_id);
|
||||
if call.named.iter().any(|(flag, _)| flag.item == "help") {
|
||||
let full_help = get_full_help(&decl.signature(), &decl.examples(), context);
|
||||
let full_help = get_full_help(&decl.signature(), &decl.examples(), engine_state);
|
||||
Ok(Value::String {
|
||||
val: full_help,
|
||||
span: call.head,
|
||||
}
|
||||
.into_pipeline_data())
|
||||
} else if let Some(block_id) = decl.get_block_id() {
|
||||
let mut state = context.enter_scope();
|
||||
let mut stack = stack.enter_scope();
|
||||
for (arg, param) in call.positional.iter().zip(
|
||||
decl.signature()
|
||||
.required_positional
|
||||
.iter()
|
||||
.chain(decl.signature().optional_positional.iter()),
|
||||
) {
|
||||
let result = eval_expression(&state, arg)?;
|
||||
let result = eval_expression(engine_state, &mut stack, arg)?;
|
||||
let var_id = param
|
||||
.var_id
|
||||
.expect("internal error: all custom parameters must have var_ids");
|
||||
|
||||
state.add_var(var_id, result);
|
||||
stack.add_var(var_id, result);
|
||||
}
|
||||
|
||||
if let Some(rest_positional) = decl.signature().rest_positional {
|
||||
@ -54,7 +55,7 @@ fn eval_call(
|
||||
decl.signature().required_positional.len()
|
||||
+ decl.signature().optional_positional.len(),
|
||||
) {
|
||||
let result = eval_expression(&state, arg)?;
|
||||
let result = eval_expression(&engine_state, &mut stack, arg)?;
|
||||
rest_items.push(result);
|
||||
}
|
||||
|
||||
@ -64,7 +65,7 @@ fn eval_call(
|
||||
Span::unknown()
|
||||
};
|
||||
|
||||
state.add_var(
|
||||
stack.add_var(
|
||||
rest_positional
|
||||
.var_id
|
||||
.expect("Internal error: rest positional parameter lacks var_id"),
|
||||
@ -81,11 +82,11 @@ fn eval_call(
|
||||
for call_named in &call.named {
|
||||
if call_named.0.item == named.long {
|
||||
if let Some(arg) = &call_named.1 {
|
||||
let result = eval_expression(&state, arg)?;
|
||||
let result = eval_expression(&engine_state, &mut stack, arg)?;
|
||||
|
||||
state.add_var(var_id, result);
|
||||
stack.add_var(var_id, result);
|
||||
} else {
|
||||
state.add_var(
|
||||
stack.add_var(
|
||||
var_id,
|
||||
Value::Bool {
|
||||
val: true,
|
||||
@ -98,7 +99,7 @@ fn eval_call(
|
||||
}
|
||||
|
||||
if !found && named.arg.is_none() {
|
||||
state.add_var(
|
||||
stack.add_var(
|
||||
var_id,
|
||||
Value::Bool {
|
||||
val: false,
|
||||
@ -108,27 +109,27 @@ fn eval_call(
|
||||
}
|
||||
}
|
||||
}
|
||||
let block = context.engine_state.get_block(block_id);
|
||||
eval_block(&state, block, input)
|
||||
let block = engine_state.get_block(block_id);
|
||||
eval_block(engine_state, &mut stack, block, input)
|
||||
} else {
|
||||
decl.run(context, call, input)
|
||||
decl.run(engine_state, stack, call, input)
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_external(
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
name: &str,
|
||||
name_span: &Span,
|
||||
args: &[Expression],
|
||||
input: PipelineData,
|
||||
last_expression: bool,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let decl_id = context
|
||||
.engine_state
|
||||
let decl_id = engine_state
|
||||
.find_decl("run_external".as_bytes())
|
||||
.ok_or_else(|| ShellError::ExternalNotSupported(*name_span))?;
|
||||
|
||||
let command = context.engine_state.get_decl(decl_id);
|
||||
let command = engine_state.get_decl(decl_id);
|
||||
|
||||
let mut call = Call::new();
|
||||
|
||||
@ -153,11 +154,12 @@ fn eval_external(
|
||||
))
|
||||
}
|
||||
|
||||
command.run(context, &call, input)
|
||||
command.run(engine_state, stack, &call, input)
|
||||
}
|
||||
|
||||
pub fn eval_expression(
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
expr: &Expression,
|
||||
) -> Result<Value, ShellError> {
|
||||
match &expr.expr {
|
||||
@ -173,13 +175,13 @@ pub fn eval_expression(
|
||||
val: *f,
|
||||
span: expr.span,
|
||||
}),
|
||||
Expr::ValueWithUnit(e, unit) => match eval_expression(context, e)? {
|
||||
Expr::ValueWithUnit(e, unit) => match eval_expression(engine_state, stack, e)? {
|
||||
Value::Int { val, .. } => Ok(compute(val, unit.item, unit.span)),
|
||||
_ => Err(ShellError::CantConvert("unit value".into(), e.span)),
|
||||
},
|
||||
Expr::Range(from, next, to, operator) => {
|
||||
let from = if let Some(f) = from {
|
||||
eval_expression(context, f)?
|
||||
eval_expression(engine_state, stack, f)?
|
||||
} else {
|
||||
Value::Nothing {
|
||||
span: Span::unknown(),
|
||||
@ -187,7 +189,7 @@ pub fn eval_expression(
|
||||
};
|
||||
|
||||
let next = if let Some(s) = next {
|
||||
eval_expression(context, s)?
|
||||
eval_expression(engine_state, stack, s)?
|
||||
} else {
|
||||
Value::Nothing {
|
||||
span: Span::unknown(),
|
||||
@ -195,7 +197,7 @@ pub fn eval_expression(
|
||||
};
|
||||
|
||||
let to = if let Some(t) = to {
|
||||
eval_expression(context, t)?
|
||||
eval_expression(engine_state, stack, t)?
|
||||
} else {
|
||||
Value::Nothing {
|
||||
span: Span::unknown(),
|
||||
@ -207,7 +209,7 @@ pub fn eval_expression(
|
||||
span: expr.span,
|
||||
})
|
||||
}
|
||||
Expr::Var(var_id) => context
|
||||
Expr::Var(var_id) => stack
|
||||
.get_var(*var_id)
|
||||
.map_err(move |_| ShellError::VariableNotFoundAtRuntime(expr.span)),
|
||||
Expr::CellPath(cell_path) => Ok(Value::CellPath {
|
||||
@ -215,32 +217,40 @@ pub fn eval_expression(
|
||||
span: expr.span,
|
||||
}),
|
||||
Expr::FullCellPath(cell_path) => {
|
||||
let value = eval_expression(context, &cell_path.head)?;
|
||||
let value = eval_expression(engine_state, stack, &cell_path.head)?;
|
||||
|
||||
value.follow_cell_path(&cell_path.tail)
|
||||
}
|
||||
Expr::RowCondition(_, expr) => eval_expression(context, expr),
|
||||
Expr::RowCondition(_, expr) => eval_expression(engine_state, stack, expr),
|
||||
Expr::Call(call) => {
|
||||
// FIXME: protect this collect with ctrl-c
|
||||
Ok(Value::List {
|
||||
vals: eval_call(context, call, PipelineData::new())?.collect(),
|
||||
vals: eval_call(engine_state, stack, call, PipelineData::new())?.collect(),
|
||||
span: expr.span,
|
||||
})
|
||||
}
|
||||
Expr::ExternalCall(name, span, args) => {
|
||||
// FIXME: protect this collect with ctrl-c
|
||||
Ok(Value::List {
|
||||
vals: eval_external(context, name, span, args, PipelineData::new(), true)?
|
||||
.collect(),
|
||||
vals: eval_external(
|
||||
engine_state,
|
||||
stack,
|
||||
name,
|
||||
span,
|
||||
args,
|
||||
PipelineData::new(),
|
||||
true,
|
||||
)?
|
||||
.collect(),
|
||||
span: expr.span,
|
||||
})
|
||||
}
|
||||
Expr::Operator(_) => Ok(Value::Nothing { span: expr.span }),
|
||||
Expr::BinaryOp(lhs, op, rhs) => {
|
||||
let op_span = op.span;
|
||||
let lhs = eval_expression(context, lhs)?;
|
||||
let lhs = eval_expression(engine_state, stack, lhs)?;
|
||||
let op = eval_operator(op)?;
|
||||
let rhs = eval_expression(context, rhs)?;
|
||||
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||
|
||||
match op {
|
||||
Operator::Plus => lhs.add(op_span, &rhs),
|
||||
@ -264,13 +274,13 @@ pub fn eval_expression(
|
||||
}
|
||||
}
|
||||
Expr::Subexpression(block_id) => {
|
||||
let block = context.engine_state.get_block(*block_id);
|
||||
let block = engine_state.get_block(*block_id);
|
||||
|
||||
let state = context.enter_scope();
|
||||
let mut stack = stack.enter_scope();
|
||||
|
||||
// FIXME: protect this collect with ctrl-c
|
||||
Ok(Value::List {
|
||||
vals: eval_block(&state, block, PipelineData::new())?.collect(),
|
||||
vals: eval_block(engine_state, &mut stack, block, PipelineData::new())?.collect(),
|
||||
span: expr.span,
|
||||
})
|
||||
}
|
||||
@ -281,7 +291,7 @@ pub fn eval_expression(
|
||||
Expr::List(x) => {
|
||||
let mut output = vec![];
|
||||
for expr in x {
|
||||
output.push(eval_expression(context, expr)?);
|
||||
output.push(eval_expression(engine_state, stack, expr)?);
|
||||
}
|
||||
Ok(Value::List {
|
||||
vals: output,
|
||||
@ -291,14 +301,14 @@ pub fn eval_expression(
|
||||
Expr::Table(headers, vals) => {
|
||||
let mut output_headers = vec![];
|
||||
for expr in headers {
|
||||
output_headers.push(eval_expression(context, expr)?.as_string()?);
|
||||
output_headers.push(eval_expression(engine_state, stack, expr)?.as_string()?);
|
||||
}
|
||||
|
||||
let mut output_rows = vec![];
|
||||
for val in vals {
|
||||
let mut row = vec![];
|
||||
for expr in val {
|
||||
row.push(eval_expression(context, expr)?);
|
||||
row.push(eval_expression(engine_state, stack, expr)?);
|
||||
}
|
||||
output_rows.push(Value::Record {
|
||||
cols: output_headers.clone(),
|
||||
@ -311,7 +321,7 @@ pub fn eval_expression(
|
||||
span: expr.span,
|
||||
})
|
||||
}
|
||||
Expr::Keyword(_, _, expr) => eval_expression(context, expr),
|
||||
Expr::Keyword(_, _, expr) => eval_expression(engine_state, stack, expr),
|
||||
Expr::String(s) => Ok(Value::String {
|
||||
val: s.clone(),
|
||||
span: expr.span,
|
||||
@ -330,7 +340,8 @@ pub fn eval_expression(
|
||||
}
|
||||
|
||||
pub fn eval_block(
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
block: &Block,
|
||||
mut input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
@ -342,14 +353,15 @@ pub fn eval_block(
|
||||
expr: Expr::Call(call),
|
||||
..
|
||||
} => {
|
||||
input = eval_call(context, call, input)?;
|
||||
input = eval_call(engine_state, stack, call, input)?;
|
||||
}
|
||||
Expression {
|
||||
expr: Expr::ExternalCall(name, name_span, args),
|
||||
..
|
||||
} => {
|
||||
input = eval_external(
|
||||
context,
|
||||
engine_state,
|
||||
stack,
|
||||
name,
|
||||
name_span,
|
||||
args,
|
||||
@ -359,7 +371,7 @@ pub fn eval_block(
|
||||
}
|
||||
|
||||
elem => {
|
||||
input = eval_expression(context, elem)?.into_pipeline_data();
|
||||
input = eval_expression(engine_state, stack, elem)?.into_pipeline_data();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use nu_parser::ParseError;
|
||||
use nu_parser::*;
|
||||
use nu_protocol::{
|
||||
ast::{Expr, Expression, Pipeline, Statement},
|
||||
engine::{Command, EngineState, StateWorkingSet},
|
||||
engine::{Command, EngineState, Stack, StateWorkingSet},
|
||||
Signature, SyntaxShape,
|
||||
};
|
||||
|
||||
@ -32,7 +32,8 @@ impl Command for Let {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &nu_protocol::engine::EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
_call: &nu_protocol::ast::Call,
|
||||
_input: nu_protocol::PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{ast::Call, value::Value, BlockId, Example, PipelineData, ShellError, Signature};
|
||||
|
||||
use super::EvaluationContext;
|
||||
use super::{EngineState, EvaluationContext, Stack};
|
||||
|
||||
pub trait Command: Send + Sync + CommandClone {
|
||||
fn name(&self) -> &str;
|
||||
@ -17,7 +17,8 @@ pub trait Command: Send + Sync + CommandClone {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError>;
|
||||
|
@ -1,7 +1,9 @@
|
||||
use crate::ast::Call;
|
||||
use crate::engine::Command;
|
||||
use crate::engine::CommandClone;
|
||||
use crate::engine::EngineState;
|
||||
use crate::engine::EvaluationContext;
|
||||
use crate::engine::Stack;
|
||||
use crate::BlockId;
|
||||
use crate::PipelineData;
|
||||
use crate::SyntaxShape;
|
||||
@ -357,7 +359,8 @@ impl Command for Predeclaration {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
_call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, crate::ShellError> {
|
||||
@ -386,7 +389,8 @@ impl Command for BlockCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
_call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<crate::PipelineData, crate::ShellError> {
|
||||
|
150
src/main.rs
150
src/main.rs
@ -13,7 +13,7 @@ use nu_parser::parse;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{EngineState, EvaluationContext, Stack, StateWorkingSet},
|
||||
ShellError, Value,
|
||||
IntoPipelineData, PipelineData, ShellError, Value,
|
||||
};
|
||||
use reedline::{Completer, CompletionActionHandler, DefaultPrompt, LineBuffer, Prompt};
|
||||
|
||||
@ -82,14 +82,13 @@ fn main() -> Result<()> {
|
||||
miette_hook(x);
|
||||
}));
|
||||
|
||||
let engine_state = create_default_context();
|
||||
let mut engine_state = create_default_context();
|
||||
|
||||
if let Some(path) = std::env::args().nth(1) {
|
||||
let file = std::fs::read(&path).into_diagnostic()?;
|
||||
|
||||
let (block, delta) = {
|
||||
let engine_state = engine_state.borrow();
|
||||
let mut working_set = StateWorkingSet::new(&*engine_state);
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
let (output, err) = parse(&mut working_set, Some(&path), &file, false);
|
||||
if let Some(err) = err {
|
||||
report_error(&working_set, &err);
|
||||
@ -99,20 +98,16 @@ fn main() -> Result<()> {
|
||||
(output, working_set.render())
|
||||
};
|
||||
|
||||
EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta);
|
||||
EngineState::merge_delta(&mut engine_state, delta);
|
||||
|
||||
let state = EvaluationContext {
|
||||
engine_state: engine_state.clone(),
|
||||
stack: nu_protocol::engine::Stack::new(),
|
||||
};
|
||||
let mut stack = nu_protocol::engine::Stack::new();
|
||||
|
||||
match eval_block(&state, &block, Value::nothing()) {
|
||||
Ok(value) => {
|
||||
println!("{}", value.into_string());
|
||||
match eval_block(&engine_state, &mut stack, &block, PipelineData::new()) {
|
||||
Ok(pipeline_data) => {
|
||||
println!("{}", pipeline_data.collect_string());
|
||||
}
|
||||
Err(err) => {
|
||||
let engine_state = engine_state.borrow();
|
||||
let working_set = StateWorkingSet::new(&*engine_state);
|
||||
let working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
report_error(&working_set, &err);
|
||||
|
||||
@ -127,28 +122,9 @@ fn main() -> Result<()> {
|
||||
let completer = NuCompleter::new(engine_state.clone());
|
||||
let mut entry_num = 0;
|
||||
|
||||
let mut line_editor = Reedline::create()
|
||||
.into_diagnostic()?
|
||||
.with_history(Box::new(
|
||||
FileBackedHistory::with_file(1000, "history.txt".into()).into_diagnostic()?,
|
||||
))
|
||||
.into_diagnostic()?
|
||||
.with_highlighter(Box::new(NuHighlighter {
|
||||
engine_state: engine_state.clone(),
|
||||
}))
|
||||
.with_completion_action_handler(Box::new(FuzzyCompletion {
|
||||
completer: Box::new(completer),
|
||||
}))
|
||||
// .with_completion_action_handler(Box::new(
|
||||
// ListCompletionHandler::default().with_completer(Box::new(completer)),
|
||||
// ))
|
||||
.with_validator(Box::new(NuValidator {
|
||||
engine_state: engine_state.clone(),
|
||||
}));
|
||||
|
||||
let default_prompt = DefaultPrompt::new(1);
|
||||
let mut nu_prompt = NushellPrompt::new();
|
||||
let stack = nu_protocol::engine::Stack::new();
|
||||
let mut stack = nu_protocol::engine::Stack::new();
|
||||
|
||||
// Load config startup file
|
||||
if let Some(mut config_path) = nu_path::config_dir() {
|
||||
@ -162,15 +138,34 @@ fn main() -> Result<()> {
|
||||
let config_filename = config_path.to_string_lossy().to_owned();
|
||||
|
||||
if let Ok(contents) = std::fs::read_to_string(&config_path) {
|
||||
eval_source(engine_state.clone(), &stack, &contents, &config_filename);
|
||||
eval_source(&mut engine_state, &mut stack, &contents, &config_filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
let mut line_editor = Reedline::create()
|
||||
.into_diagnostic()?
|
||||
.with_history(Box::new(
|
||||
FileBackedHistory::with_file(1000, "history.txt".into()).into_diagnostic()?,
|
||||
))
|
||||
.into_diagnostic()?
|
||||
.with_highlighter(Box::new(NuHighlighter {
|
||||
engine_state: engine_state.clone(),
|
||||
}))
|
||||
.with_completion_action_handler(Box::new(FuzzyCompletion {
|
||||
completer: Box::new(completer.clone()),
|
||||
}))
|
||||
// .with_completion_action_handler(Box::new(
|
||||
// ListCompletionHandler::default().with_completer(Box::new(completer)),
|
||||
// ))
|
||||
.with_validator(Box::new(NuValidator {
|
||||
engine_state: engine_state.clone(),
|
||||
}));
|
||||
|
||||
let prompt = update_prompt(
|
||||
PROMPT_COMMAND,
|
||||
engine_state.clone(),
|
||||
&engine_state,
|
||||
&stack,
|
||||
&mut nu_prompt,
|
||||
&default_prompt,
|
||||
@ -184,25 +179,27 @@ fn main() -> Result<()> {
|
||||
if s.trim() == "exit" {
|
||||
break;
|
||||
} else if s.trim() == "vars" {
|
||||
engine_state.borrow().print_vars();
|
||||
engine_state.print_vars();
|
||||
continue;
|
||||
} else if s.trim() == "decls" {
|
||||
engine_state.borrow().print_decls();
|
||||
engine_state.print_decls();
|
||||
continue;
|
||||
} else if s.trim() == "blocks" {
|
||||
engine_state.borrow().print_blocks();
|
||||
engine_state.print_blocks();
|
||||
continue;
|
||||
} else if s.trim() == "stack" {
|
||||
stack.print_stack();
|
||||
continue;
|
||||
} else if s.trim() == "contents" {
|
||||
engine_state.borrow().print_contents();
|
||||
engine_state.print_contents();
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut engine_state = engine_state.clone();
|
||||
|
||||
eval_source(
|
||||
engine_state.clone(),
|
||||
&stack,
|
||||
&mut engine_state,
|
||||
&mut stack,
|
||||
&s,
|
||||
&format!("entry #{}", entry_num),
|
||||
);
|
||||
@ -229,16 +226,19 @@ fn main() -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
fn print_value(value: Value, state: &EvaluationContext) -> Result<(), ShellError> {
|
||||
fn print_value(value: Value, engine_state: &EngineState) -> Result<(), ShellError> {
|
||||
// If the table function is in the declarations, then we can use it
|
||||
// to create the table value that will be printed in the terminal
|
||||
let engine_state = state.engine_state.borrow();
|
||||
let output = match engine_state.find_decl("table".as_bytes()) {
|
||||
Some(decl_id) => {
|
||||
let table = engine_state
|
||||
.get_decl(decl_id)
|
||||
.run(state, &Call::new(), value)?;
|
||||
table.into_string()
|
||||
let mut stack = Stack::new();
|
||||
let table = engine_state.get_decl(decl_id).run(
|
||||
engine_state,
|
||||
&mut stack,
|
||||
&Call::new(),
|
||||
value.into_pipeline_data(),
|
||||
)?;
|
||||
table.collect_string()
|
||||
}
|
||||
None => value.into_string(),
|
||||
};
|
||||
@ -254,7 +254,7 @@ fn print_value(value: Value, state: &EvaluationContext) -> Result<(), ShellError
|
||||
|
||||
fn update_prompt<'prompt>(
|
||||
env_variable: &str,
|
||||
engine_state: Rc<RefCell<EngineState>>,
|
||||
engine_state: &EngineState,
|
||||
stack: &Stack,
|
||||
nu_prompt: &'prompt mut NushellPrompt,
|
||||
default_prompt: &'prompt DefaultPrompt,
|
||||
@ -271,8 +271,7 @@ fn update_prompt<'prompt>(
|
||||
}
|
||||
|
||||
let (block, delta) = {
|
||||
let ref_engine_state = engine_state.borrow();
|
||||
let mut working_set = StateWorkingSet::new(&ref_engine_state);
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
let (output, err) = parse(&mut working_set, None, prompt_command.as_bytes(), false);
|
||||
if let Some(err) = err {
|
||||
report_error(&working_set, &err);
|
||||
@ -281,26 +280,13 @@ fn update_prompt<'prompt>(
|
||||
(output, working_set.render())
|
||||
};
|
||||
|
||||
EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta);
|
||||
let mut stack = stack.clone();
|
||||
|
||||
let state = nu_protocol::engine::EvaluationContext {
|
||||
engine_state: engine_state.clone(),
|
||||
stack: stack.clone(),
|
||||
};
|
||||
|
||||
let evaluated_prompt = match eval_block(&state, &block, Value::nothing()) {
|
||||
Ok(value) => match value.as_string() {
|
||||
Ok(prompt) => prompt,
|
||||
Err(err) => {
|
||||
let engine_state = engine_state.borrow();
|
||||
let working_set = StateWorkingSet::new(&*engine_state);
|
||||
report_error(&working_set, &err);
|
||||
return default_prompt as &dyn Prompt;
|
||||
}
|
||||
},
|
||||
let evaluated_prompt = match eval_block(&engine_state, &mut stack, &block, PipelineData::new())
|
||||
{
|
||||
Ok(pipeline_data) => pipeline_data.collect_string(),
|
||||
Err(err) => {
|
||||
let engine_state = engine_state.borrow();
|
||||
let working_set = StateWorkingSet::new(&*engine_state);
|
||||
let working_set = StateWorkingSet::new(&engine_state);
|
||||
report_error(&working_set, &err);
|
||||
return default_prompt as &dyn Prompt;
|
||||
}
|
||||
@ -312,14 +298,13 @@ fn update_prompt<'prompt>(
|
||||
}
|
||||
|
||||
fn eval_source(
|
||||
engine_state: Rc<RefCell<EngineState>>,
|
||||
stack: &Stack,
|
||||
engine_state: &mut EngineState,
|
||||
stack: &mut Stack,
|
||||
source: &str,
|
||||
fname: &str,
|
||||
) -> bool {
|
||||
let (block, delta) = {
|
||||
let engine_state = engine_state.borrow();
|
||||
let mut working_set = StateWorkingSet::new(&*engine_state);
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
let (output, err) = parse(
|
||||
&mut working_set,
|
||||
Some(fname), // format!("entry #{}", entry_num)
|
||||
@ -333,26 +318,19 @@ fn eval_source(
|
||||
(output, working_set.render())
|
||||
};
|
||||
|
||||
EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta);
|
||||
EngineState::merge_delta(engine_state, delta);
|
||||
|
||||
let state = nu_protocol::engine::EvaluationContext {
|
||||
engine_state: engine_state.clone(),
|
||||
stack: stack.clone(),
|
||||
};
|
||||
|
||||
match eval_block(&state, &block, Value::nothing()) {
|
||||
Ok(value) => {
|
||||
if let Err(err) = print_value(value, &state) {
|
||||
let engine_state = engine_state.borrow();
|
||||
let working_set = StateWorkingSet::new(&*engine_state);
|
||||
match eval_block(&engine_state, stack, &block, PipelineData::new()) {
|
||||
Ok(pipeline_data) => {
|
||||
if let Err(err) = print_value(pipeline_data.into_value(), &engine_state) {
|
||||
let working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
report_error(&working_set, &err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
let engine_state = engine_state.borrow();
|
||||
let working_set = StateWorkingSet::new(&*engine_state);
|
||||
let working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
report_error(&working_set, &err);
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user