forked from extern/nushell
Merge branch 'nushell:main' into engine-q-math
This commit is contained in:
@ -1,9 +1,10 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
Example, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SubCommand;
|
||||
|
||||
impl Command for SubCommand {
|
||||
@ -25,11 +26,12 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
into_binary(context, call, input)
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
into_binary(call, input)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -84,14 +86,13 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn into_binary(
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let head = call.head;
|
||||
// let column_paths: Vec<CellPath> = call.rest(context, 0)?;
|
||||
|
||||
input.map(head, move |v| {
|
||||
input.map(move |v| {
|
||||
action(v, head)
|
||||
// FIXME: Add back in cell_path support
|
||||
// if column_paths.is_empty() {
|
||||
|
@ -1,10 +1,11 @@
|
||||
use nu_engine::get_full_help;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
Signature, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
IntoPipelineData, PipelineData, Signature, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Into;
|
||||
|
||||
impl Command for Into {
|
||||
@ -22,14 +23,16 @@ impl Command for Into {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_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,9 +1,10 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
Example, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SubCommand;
|
||||
|
||||
impl Command for SubCommand {
|
||||
@ -25,11 +26,12 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
into_filesize(context, call, input)
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
into_filesize(call, input)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -112,14 +114,13 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn into_filesize(
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let head = call.head;
|
||||
// let call_paths: Vec<ColumnPath> = args.rest(0)?;
|
||||
|
||||
input.map(head, move |v| {
|
||||
input.map(move |v| {
|
||||
action(v, head)
|
||||
|
||||
// FIXME: Add back cell_path support
|
||||
|
@ -1,9 +1,10 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
Example, IntoValueStream, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SubCommand;
|
||||
|
||||
impl Command for SubCommand {
|
||||
@ -25,11 +26,12 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
into_int(context, call, input)
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
into_int(call, input)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -78,10 +80,8 @@ impl Command for SubCommand {
|
||||
Example {
|
||||
description: "Convert bool to integer",
|
||||
example: "[$false, $true] | into int",
|
||||
result: Some(Value::Stream {
|
||||
stream: vec![Value::test_int(0), Value::test_int(1)]
|
||||
.into_iter()
|
||||
.into_value_stream(),
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_int(0), Value::test_int(1)],
|
||||
span: Span::unknown(),
|
||||
}),
|
||||
},
|
||||
@ -90,14 +90,13 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn into_int(
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let head = call.head;
|
||||
// let column_paths: Vec<CellPath> = call.rest(context, 0)?;
|
||||
|
||||
input.map(head, move |v| {
|
||||
input.map(move |v| {
|
||||
action(v, head)
|
||||
// FIXME: Add back cell_path support
|
||||
// if column_paths.is_empty() {
|
||||
|
@ -1,7 +1,8 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Alias;
|
||||
|
||||
impl Command for Alias {
|
||||
@ -25,10 +26,11 @@ impl Command for Alias {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
_call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Def;
|
||||
|
||||
impl Command for Def {
|
||||
@ -26,10 +27,11 @@ impl Command for Def {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
_call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use nu_engine::{eval_block, CallExt};
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Do;
|
||||
|
||||
impl Command for Do {
|
||||
@ -27,19 +28,19 @@ impl Command for Do {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
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 engine_state = context.engine_state.borrow();
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
||||
let state = context.enter_scope();
|
||||
let mut stack = stack.collect_captures(&block.captures);
|
||||
|
||||
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,7 +1,8 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ExportDef;
|
||||
|
||||
impl Command for ExportDef {
|
||||
@ -26,10 +27,11 @@ impl Command for ExportDef {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
_call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use nu_engine::{eval_block, eval_expression};
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Example, Signature, Span, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct For;
|
||||
|
||||
impl Command for For {
|
||||
@ -36,10 +37,11 @@ impl Command for For {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let var_id = call.positional[0]
|
||||
.as_var()
|
||||
.expect("internal error: missing variable");
|
||||
@ -47,27 +49,48 @@ 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]
|
||||
let block_id = call.positional[2]
|
||||
.as_block()
|
||||
.expect("internal error: expected block");
|
||||
|
||||
let context = context.clone();
|
||||
let engine_state = engine_state.clone();
|
||||
let block = engine_state.get_block(block_id);
|
||||
let mut stack = stack.collect_captures(&block.captures);
|
||||
|
||||
values.map(call.head, move |x| {
|
||||
let engine_state = context.engine_state.borrow();
|
||||
let block = engine_state.get_block(block);
|
||||
match values {
|
||||
Value::List { vals, .. } => Ok(vals
|
||||
.into_iter()
|
||||
.map(move |x| {
|
||||
let mut stack = stack.clone();
|
||||
stack.add_var(var_id, x);
|
||||
|
||||
let state = context.enter_scope();
|
||||
let block = engine_state.get_block(block_id);
|
||||
match eval_block(&engine_state, &mut stack, block, PipelineData::new()) {
|
||||
Ok(pipeline_data) => pipeline_data.into_value(),
|
||||
Err(error) => Value::Error { error },
|
||||
}
|
||||
})
|
||||
.into_pipeline_data()),
|
||||
Value::Range { val, .. } => Ok(val
|
||||
.into_range_iter()?
|
||||
.map(move |x| {
|
||||
stack.add_var(var_id, x);
|
||||
|
||||
state.add_var(var_id, x);
|
||||
let block = engine_state.get_block(block_id);
|
||||
match eval_block(&engine_state, &mut stack, block, PipelineData::new()) {
|
||||
Ok(pipeline_data) => pipeline_data.into_value(),
|
||||
Err(error) => Value::Error { error },
|
||||
}
|
||||
})
|
||||
.into_pipeline_data()),
|
||||
x => {
|
||||
stack.add_var(var_id, x);
|
||||
|
||||
match eval_block(&state, block, Value::nothing()) {
|
||||
Ok(value) => value,
|
||||
Err(error) => Value::Error { error },
|
||||
eval_block(&engine_state, &mut stack, block, PipelineData::new())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -1,11 +1,13 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
span, Example, ShellError, Signature, Spanned, SyntaxShape, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
span, Example, IntoPipelineData, PipelineData, ShellError, Signature, Spanned, SyntaxShape,
|
||||
Value,
|
||||
};
|
||||
|
||||
use nu_engine::{get_full_help, CallExt};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Help;
|
||||
|
||||
impl Command for Help {
|
||||
@ -34,11 +36,12 @@ impl Command for Help {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<Value, ShellError> {
|
||||
help(context, call)
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
help(engine_state, stack, call)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -72,12 +75,16 @@ impl Command for Help {
|
||||
}
|
||||
}
|
||||
|
||||
fn help(context: &EvaluationContext, call: &Call) -> Result<Value, 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;
|
||||
@ -114,10 +121,7 @@ fn help(context: &EvaluationContext, call: &Call) -> Result<Value, ShellError> {
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Value::List {
|
||||
vals: found_cmds_vec,
|
||||
span: head,
|
||||
});
|
||||
return Ok(found_cmds_vec.into_iter().into_pipeline_data());
|
||||
}
|
||||
|
||||
if !rest.is_empty() {
|
||||
@ -151,10 +155,7 @@ fn help(context: &EvaluationContext, call: &Call) -> Result<Value, ShellError> {
|
||||
});
|
||||
}
|
||||
|
||||
Ok(Value::List {
|
||||
vals: found_cmds_vec,
|
||||
span: head,
|
||||
})
|
||||
Ok(found_cmds_vec.into_iter().into_pipeline_data())
|
||||
} else {
|
||||
let mut name = String::new();
|
||||
let mut output = String::new();
|
||||
@ -168,7 +169,7 @@ fn help(context: &EvaluationContext, call: &Call) -> Result<Value, ShellError> {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -177,7 +178,8 @@ fn help(context: &EvaluationContext, call: &Call) -> Result<Value, ShellError> {
|
||||
Ok(Value::String {
|
||||
val: output,
|
||||
span: call.head,
|
||||
})
|
||||
}
|
||||
.into_pipeline_data())
|
||||
} else {
|
||||
Err(ShellError::CommandNotFound(span(&[
|
||||
rest[0].span,
|
||||
@ -355,7 +357,8 @@ You can also learn more at https://www.nushell.sh/book/"#;
|
||||
Ok(Value::String {
|
||||
val: msg.into(),
|
||||
span: head,
|
||||
})
|
||||
}
|
||||
.into_pipeline_data())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Hide;
|
||||
|
||||
impl Command for Hide {
|
||||
@ -19,10 +20,11 @@ impl Command for Hide {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
_call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use nu_engine::{eval_block, eval_expression};
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{ShellError, Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct If;
|
||||
|
||||
impl Command for If {
|
||||
@ -27,38 +28,40 @@ impl Command for If {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let cond = &call.positional[0];
|
||||
let then_block = call.positional[1]
|
||||
.as_block()
|
||||
.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 } => {
|
||||
let engine_state = context.engine_state.borrow();
|
||||
Value::Bool { val, .. } => {
|
||||
if val {
|
||||
let block = engine_state.get_block(then_block);
|
||||
let state = context.enter_scope();
|
||||
eval_block(&state, block, input)
|
||||
let mut stack = stack.collect_captures(&block.captures);
|
||||
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 = engine_state.get_block(block_id);
|
||||
let state = context.enter_scope();
|
||||
eval_block(&state, block, input)
|
||||
let mut stack = stack.collect_captures(&block.captures);
|
||||
eval_block(engine_state, &mut stack, block, input)
|
||||
} else {
|
||||
eval_expression(context, else_expr)
|
||||
eval_expression(engine_state, stack, else_expr)
|
||||
.map(|x| x.into_pipeline_data())
|
||||
}
|
||||
} else {
|
||||
eval_expression(context, else_case)
|
||||
eval_expression(engine_state, stack, else_case)
|
||||
.map(|x| x.into_pipeline_data())
|
||||
}
|
||||
} else {
|
||||
Ok(Value::Nothing { span })
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
_ => Err(ShellError::CantConvert("bool".into(), result.span()?)),
|
||||
|
@ -1,8 +1,9 @@
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Let;
|
||||
|
||||
impl Command for Let {
|
||||
@ -26,10 +27,11 @@ impl Command for Let {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let var_id = call.positional[0]
|
||||
.as_var()
|
||||
.expect("internal error: missing variable");
|
||||
@ -38,13 +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);
|
||||
Ok(Value::Nothing {
|
||||
span: call.positional[0].span,
|
||||
})
|
||||
stack.add_var(var_id, rhs);
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Module;
|
||||
|
||||
impl Command for Module {
|
||||
@ -25,10 +26,11 @@ impl Command for Module {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
_call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
use nu_engine::{eval_block, CallExt};
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{ShellError, Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, ShellError, Signature, SyntaxShape};
|
||||
|
||||
/// Source a file for environment variables.
|
||||
#[derive(Clone)]
|
||||
pub struct Source;
|
||||
|
||||
impl Command for Source {
|
||||
@ -25,19 +26,16 @@ impl Command for Source {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<Value, ShellError> {
|
||||
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
|
||||
.borrow()
|
||||
.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,7 +1,8 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Use;
|
||||
|
||||
impl Command for Use {
|
||||
@ -19,10 +20,11 @@ impl Command for Use {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
_call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -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 ) => {
|
||||
@ -92,7 +89,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
|
||||
|
20
crates/nu-command/src/env/let_env.rs
vendored
20
crates/nu-command/src/env/let_env.rs
vendored
@ -1,8 +1,9 @@
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LetEnv;
|
||||
|
||||
impl Command for LetEnv {
|
||||
@ -26,10 +27,11 @@ impl Command for LetEnv {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let env_var = call.positional[0]
|
||||
.as_string()
|
||||
.expect("internal error: missing variable");
|
||||
@ -38,14 +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);
|
||||
Ok(Value::Nothing {
|
||||
span: call.positional[0].span,
|
||||
})
|
||||
stack.add_env_var(env_var, rhs);
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,19 @@
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use nu_engine::eval_block;
|
||||
use nu_parser::parse;
|
||||
use nu_protocol::{
|
||||
engine::{Command, EngineState, EvaluationContext, StateWorkingSet},
|
||||
Value,
|
||||
engine::{Command, EngineState, Stack, StateWorkingSet},
|
||||
PipelineData,
|
||||
};
|
||||
|
||||
use super::{From, Into, Split};
|
||||
|
||||
pub fn test_examples(cmd: impl Command + 'static) {
|
||||
let examples = cmd.examples();
|
||||
let engine_state = Rc::new(RefCell::new(EngineState::new()));
|
||||
let mut engine_state = Box::new(EngineState::new());
|
||||
|
||||
let delta = {
|
||||
// Base functions that are needed for testing
|
||||
// Try to keep this working set small to keep tests running as fast as possible
|
||||
let engine_state = engine_state.borrow();
|
||||
let mut working_set = StateWorkingSet::new(&*engine_state);
|
||||
working_set.add_decl(Box::new(From));
|
||||
working_set.add_decl(Box::new(Into));
|
||||
@ -28,7 +25,7 @@ pub fn test_examples(cmd: impl Command + 'static) {
|
||||
working_set.render()
|
||||
};
|
||||
|
||||
EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta);
|
||||
EngineState::merge_delta(&mut *engine_state, delta);
|
||||
|
||||
for example in examples {
|
||||
// Skip tests that don't have results to compare to
|
||||
@ -38,7 +35,6 @@ pub fn test_examples(cmd: impl Command + 'static) {
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
let (block, delta) = {
|
||||
let engine_state = engine_state.borrow();
|
||||
let mut working_set = StateWorkingSet::new(&*engine_state);
|
||||
let (output, err) = parse(&mut working_set, None, example.example.as_bytes(), false);
|
||||
|
||||
@ -49,16 +45,14 @@ pub fn test_examples(cmd: impl Command + 'static) {
|
||||
(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 = Stack::new();
|
||||
|
||||
match eval_block(&state, &block, Value::nothing()) {
|
||||
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();
|
||||
println!("input: {}", example.example);
|
||||
println!("result: {:?}", result);
|
||||
println!("done: {:?}", start.elapsed());
|
||||
|
@ -1,7 +1,8 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Git;
|
||||
|
||||
impl Command for Git {
|
||||
@ -19,10 +20,11 @@ impl Command for Git {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
use std::process::Command as ProcessCommand;
|
||||
use std::process::Stdio;
|
||||
|
||||
@ -37,17 +39,18 @@ impl Command for Git {
|
||||
Ok(Value::String {
|
||||
val: String::from_utf8_lossy(&result).to_string(),
|
||||
span: call.head,
|
||||
})
|
||||
}
|
||||
.into_pipeline_data())
|
||||
}
|
||||
Err(_err) => {
|
||||
// FIXME: Move this to an external signature and add better error handling
|
||||
Ok(Value::nothing())
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_err) => {
|
||||
// FIXME: Move this to an external signature and add better error handling
|
||||
Ok(Value::nothing())
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GitCheckout;
|
||||
|
||||
impl Command for GitCheckout {
|
||||
@ -24,16 +25,17 @@ impl Command for GitCheckout {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
use std::process::Command as ProcessCommand;
|
||||
use std::process::Stdio;
|
||||
|
||||
let block = &call.positional[0];
|
||||
|
||||
let out = eval_expression(context, block)?;
|
||||
let out = eval_expression(engine_state, stack, block)?;
|
||||
|
||||
let out = out.as_string()?;
|
||||
|
||||
@ -52,17 +54,18 @@ impl Command for GitCheckout {
|
||||
Ok(Value::String {
|
||||
val: String::from_utf8_lossy(&result).to_string(),
|
||||
span: call.head,
|
||||
})
|
||||
}
|
||||
.into_pipeline_data())
|
||||
}
|
||||
Err(_err) => {
|
||||
// FIXME: Move this to an external signature and add better error handling
|
||||
Ok(Value::nothing())
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_err) => {
|
||||
// FIXME: Move this to an external signature and add better error handling
|
||||
Ok(Value::nothing())
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,14 @@ use std::process::Command as ProcessCommand;
|
||||
use std::process::Stdio;
|
||||
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::engine::Command;
|
||||
use nu_protocol::engine::EngineState;
|
||||
use nu_protocol::engine::Stack;
|
||||
use nu_protocol::IntoPipelineData;
|
||||
use nu_protocol::PipelineData;
|
||||
use nu_protocol::{Signature, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ListGitBranches;
|
||||
|
||||
//NOTE: this is not a real implementation :D. It's just a simple one to test with until we port the real one.
|
||||
@ -25,10 +30,11 @@ impl Command for ListGitBranches {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let list_branches = ProcessCommand::new("git")
|
||||
.arg("branch")
|
||||
.stdout(Stdio::piped())
|
||||
@ -40,6 +46,7 @@ impl Command for ListGitBranches {
|
||||
|
||||
let s = String::from_utf8_lossy(&val).to_string();
|
||||
|
||||
#[allow(clippy::needless_collect)]
|
||||
let lines: Vec<_> = s
|
||||
.lines()
|
||||
.filter_map(|x| {
|
||||
@ -55,15 +62,12 @@ impl Command for ListGitBranches {
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(Value::List {
|
||||
vals: lines,
|
||||
span: call.head,
|
||||
})
|
||||
Ok(lines.into_iter().into_pipeline_data())
|
||||
} else {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
} else {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Cd;
|
||||
|
||||
impl Command for Cd {
|
||||
@ -20,11 +21,12 @@ impl Command for Cd {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
let path: Option<String> = call.opt(context, 0)?;
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let path: Option<String> = call.opt(engine_state, stack, 0)?;
|
||||
|
||||
let path = match path {
|
||||
Some(path) => {
|
||||
@ -40,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);
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
stack.add_env_var("PWD".into(), path);
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
use std::env::current_dir;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::interactive_helper::get_confirmation;
|
||||
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::{ShellError, Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, ShellError, Signature, SyntaxShape};
|
||||
|
||||
use crate::filesystem::util::FileStructure;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Cp;
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
@ -37,12 +38,13 @@ impl Command for Cp {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<Value, ShellError> {
|
||||
let source: String = call.req(context, 0)?;
|
||||
let destination: String = call.req(context, 1)?;
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
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");
|
||||
|
||||
@ -88,7 +90,7 @@ impl Command for Cp {
|
||||
destination.file_name().unwrap().to_str().unwrap()
|
||||
);
|
||||
|
||||
let input = get_confirmation(prompt)?;
|
||||
let input = get_interactive_confirmation(prompt)?;
|
||||
|
||||
if !input {
|
||||
remove.push(index);
|
||||
@ -202,6 +204,6 @@ impl Command for Cp {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
use dialoguer::Input;
|
||||
use std::error::Error;
|
||||
|
||||
pub fn get_confirmation(prompt: String) -> Result<bool, Box<dyn Error>> {
|
||||
let input = Input::new()
|
||||
.with_prompt(prompt)
|
||||
.validate_with(|c_input: &String| -> Result<(), String> {
|
||||
if c_input.len() == 1
|
||||
&& (c_input == "y" || c_input == "Y" || c_input == "n" || c_input == "N")
|
||||
{
|
||||
Ok(())
|
||||
} else if c_input.len() > 1 {
|
||||
Err("Enter only one letter (Y/N)".to_string())
|
||||
} else {
|
||||
Err("Input not valid".to_string())
|
||||
}
|
||||
})
|
||||
.default("Y/N".into())
|
||||
.interact_text()?;
|
||||
|
||||
if input == "y" || input == "Y" {
|
||||
Ok(true)
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{IntoValueStream, Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Ls;
|
||||
|
||||
//NOTE: this is not a real implementation :D. It's just a simple one to test with until we port the real one.
|
||||
@ -26,12 +27,13 @@ impl Command for Ls {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_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);
|
||||
@ -50,69 +52,66 @@ impl Command for Ls {
|
||||
let call_span = call.head;
|
||||
let glob = glob::glob(&pattern).unwrap();
|
||||
|
||||
Ok(Value::Stream {
|
||||
stream: glob
|
||||
.into_iter()
|
||||
.map(move |x| match x {
|
||||
Ok(path) => match std::fs::symlink_metadata(&path) {
|
||||
Ok(metadata) => {
|
||||
let is_file = metadata.is_file();
|
||||
let is_dir = metadata.is_dir();
|
||||
let filesize = metadata.len();
|
||||
Ok(glob
|
||||
.into_iter()
|
||||
.map(move |x| match x {
|
||||
Ok(path) => match std::fs::symlink_metadata(&path) {
|
||||
Ok(metadata) => {
|
||||
let is_file = metadata.is_file();
|
||||
let is_dir = metadata.is_dir();
|
||||
let filesize = metadata.len();
|
||||
|
||||
let mut cols = vec!["name".into(), "type".into(), "size".into()];
|
||||
let mut cols = vec!["name".into(), "type".into(), "size".into()];
|
||||
|
||||
let mut vals = vec![
|
||||
Value::String {
|
||||
val: path.to_string_lossy().to_string(),
|
||||
span: call_span,
|
||||
},
|
||||
if is_file {
|
||||
Value::string("File", call_span)
|
||||
} else if is_dir {
|
||||
Value::string("Dir", call_span)
|
||||
} else {
|
||||
Value::Nothing { span: call_span }
|
||||
},
|
||||
Value::Filesize {
|
||||
val: filesize as i64,
|
||||
span: call_span,
|
||||
},
|
||||
];
|
||||
|
||||
if let Ok(date) = metadata.modified() {
|
||||
let utc: DateTime<Utc> = date.into();
|
||||
|
||||
cols.push("modified".into());
|
||||
vals.push(Value::Date {
|
||||
val: utc.into(),
|
||||
span: call_span,
|
||||
});
|
||||
}
|
||||
|
||||
Value::Record {
|
||||
cols,
|
||||
vals,
|
||||
let mut vals = vec![
|
||||
Value::String {
|
||||
val: path.to_string_lossy().to_string(),
|
||||
span: call_span,
|
||||
}
|
||||
},
|
||||
if is_file {
|
||||
Value::string("File", call_span)
|
||||
} else if is_dir {
|
||||
Value::string("Dir", call_span)
|
||||
} else {
|
||||
Value::Nothing { span: call_span }
|
||||
},
|
||||
Value::Filesize {
|
||||
val: filesize as i64,
|
||||
span: call_span,
|
||||
},
|
||||
];
|
||||
|
||||
if let Ok(date) = metadata.modified() {
|
||||
let utc: DateTime<Utc> = date.into();
|
||||
|
||||
cols.push("modified".into());
|
||||
vals.push(Value::Date {
|
||||
val: utc.into(),
|
||||
span: call_span,
|
||||
});
|
||||
}
|
||||
Err(_) => Value::Record {
|
||||
cols: vec!["name".into(), "type".into(), "size".into()],
|
||||
vals: vec![
|
||||
Value::String {
|
||||
val: path.to_string_lossy().to_string(),
|
||||
span: call_span,
|
||||
},
|
||||
Value::Nothing { span: call_span },
|
||||
Value::Nothing { span: call_span },
|
||||
],
|
||||
|
||||
Value::Record {
|
||||
cols,
|
||||
vals,
|
||||
span: call_span,
|
||||
},
|
||||
}
|
||||
}
|
||||
Err(_) => Value::Record {
|
||||
cols: vec!["name".into(), "type".into(), "size".into()],
|
||||
vals: vec![
|
||||
Value::String {
|
||||
val: path.to_string_lossy().to_string(),
|
||||
span: call_span,
|
||||
},
|
||||
Value::Nothing { span: call_span },
|
||||
Value::Nothing { span: call_span },
|
||||
],
|
||||
span: call_span,
|
||||
},
|
||||
_ => Value::Nothing { span: call_span },
|
||||
})
|
||||
.into_value_stream(),
|
||||
span: call_span,
|
||||
})
|
||||
},
|
||||
_ => Value::Nothing { span: call_span },
|
||||
})
|
||||
.into_pipeline_data())
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,10 @@ use std::env::current_dir;
|
||||
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{ShellError, Signature, SyntaxShape, Value, ValueStream};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Mkdir;
|
||||
|
||||
impl Command for Mkdir {
|
||||
@ -29,13 +30,14 @@ impl Command for Mkdir {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<Value, ShellError> {
|
||||
_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();
|
||||
@ -67,8 +69,6 @@ impl Command for Mkdir {
|
||||
}
|
||||
}
|
||||
|
||||
let stream = ValueStream::from_stream(stream.into_iter());
|
||||
let span = call.head;
|
||||
Ok(Value::Stream { stream, span })
|
||||
Ok(stream.into_iter().into_pipeline_data())
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
mod cd;
|
||||
mod cp;
|
||||
mod interactive_helper;
|
||||
mod ls;
|
||||
mod mkdir;
|
||||
mod mv;
|
||||
|
@ -1,12 +1,13 @@
|
||||
use std::env::current_dir;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use super::interactive_helper::get_confirmation;
|
||||
use super::util::get_interactive_confirmation;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{ShellError, Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, ShellError, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Mv;
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
@ -37,13 +38,14 @@ impl Command for Mv {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_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");
|
||||
|
||||
@ -74,7 +76,7 @@ impl Command for Mv {
|
||||
destination.file_name().unwrap().to_str().unwrap()
|
||||
);
|
||||
|
||||
let input = get_confirmation(prompt)?;
|
||||
let input = get_interactive_confirmation(prompt)?;
|
||||
|
||||
if !input {
|
||||
remove.push(index);
|
||||
@ -128,7 +130,7 @@ impl Command for Mv {
|
||||
move_file(call, &entry, &destination)?
|
||||
}
|
||||
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,13 +3,14 @@ use std::env::current_dir;
|
||||
use std::os::unix::prelude::FileTypeExt;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::interactive_helper::get_confirmation;
|
||||
use super::util::get_interactive_confirmation;
|
||||
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{ShellError, Signature, SyntaxShape, Value, ValueStream};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Rm;
|
||||
|
||||
// Where self.0 is the unexpanded target's positional index (i.e. call.positional[self.0].span)
|
||||
@ -56,15 +57,20 @@ impl Command for Rm {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<Value, ShellError> {
|
||||
rm(context, call)
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
rm(engine_state, stack, call)
|
||||
}
|
||||
}
|
||||
|
||||
fn rm(context: &EvaluationContext, call: &Call) -> Result<Value, 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");
|
||||
@ -95,7 +101,7 @@ fn rm(context: &EvaluationContext, call: &Call) -> Result<Value, ShellError> {
|
||||
|
||||
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();
|
||||
@ -134,7 +140,7 @@ fn rm(context: &EvaluationContext, call: &Call) -> Result<Value, ShellError> {
|
||||
file.1.file_name().unwrap().to_str().unwrap()
|
||||
);
|
||||
|
||||
let input = get_confirmation(prompt)?;
|
||||
let input = get_interactive_confirmation(prompt)?;
|
||||
|
||||
if !input {
|
||||
remove.push(index);
|
||||
@ -164,11 +170,7 @@ fn rm(context: &EvaluationContext, call: &Call) -> Result<Value, ShellError> {
|
||||
// let temp = rm_helper(call, args).flatten();
|
||||
// let temp = input.flatten(call.head, move |_| rm_helper(call, args));
|
||||
|
||||
Ok(Value::Stream {
|
||||
stream: ValueStream::from_stream(response.into_iter()),
|
||||
span: call.head,
|
||||
})
|
||||
|
||||
Ok(response.into_iter().into_pipeline_data())
|
||||
// Ok(Value::Nothing { span })
|
||||
}
|
||||
|
||||
|
@ -2,9 +2,10 @@ use std::fs::OpenOptions;
|
||||
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{ShellError, Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, ShellError, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Touch;
|
||||
|
||||
impl Command for Touch {
|
||||
@ -28,12 +29,13 @@ impl Command for Touch {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<Value, ShellError> {
|
||||
let target: String = call.req(context, 0)?;
|
||||
let rest: Vec<String> = call.rest(context, 1)?;
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
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) {
|
||||
@ -47,6 +49,6 @@ impl Command for Touch {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ use std::path::{Path, PathBuf};
|
||||
use nu_path::canonicalize_with;
|
||||
use nu_protocol::ShellError;
|
||||
|
||||
use dialoguer::Input;
|
||||
use std::error::Error;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FileStructure {
|
||||
pub resources: Vec<Resource>,
|
||||
@ -79,3 +82,27 @@ pub struct Resource {
|
||||
}
|
||||
|
||||
impl Resource {}
|
||||
|
||||
pub fn get_interactive_confirmation(prompt: String) -> Result<bool, Box<dyn Error>> {
|
||||
let input = Input::new()
|
||||
.with_prompt(prompt)
|
||||
.validate_with(|c_input: &String| -> Result<(), String> {
|
||||
if c_input.len() == 1
|
||||
&& (c_input == "y" || c_input == "Y" || c_input == "n" || c_input == "N")
|
||||
{
|
||||
Ok(())
|
||||
} else if c_input.len() > 1 {
|
||||
Err("Enter only one letter (Y/N)".to_string())
|
||||
} else {
|
||||
Err("Input not valid".to_string())
|
||||
}
|
||||
})
|
||||
.default("Y/N".into())
|
||||
.interact_text()?;
|
||||
|
||||
if input == "y" || input == "Y" {
|
||||
Ok(true)
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use nu_engine::eval_block;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Example, IntoValueStream, Signature, Span, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Each;
|
||||
|
||||
impl Command for Each {
|
||||
@ -43,8 +44,8 @@ impl Command for Each {
|
||||
vec![Example {
|
||||
example: "[1 2 3] | each { 2 * $it }",
|
||||
description: "Multiplies elements in list",
|
||||
result: Some(Value::Stream {
|
||||
stream: stream_test_1.into_iter().into_value_stream(),
|
||||
result: Some(Value::List {
|
||||
vals: stream_test_1,
|
||||
span: Span::unknown(),
|
||||
}),
|
||||
}]
|
||||
@ -52,151 +53,147 @@ impl Command for Each {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let block_id = call.positional[0]
|
||||
.as_block()
|
||||
.expect("internal error: expected block");
|
||||
|
||||
let numbered = call.has_flag("numbered");
|
||||
let context = context.clone();
|
||||
let engine_state = engine_state.clone();
|
||||
let block = engine_state.get_block(block_id);
|
||||
let mut stack = stack.collect_captures(&block.captures);
|
||||
let span = call.head;
|
||||
|
||||
match input {
|
||||
Value::Range { val, .. } => Ok(Value::Stream {
|
||||
stream: val
|
||||
.into_range_iter()?
|
||||
.enumerate()
|
||||
.map(move |(idx, x)| {
|
||||
let engine_state = context.engine_state.borrow();
|
||||
let block = engine_state.get_block(block_id);
|
||||
PipelineData::Value(Value::Range { val, .. }) => Ok(val
|
||||
.into_range_iter()?
|
||||
.enumerate()
|
||||
.map(move |(idx, x)| {
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
||||
let state = context.enter_scope();
|
||||
let mut stack = stack.clone();
|
||||
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
if numbered {
|
||||
state.add_var(
|
||||
*var_id,
|
||||
Value::Record {
|
||||
cols: vec!["index".into(), "item".into()],
|
||||
vals: vec![
|
||||
Value::Int {
|
||||
val: idx as i64,
|
||||
span,
|
||||
},
|
||||
x,
|
||||
],
|
||||
span,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
state.add_var(*var_id, x);
|
||||
}
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
if numbered {
|
||||
stack.add_var(
|
||||
*var_id,
|
||||
Value::Record {
|
||||
cols: vec!["index".into(), "item".into()],
|
||||
vals: vec![
|
||||
Value::Int {
|
||||
val: idx as i64,
|
||||
span,
|
||||
},
|
||||
x,
|
||||
],
|
||||
span,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
stack.add_var(*var_id, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match eval_block(&state, block, Value::nothing()) {
|
||||
Ok(v) => v,
|
||||
Err(error) => Value::Error { error },
|
||||
}
|
||||
})
|
||||
.into_value_stream(),
|
||||
span: call.head,
|
||||
}),
|
||||
Value::List { vals: val, .. } => Ok(Value::Stream {
|
||||
stream: val
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(move |(idx, x)| {
|
||||
let engine_state = context.engine_state.borrow();
|
||||
let block = engine_state.get_block(block_id);
|
||||
match eval_block(&engine_state, &mut stack, block, PipelineData::new()) {
|
||||
Ok(v) => v,
|
||||
Err(error) => Value::Error { error }.into_pipeline_data(),
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
.into_pipeline_data()),
|
||||
PipelineData::Value(Value::List { vals: val, .. }) => Ok(val
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(move |(idx, x)| {
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
||||
let state = context.enter_scope();
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
if numbered {
|
||||
state.add_var(
|
||||
*var_id,
|
||||
Value::Record {
|
||||
cols: vec!["index".into(), "item".into()],
|
||||
vals: vec![
|
||||
Value::Int {
|
||||
val: idx as i64,
|
||||
span,
|
||||
},
|
||||
x,
|
||||
],
|
||||
span,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
state.add_var(*var_id, x);
|
||||
}
|
||||
let mut stack = stack.clone();
|
||||
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
if numbered {
|
||||
stack.add_var(
|
||||
*var_id,
|
||||
Value::Record {
|
||||
cols: vec!["index".into(), "item".into()],
|
||||
vals: vec![
|
||||
Value::Int {
|
||||
val: idx as i64,
|
||||
span,
|
||||
},
|
||||
x,
|
||||
],
|
||||
span,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
stack.add_var(*var_id, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match eval_block(&state, block, Value::nothing()) {
|
||||
Ok(v) => v,
|
||||
Err(error) => Value::Error { error },
|
||||
}
|
||||
})
|
||||
.into_value_stream(),
|
||||
span: call.head,
|
||||
}),
|
||||
Value::Stream { stream, .. } => Ok(Value::Stream {
|
||||
stream: stream
|
||||
.enumerate()
|
||||
.map(move |(idx, x)| {
|
||||
let engine_state = context.engine_state.borrow();
|
||||
let block = engine_state.get_block(block_id);
|
||||
match eval_block(&engine_state, &mut stack, block, PipelineData::new()) {
|
||||
Ok(v) => v,
|
||||
Err(error) => Value::Error { error }.into_pipeline_data(),
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
.into_pipeline_data()),
|
||||
PipelineData::Stream(stream) => Ok(stream
|
||||
.enumerate()
|
||||
.map(move |(idx, x)| {
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
||||
let state = context.enter_scope();
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
if numbered {
|
||||
state.add_var(
|
||||
*var_id,
|
||||
Value::Record {
|
||||
cols: vec!["index".into(), "item".into()],
|
||||
vals: vec![
|
||||
Value::Int {
|
||||
val: idx as i64,
|
||||
span,
|
||||
},
|
||||
x,
|
||||
],
|
||||
span,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
state.add_var(*var_id, x);
|
||||
}
|
||||
let mut stack = stack.clone();
|
||||
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
if numbered {
|
||||
stack.add_var(
|
||||
*var_id,
|
||||
Value::Record {
|
||||
cols: vec!["index".into(), "item".into()],
|
||||
vals: vec![
|
||||
Value::Int {
|
||||
val: idx as i64,
|
||||
span,
|
||||
},
|
||||
x,
|
||||
],
|
||||
span,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
stack.add_var(*var_id, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match eval_block(&state, block, Value::nothing()) {
|
||||
Ok(v) => v,
|
||||
Err(error) => Value::Error { error },
|
||||
}
|
||||
})
|
||||
.into_value_stream(),
|
||||
span: call.head,
|
||||
}),
|
||||
Value::Record { cols, vals, .. } => {
|
||||
match eval_block(&engine_state, &mut stack, block, PipelineData::new()) {
|
||||
Ok(v) => v,
|
||||
Err(error) => Value::Error { error }.into_pipeline_data(),
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
.into_pipeline_data()),
|
||||
PipelineData::Value(Value::Record { cols, vals, .. }) => {
|
||||
let mut output_cols = vec![];
|
||||
let mut output_vals = vec![];
|
||||
|
||||
for (col, val) in cols.into_iter().zip(vals.into_iter()) {
|
||||
let engine_state = context.engine_state.borrow();
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
||||
let state = context.enter_scope();
|
||||
let mut stack = stack.clone();
|
||||
|
||||
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()],
|
||||
@ -213,17 +210,17 @@ impl Command for Each {
|
||||
}
|
||||
}
|
||||
|
||||
match eval_block(&state, block, Value::nothing())? {
|
||||
Value::Record {
|
||||
match eval_block(&engine_state, &mut stack, block, PipelineData::new())? {
|
||||
PipelineData::Value(Value::Record {
|
||||
mut cols, mut vals, ..
|
||||
} => {
|
||||
}) => {
|
||||
// TODO check that the lengths match when traversing record
|
||||
output_cols.append(&mut cols);
|
||||
output_vals.append(&mut vals);
|
||||
}
|
||||
x => {
|
||||
output_cols.push(col);
|
||||
output_vals.push(x);
|
||||
output_vals.push(x.into_value());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -232,20 +229,19 @@ impl Command for Each {
|
||||
cols: output_cols,
|
||||
vals: output_vals,
|
||||
span: call.head,
|
||||
})
|
||||
}
|
||||
.into_pipeline_data())
|
||||
}
|
||||
x => {
|
||||
let engine_state = context.engine_state.borrow();
|
||||
PipelineData::Value(x) => {
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
||||
let state = context.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, Value::nothing())
|
||||
eval_block(&engine_state, &mut stack, block, PipelineData::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::{Call, CellPath};
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Get;
|
||||
|
||||
impl Command for Get {
|
||||
@ -24,12 +25,15 @@ impl Command for Get {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
let cell_path: CellPath = call.req(context, 0)?;
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let cell_path: CellPath = call.req(engine_state, stack, 0)?;
|
||||
|
||||
input.follow_cell_path(&cell_path.members)
|
||||
input
|
||||
.follow_cell_path(&cell_path.members)
|
||||
.map(|x| x.into_pipeline_data())
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Length;
|
||||
|
||||
impl Command for Length {
|
||||
@ -19,35 +20,22 @@ impl Command for Length {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
match input {
|
||||
Value::List { vals: val, .. } => {
|
||||
let length = val.len();
|
||||
|
||||
Ok(Value::Int {
|
||||
val: length as i64,
|
||||
span: call.head,
|
||||
})
|
||||
}
|
||||
Value::Stream { stream, .. } => {
|
||||
let length = stream.count();
|
||||
|
||||
Ok(Value::Int {
|
||||
val: length as i64,
|
||||
span: call.head,
|
||||
})
|
||||
}
|
||||
Value::Nothing { .. } => Ok(Value::Int {
|
||||
PipelineData::Value(Value::Nothing { .. }) => Ok(Value::Int {
|
||||
val: 0,
|
||||
span: call.head,
|
||||
}),
|
||||
}
|
||||
.into_pipeline_data()),
|
||||
_ => Ok(Value::Int {
|
||||
val: 1,
|
||||
val: input.into_iter().count() as i64,
|
||||
span: call.head,
|
||||
}),
|
||||
}
|
||||
.into_pipeline_data()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{ShellError, Signature, Value, ValueStream};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Lines;
|
||||
|
||||
const SPLIT_CHAR: char = '\n';
|
||||
@ -24,17 +22,17 @@ impl Command for Lines {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
let span = call.head;
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
match input {
|
||||
#[allow(clippy::needless_collect)]
|
||||
// Collect is needed because the string may not live long enough for
|
||||
// the Rc structure to continue using it. If split could take ownership
|
||||
// of the split values, then this wouldn't be needed
|
||||
Value::String { val, span } => {
|
||||
PipelineData::Value(Value::String { val, span }) => {
|
||||
let lines = val
|
||||
.split(SPLIT_CHAR)
|
||||
.map(|s| s.to_string())
|
||||
@ -48,12 +46,9 @@ impl Command for Lines {
|
||||
}
|
||||
});
|
||||
|
||||
Ok(Value::Stream {
|
||||
stream: ValueStream(Rc::new(RefCell::new(iter))),
|
||||
span,
|
||||
})
|
||||
Ok(iter.into_pipeline_data())
|
||||
}
|
||||
Value::Stream { stream, span: _ } => {
|
||||
PipelineData::Stream(stream) => {
|
||||
let iter = stream
|
||||
.into_iter()
|
||||
.filter_map(|value| {
|
||||
@ -79,12 +74,9 @@ impl Command for Lines {
|
||||
})
|
||||
.flatten();
|
||||
|
||||
Ok(Value::Stream {
|
||||
stream: ValueStream(Rc::new(RefCell::new(iter))),
|
||||
span,
|
||||
})
|
||||
Ok(iter.into_pipeline_data())
|
||||
}
|
||||
val => Err(ShellError::UnsupportedInput(
|
||||
PipelineData::Value(val) => Err(ShellError::UnsupportedInput(
|
||||
format!("Not supported input: {}", val.as_string()?),
|
||||
call.head,
|
||||
)),
|
||||
|
@ -1,8 +1,11 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::{Call, CellPath};
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Example, IntoValueStream, ShellError, Signature, Span, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Select;
|
||||
|
||||
impl Command for Select {
|
||||
@ -24,11 +27,12 @@ impl Command for Select {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
let columns: Vec<CellPath> = call.rest(context, 0)?;
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let columns: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
|
||||
let span = call.head;
|
||||
|
||||
select(span, columns, input)
|
||||
@ -50,16 +54,20 @@ impl Command for Select {
|
||||
}
|
||||
}
|
||||
|
||||
fn select(span: Span, columns: Vec<CellPath>, input: Value) -> Result<Value, ShellError> {
|
||||
fn select(
|
||||
span: Span,
|
||||
columns: Vec<CellPath>,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
if columns.is_empty() {
|
||||
return Err(ShellError::CantFindColumn(span, input.span()?));
|
||||
return Err(ShellError::CantFindColumn(span, span)); //FIXME?
|
||||
}
|
||||
|
||||
match input {
|
||||
Value::List {
|
||||
PipelineData::Value(Value::List {
|
||||
vals: input_vals,
|
||||
span,
|
||||
} => {
|
||||
}) => {
|
||||
let mut output = vec![];
|
||||
|
||||
for input_val in input_vals {
|
||||
@ -76,33 +84,30 @@ fn select(span: Span, columns: Vec<CellPath>, input: Value) -> Result<Value, She
|
||||
output.push(Value::Record { cols, vals, span })
|
||||
}
|
||||
|
||||
Ok(Value::List { vals: output, span })
|
||||
Ok(output.into_iter().into_pipeline_data())
|
||||
}
|
||||
Value::Stream { stream, span } => Ok(Value::Stream {
|
||||
stream: stream
|
||||
.map(move |x| {
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
for path in &columns {
|
||||
//FIXME: improve implementation to not clone
|
||||
match x.clone().follow_cell_path(&path.members) {
|
||||
Ok(value) => {
|
||||
cols.push(path.into_string());
|
||||
vals.push(value);
|
||||
}
|
||||
Err(error) => {
|
||||
cols.push(path.into_string());
|
||||
vals.push(Value::Error { error });
|
||||
}
|
||||
PipelineData::Stream(stream) => Ok(stream
|
||||
.map(move |x| {
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
for path in &columns {
|
||||
//FIXME: improve implementation to not clone
|
||||
match x.clone().follow_cell_path(&path.members) {
|
||||
Ok(value) => {
|
||||
cols.push(path.into_string());
|
||||
vals.push(value);
|
||||
}
|
||||
Err(error) => {
|
||||
cols.push(path.into_string());
|
||||
vals.push(Value::Error { error });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Value::Record { cols, vals, span }
|
||||
})
|
||||
.into_value_stream(),
|
||||
span,
|
||||
}),
|
||||
v => {
|
||||
Value::Record { cols, vals, span }
|
||||
})
|
||||
.into_pipeline_data()),
|
||||
PipelineData::Value(v) => {
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
|
||||
@ -114,7 +119,7 @@ fn select(span: Span, columns: Vec<CellPath>, input: Value) -> Result<Value, She
|
||||
vals.push(result);
|
||||
}
|
||||
|
||||
Ok(Value::Record { cols, vals, span })
|
||||
Ok(Value::Record { cols, vals, span }.into_pipeline_data())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::{Call, Expr, Expression};
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{IntoValueStream, ShellError, Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Where;
|
||||
|
||||
impl Command for Where {
|
||||
@ -20,13 +21,17 @@ impl Command for Where {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
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();
|
||||
|
||||
// FIXME: very expensive
|
||||
let mut stack = stack.clone();
|
||||
|
||||
let (var_id, cond) = match cond {
|
||||
Expression {
|
||||
@ -37,54 +42,40 @@ impl Command for Where {
|
||||
};
|
||||
|
||||
match input {
|
||||
Value::Stream { stream, span } => {
|
||||
let output_stream = stream
|
||||
.filter(move |value| {
|
||||
context.add_var(var_id, value.clone());
|
||||
PipelineData::Stream(stream) => Ok(stream
|
||||
.filter(move |value| {
|
||||
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(),
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
.into_value_stream();
|
||||
|
||||
Ok(Value::Stream {
|
||||
stream: output_stream,
|
||||
span,
|
||||
match result {
|
||||
Ok(result) => result.is_true(),
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
}
|
||||
Value::List { vals, span } => {
|
||||
let output_stream = vals
|
||||
.into_iter()
|
||||
.filter(move |value| {
|
||||
context.add_var(var_id, value.clone());
|
||||
.into_pipeline_data()),
|
||||
PipelineData::Value(Value::List { vals, .. }) => Ok(vals
|
||||
.into_iter()
|
||||
.filter(move |value| {
|
||||
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(),
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
.into_value_stream();
|
||||
|
||||
Ok(Value::Stream {
|
||||
stream: output_stream,
|
||||
span,
|
||||
match result {
|
||||
Ok(result) => result.is_true(),
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
}
|
||||
x => {
|
||||
context.add_var(var_id, x.clone());
|
||||
.into_pipeline_data()),
|
||||
PipelineData::Value(x) => {
|
||||
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)
|
||||
Ok(x.into_pipeline_data())
|
||||
} else {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{IntoValueStream, Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Wrap;
|
||||
|
||||
impl Command for Wrap {
|
||||
@ -20,40 +21,36 @@ impl Command for Wrap {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
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 {
|
||||
Value::List { vals, .. } => Ok(Value::List {
|
||||
vals: vals
|
||||
.into_iter()
|
||||
.map(move |x| Value::Record {
|
||||
cols: vec![name.clone()],
|
||||
vals: vec![x],
|
||||
span,
|
||||
})
|
||||
.collect(),
|
||||
span,
|
||||
}),
|
||||
Value::Stream { stream, .. } => Ok(Value::Stream {
|
||||
stream: stream
|
||||
.map(move |x| Value::Record {
|
||||
cols: vec![name.clone()],
|
||||
vals: vec![x],
|
||||
span,
|
||||
})
|
||||
.into_value_stream(),
|
||||
span,
|
||||
}),
|
||||
_ => Ok(Value::Record {
|
||||
PipelineData::Value(Value::List { vals, .. }) => Ok(vals
|
||||
.into_iter()
|
||||
.map(move |x| Value::Record {
|
||||
cols: vec![name.clone()],
|
||||
vals: vec![x],
|
||||
span,
|
||||
})
|
||||
.into_pipeline_data()),
|
||||
PipelineData::Stream(stream) => Ok(stream
|
||||
.map(move |x| Value::Record {
|
||||
cols: vec![name.clone()],
|
||||
vals: vec![x],
|
||||
span,
|
||||
})
|
||||
.into_pipeline_data()),
|
||||
PipelineData::Value(input) => Ok(Value::Record {
|
||||
cols: vec![name],
|
||||
vals: vec![input],
|
||||
span,
|
||||
}),
|
||||
}
|
||||
.into_pipeline_data()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{ShellError, Signature, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, ShellError, Signature};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct From;
|
||||
|
||||
impl Command for From {
|
||||
@ -19,10 +20,11 @@ impl Command for From {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
_call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, ShellError> {
|
||||
Ok(Value::nothing())
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, ShellError> {
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Example, IntoValueStream, ShellError, Signature, Span, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FromJson;
|
||||
|
||||
impl Command for FromJson {
|
||||
@ -67,11 +68,12 @@ impl Command for FromJson {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, ShellError> {
|
||||
let span = input.span()?;
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
let mut string_input = input.collect_string();
|
||||
string_input.push('\n');
|
||||
|
||||
@ -79,21 +81,18 @@ impl Command for FromJson {
|
||||
if call.has_flag("objects") {
|
||||
#[allow(clippy::needless_collect)]
|
||||
let lines: Vec<String> = string_input.lines().map(|x| x.to_string()).collect();
|
||||
Ok(Value::Stream {
|
||||
stream: lines
|
||||
.into_iter()
|
||||
.map(move |mut x| {
|
||||
x.push('\n');
|
||||
match convert_string_to_value(x, span) {
|
||||
Ok(v) => v,
|
||||
Err(error) => Value::Error { error },
|
||||
}
|
||||
})
|
||||
.into_value_stream(),
|
||||
span,
|
||||
})
|
||||
Ok(lines
|
||||
.into_iter()
|
||||
.map(move |mut x| {
|
||||
x.push('\n');
|
||||
match convert_string_to_value(x, span) {
|
||||
Ok(v) => v,
|
||||
Err(error) => Value::Error { error },
|
||||
}
|
||||
})
|
||||
.into_pipeline_data())
|
||||
} else {
|
||||
convert_string_to_value(string_input, span)
|
||||
Ok(convert_string_to_value(string_input, span)?.into_pipeline_data())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Example, ShellError, Signature, Span, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BuildString;
|
||||
|
||||
impl Command for BuildString {
|
||||
@ -41,20 +44,22 @@ impl Command for BuildString {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_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 {
|
||||
val: output.join(""),
|
||||
span: call.head,
|
||||
})
|
||||
}
|
||||
.into_pipeline_data())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,9 +3,10 @@ extern crate unicode_segmentation;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Example, ShellError, Signature, Span, Type, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, Type, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Size;
|
||||
|
||||
impl Command for Size {
|
||||
@ -23,11 +24,12 @@ impl Command for Size {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<Value, ShellError> {
|
||||
size(context, call, input)
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
size(call, input)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -98,9 +100,9 @@ impl Command for Size {
|
||||
}
|
||||
}
|
||||
|
||||
fn size(_context: &EvaluationContext, call: &Call, input: Value) -> Result<Value, ShellError> {
|
||||
fn size(call: &Call, input: PipelineData) -> Result<PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
input.map(span, move |v| match v.as_string() {
|
||||
input.map(move |v| match v.as_string() {
|
||||
Ok(s) => count(&s, span),
|
||||
Err(_) => Value::Error {
|
||||
error: ShellError::PipelineMismatch {
|
||||
|
@ -1,9 +1,10 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
Example, ShellError, Signature, Span, Type, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SubCommand;
|
||||
|
||||
impl Command for SubCommand {
|
||||
@ -38,18 +39,22 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
split_chars(call, input)
|
||||
}
|
||||
}
|
||||
|
||||
fn split_chars(call: &Call, input: Value) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
fn split_chars(
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let span = call.head;
|
||||
|
||||
Ok(input.flat_map(span, move |x| split_chars_helper(&x, span)))
|
||||
input.flat_map(move |x| split_chars_helper(&x, span))
|
||||
}
|
||||
|
||||
fn split_chars_helper(v: &Value, name: Span) -> Vec<Value> {
|
||||
|
@ -1,10 +1,11 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SubCommand;
|
||||
|
||||
impl Command for SubCommand {
|
||||
@ -33,27 +34,27 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
split_column(context, call, input)
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
split_column(engine_state, stack, call, input)
|
||||
}
|
||||
}
|
||||
|
||||
fn split_column(
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
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");
|
||||
|
||||
input.map(name_span, move |x| {
|
||||
split_column_helper(&x, &separator, &rest, collapse_empty, name_span)
|
||||
})
|
||||
input.map(move |x| split_column_helper(&x, &separator, &rest, collapse_empty, name_span))
|
||||
}
|
||||
|
||||
fn split_column_helper(
|
||||
|
@ -1,8 +1,8 @@
|
||||
use nu_engine::get_full_help;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
Signature, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
IntoPipelineData, PipelineData, Signature, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -23,14 +23,20 @@ impl Command for SplitCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_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,10 +1,11 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SubCommand;
|
||||
|
||||
impl Command for SubCommand {
|
||||
@ -26,25 +27,25 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
split_row(context, call, input)
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
split_row(engine_state, stack, call, input)
|
||||
}
|
||||
}
|
||||
|
||||
fn split_row(
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
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(name_span, move |x| {
|
||||
split_row_helper(&x, &separator, name_span)
|
||||
}))
|
||||
input.flat_map(move |x| split_row_helper(&x, &separator, name_span))
|
||||
}
|
||||
|
||||
fn split_row_helper(v: &Value, separator: &Spanned<String>, name: Span) -> Vec<Value> {
|
||||
|
@ -2,9 +2,10 @@ use std::time::Instant;
|
||||
|
||||
use nu_engine::eval_block;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{PipelineData, Signature, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Benchmark;
|
||||
|
||||
impl Command for Benchmark {
|
||||
@ -26,23 +27,22 @@ impl Command for Benchmark {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let block = call.positional[0]
|
||||
.as_block()
|
||||
.expect("internal error: expected block");
|
||||
let engine_state = context.engine_state.borrow();
|
||||
let block = engine_state.get_block(block);
|
||||
|
||||
let state = context.enter_scope();
|
||||
let mut stack = stack.collect_captures(&block.captures);
|
||||
let start_time = Instant::now();
|
||||
eval_block(&state, block, Value::nothing())?;
|
||||
eval_block(engine_state, &mut stack, block, PipelineData::new())?.into_value();
|
||||
|
||||
let end_time = Instant::now();
|
||||
println!("{} ms", (end_time - start_time).as_millis());
|
||||
Ok(Value::Nothing {
|
||||
span: call.positional[0].span,
|
||||
})
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
Example, ShellError, Signature, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Value,
|
||||
};
|
||||
use sysinfo::{ProcessExt, System, SystemExt};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Ps;
|
||||
|
||||
impl Command for Ps {
|
||||
@ -29,10 +30,11 @@ impl Command for Ps {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
run_ps(call)
|
||||
}
|
||||
|
||||
@ -45,7 +47,7 @@ impl Command for Ps {
|
||||
}
|
||||
}
|
||||
|
||||
fn run_ps(call: &Call) -> Result<Value, ShellError> {
|
||||
fn run_ps(call: &Call) -> Result<PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
let long = call.has_flag("long");
|
||||
let mut sys = System::new_all();
|
||||
@ -124,5 +126,5 @@ fn run_ps(call: &Call) -> Result<Value, ShellError> {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Value::List { vals: output, span })
|
||||
Ok(output.into_iter().into_pipeline_data())
|
||||
}
|
||||
|
@ -1,22 +1,19 @@
|
||||
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::process::{Command as CommandSys, Stdio};
|
||||
use std::sync::mpsc;
|
||||
|
||||
use nu_protocol::{
|
||||
ast::{Call, Expression},
|
||||
engine::{Command, EvaluationContext},
|
||||
ShellError, Signature, SyntaxShape, Value,
|
||||
};
|
||||
use nu_protocol::{Span, ValueStream};
|
||||
use nu_protocol::engine::{EngineState, Stack};
|
||||
use nu_protocol::{ast::Call, engine::Command, ShellError, Signature, SyntaxShape, Value};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, Span, Spanned};
|
||||
|
||||
use nu_engine::eval_expression;
|
||||
use nu_engine::CallExt;
|
||||
|
||||
const OUTPUT_BUFFER_SIZE: usize = 8192;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct External;
|
||||
|
||||
impl Command for External {
|
||||
@ -36,53 +33,35 @@ impl Command for External {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<Value, ShellError> {
|
||||
let command = ExternalCommand::try_new(call, context)?;
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
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()
|
||||
}
|
||||
|
||||
pub fn run_with_input(&self, input: Value) -> Result<Value, ShellError> {
|
||||
impl ExternalCommand {
|
||||
pub fn run_with_input(&self, input: PipelineData) -> Result<PipelineData, ShellError> {
|
||||
let mut process = self.create_command();
|
||||
|
||||
// TODO. We don't have a way to know the current directory
|
||||
@ -90,8 +69,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
|
||||
@ -101,11 +79,7 @@ impl<'call, 'contex> ExternalCommand<'call, 'contex> {
|
||||
|
||||
// If there is an input from the pipeline. The stdin from the process
|
||||
// is piped so it can be used to send the input information
|
||||
if let Value::String { .. } = input {
|
||||
process.stdin(Stdio::piped());
|
||||
}
|
||||
|
||||
if let Value::Stream { .. } = input {
|
||||
if !matches!(input, PipelineData::Value(Value::Nothing { .. })) {
|
||||
process.stdin(Stdio::piped());
|
||||
}
|
||||
|
||||
@ -116,33 +90,29 @@ impl<'call, 'contex> ExternalCommand<'call, 'contex> {
|
||||
)),
|
||||
Ok(mut child) => {
|
||||
// if there is a string or a stream, that is sent to the pipe std
|
||||
match input {
|
||||
Value::String { val, span: _ } => {
|
||||
if let Some(mut stdin_write) = child.stdin.take() {
|
||||
self.write_to_stdin(&mut stdin_write, val.as_bytes())?
|
||||
}
|
||||
}
|
||||
Value::Binary { val, span: _ } => {
|
||||
if let Some(mut stdin_write) = child.stdin.take() {
|
||||
self.write_to_stdin(&mut stdin_write, &val)?
|
||||
}
|
||||
}
|
||||
Value::Stream { stream, span: _ } => {
|
||||
if let Some(mut stdin_write) = child.stdin.take() {
|
||||
for value in stream {
|
||||
match value {
|
||||
Value::String { val, span: _ } => {
|
||||
self.write_to_stdin(&mut stdin_write, val.as_bytes())?
|
||||
if let Some(mut stdin_write) = child.stdin.take() {
|
||||
std::thread::spawn(move || {
|
||||
for value in input.into_iter() {
|
||||
match value {
|
||||
Value::String { val, span: _ } => {
|
||||
if stdin_write.write(val.as_bytes()).is_err() {
|
||||
return Ok(());
|
||||
}
|
||||
Value::Binary { val, span: _ } => {
|
||||
self.write_to_stdin(&mut stdin_write, &val)?
|
||||
}
|
||||
Value::Binary { val, span: _ } => {
|
||||
if stdin_write.write(&val).is_err() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
x => {
|
||||
if stdin_write.write(x.into_string().as_bytes()).is_err() {
|
||||
return Err(());
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
||||
// If this external is not the last expression, then its output is piped to a channel
|
||||
@ -185,12 +155,9 @@ impl<'call, 'contex> ExternalCommand<'call, 'contex> {
|
||||
});
|
||||
|
||||
// The ValueStream is consumed by the next expression in the pipeline
|
||||
Value::Stream {
|
||||
stream: ValueStream(Rc::new(RefCell::new(ChannelReceiver::new(rx)))),
|
||||
span: Span::unknown(),
|
||||
}
|
||||
ChannelReceiver::new(rx).into_pipeline_data()
|
||||
} else {
|
||||
Value::nothing()
|
||||
PipelineData::new()
|
||||
};
|
||||
|
||||
match child.wait() {
|
||||
@ -212,8 +179,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
|
||||
@ -222,23 +189,12 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
fn write_to_stdin(&self, stdin_write: &mut ChildStdin, val: &[u8]) -> Result<(), ShellError> {
|
||||
if stdin_write.write(val).is_err() {
|
||||
Err(ShellError::ExternalCommand(
|
||||
"Error writing input to stdin".to_string(),
|
||||
self.name.span,
|
||||
))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The piped data from stdout from the external command can be either String
|
||||
|
@ -1,10 +1,11 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EvaluationContext},
|
||||
Example, ShellError, Signature, Span, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Value,
|
||||
};
|
||||
use sysinfo::{ComponentExt, DiskExt, NetworkExt, ProcessorExt, System, SystemExt, UserExt};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Sys;
|
||||
|
||||
impl Command for Sys {
|
||||
@ -24,10 +25,11 @@ impl Command for Sys {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
run_sys(call)
|
||||
}
|
||||
|
||||
@ -40,7 +42,7 @@ impl Command for Sys {
|
||||
}
|
||||
}
|
||||
|
||||
fn run_sys(call: &Call) -> Result<Value, ShellError> {
|
||||
fn run_sys(call: &Call) -> Result<PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
let mut sys = System::new();
|
||||
|
||||
@ -76,7 +78,8 @@ fn run_sys(call: &Call) -> Result<Value, ShellError> {
|
||||
cols: headers,
|
||||
vals: values,
|
||||
span,
|
||||
})
|
||||
}
|
||||
.into_pipeline_data())
|
||||
}
|
||||
|
||||
pub fn trim_cstyle_null(s: String) -> String {
|
||||
|
@ -2,12 +2,13 @@ use lscolors::{LsColors, Style};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::{Call, PathMember},
|
||||
engine::{Command, EvaluationContext},
|
||||
Signature, Span, SyntaxShape, Value,
|
||||
engine::{Command, EngineState, Stack},
|
||||
IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
use nu_term_grid::grid::{Alignment, Cell, Direction, Filling, Grid, GridOptions};
|
||||
use terminal_size::{Height, Width};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Griddle;
|
||||
|
||||
impl Command for Griddle {
|
||||
@ -47,16 +48,17 @@ prints out the list properly."#
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
let width_param: Option<String> = call.get_flag(context, "width")?;
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
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 {
|
||||
Value::List { vals, .. } => {
|
||||
PipelineData::Value(Value::List { vals, .. }) => {
|
||||
// dbg!("value::list");
|
||||
let data = convert_to_list2(vals);
|
||||
if let Some(items) = data {
|
||||
@ -68,10 +70,10 @@ prints out the list properly."#
|
||||
separator_param,
|
||||
))
|
||||
} else {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
Value::Stream { stream, .. } => {
|
||||
PipelineData::Stream(stream) => {
|
||||
// dbg!("value::stream");
|
||||
let data = convert_to_list2(stream);
|
||||
if let Some(items) = data {
|
||||
@ -84,10 +86,10 @@ prints out the list properly."#
|
||||
))
|
||||
} else {
|
||||
// dbg!(data);
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
Value::Record { cols, vals, .. } => {
|
||||
PipelineData::Value(Value::Record { cols, vals, .. }) => {
|
||||
// dbg!("value::record");
|
||||
let mut items = vec![];
|
||||
|
||||
@ -118,7 +120,7 @@ fn create_grid_output2(
|
||||
width_param: Option<String>,
|
||||
color_param: bool,
|
||||
separator_param: Option<String>,
|
||||
) -> Value {
|
||||
) -> PipelineData {
|
||||
let ls_colors = LsColors::from_env().unwrap_or_default();
|
||||
let cols = if let Some(col) = width_param {
|
||||
col.parse::<u16>().unwrap_or(80)
|
||||
@ -166,6 +168,7 @@ fn create_grid_output2(
|
||||
span: call.head,
|
||||
}
|
||||
}
|
||||
.into_pipeline_data()
|
||||
}
|
||||
|
||||
fn convert_to_list2(iter: impl IntoIterator<Item = Value>) -> Option<Vec<(usize, String, String)>> {
|
||||
|
@ -1,10 +1,11 @@
|
||||
use nu_protocol::ast::{Call, PathMember};
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{ShellError, Signature, Span, Value};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, Span, Value};
|
||||
use nu_table::StyledString;
|
||||
use std::collections::HashMap;
|
||||
use terminal_size::{Height, Width};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Table;
|
||||
|
||||
//NOTE: this is not a real implementation :D. It's just a simple one to test with until we port the real one.
|
||||
@ -23,10 +24,11 @@ impl Command for Table {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let term_width = if let Some((Width(w), Height(_h))) = terminal_size::terminal_size() {
|
||||
w as usize
|
||||
} else {
|
||||
@ -34,7 +36,7 @@ impl Command for Table {
|
||||
};
|
||||
|
||||
match input {
|
||||
Value::List { vals, .. } => {
|
||||
PipelineData::Value(Value::List { vals, .. }) => {
|
||||
let table = convert_to_table(vals)?;
|
||||
|
||||
if let Some(table) = table {
|
||||
@ -43,12 +45,13 @@ impl Command for Table {
|
||||
Ok(Value::String {
|
||||
val: result,
|
||||
span: call.head,
|
||||
})
|
||||
}
|
||||
.into_pipeline_data())
|
||||
} else {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
Value::Stream { stream, .. } => {
|
||||
PipelineData::Stream(stream) => {
|
||||
let table = convert_to_table(stream)?;
|
||||
|
||||
if let Some(table) = table {
|
||||
@ -57,12 +60,13 @@ impl Command for Table {
|
||||
Ok(Value::String {
|
||||
val: result,
|
||||
span: call.head,
|
||||
})
|
||||
}
|
||||
.into_pipeline_data())
|
||||
} else {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
Ok(PipelineData::new())
|
||||
}
|
||||
}
|
||||
Value::Record { cols, vals, .. } => {
|
||||
PipelineData::Value(Value::Record { cols, vals, .. }) => {
|
||||
let mut output = vec![];
|
||||
|
||||
for (c, v) in cols.into_iter().zip(vals.into_iter()) {
|
||||
@ -89,9 +93,10 @@ impl Command for Table {
|
||||
Ok(Value::String {
|
||||
val: result,
|
||||
span: call.head,
|
||||
})
|
||||
}
|
||||
.into_pipeline_data())
|
||||
}
|
||||
Value::Error { error } => Err(error),
|
||||
PipelineData::Value(Value::Error { error }) => Err(error),
|
||||
x => Ok(x),
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user