mirror of
https://github.com/nushell/nushell.git
synced 2024-11-16 05:23:44 +01:00
commit
22c6ed4718
@ -1,7 +1,7 @@
|
|||||||
use nu_engine::eval_expression;
|
use nu_engine::eval_expression;
|
||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EvaluationContext};
|
use nu_protocol::engine::{Command, EvaluationContext};
|
||||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
use nu_protocol::{ShellError, Signature, SyntaxShape, Value};
|
||||||
|
|
||||||
pub struct BuildString;
|
pub struct BuildString;
|
||||||
|
|
||||||
@ -24,13 +24,12 @@ impl Command for BuildString {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
_input: Value,
|
_input: Value,
|
||||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||||
let mut output = vec![];
|
let output = call
|
||||||
|
.positional
|
||||||
|
.iter()
|
||||||
|
.map(|expr| eval_expression(context, expr).map(|val| val.into_string()))
|
||||||
|
.collect::<Result<Vec<String>, ShellError>>()?;
|
||||||
|
|
||||||
for expr in &call.positional {
|
|
||||||
let val = eval_expression(context, expr)?;
|
|
||||||
|
|
||||||
output.push(val.into_string());
|
|
||||||
}
|
|
||||||
Ok(Value::String {
|
Ok(Value::String {
|
||||||
val: output.join(""),
|
val: output.join(""),
|
||||||
span: call.head,
|
span: call.head,
|
||||||
|
@ -67,6 +67,8 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
|
|||||||
working_set.add_decl(sig.predeclare());
|
working_set.add_decl(sig.predeclare());
|
||||||
let sig = Signature::build("stack");
|
let sig = Signature::build("stack");
|
||||||
working_set.add_decl(sig.predeclare());
|
working_set.add_decl(sig.predeclare());
|
||||||
|
let sig = Signature::build("contents");
|
||||||
|
working_set.add_decl(sig.predeclare());
|
||||||
|
|
||||||
working_set.render()
|
working_set.render()
|
||||||
};
|
};
|
||||||
|
@ -62,7 +62,7 @@ impl Command for Lines {
|
|||||||
.filter_map(|s| {
|
.filter_map(|s| {
|
||||||
if !s.is_empty() {
|
if !s.is_empty() {
|
||||||
Some(Value::String {
|
Some(Value::String {
|
||||||
val: s.into(),
|
val: s.trim().into(),
|
||||||
span,
|
span,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -117,7 +117,6 @@ impl<'call, 'contex> ExternalCommand<'call, 'contex> {
|
|||||||
Ok(mut child) => {
|
Ok(mut child) => {
|
||||||
// if there is a string or a stream, that is sent to the pipe std
|
// if there is a string or a stream, that is sent to the pipe std
|
||||||
match input {
|
match input {
|
||||||
Value::Nothing { span: _ } => (),
|
|
||||||
Value::String { val, span: _ } => {
|
Value::String { val, span: _ } => {
|
||||||
if let Some(mut stdin_write) = child.stdin.take() {
|
if let Some(mut stdin_write) = child.stdin.take() {
|
||||||
self.write_to_stdin(&mut stdin_write, val.as_bytes())?
|
self.write_to_stdin(&mut stdin_write, val.as_bytes())?
|
||||||
@ -143,12 +142,7 @@ impl<'call, 'contex> ExternalCommand<'call, 'contex> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => (),
|
||||||
return Err(ShellError::ExternalCommand(
|
|
||||||
"Input is not string or binary".to_string(),
|
|
||||||
self.name.span,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this external is not the last expression, then its output is piped to a channel
|
// If this external is not the last expression, then its output is piped to a channel
|
||||||
|
@ -65,7 +65,11 @@ fn convert_to_table(iter: impl IntoIterator<Item = Value>) -> Option<nu_table::T
|
|||||||
let mut iter = iter.into_iter().peekable();
|
let mut iter = iter.into_iter().peekable();
|
||||||
|
|
||||||
if let Some(first) = iter.peek() {
|
if let Some(first) = iter.peek() {
|
||||||
let mut headers = first.columns();
|
let mut headers = match first {
|
||||||
|
Value::Record { .. } => first.columns(),
|
||||||
|
_ => ["Column_0".to_string()].to_vec(),
|
||||||
|
};
|
||||||
|
|
||||||
headers.insert(0, "#".into());
|
headers.insert(0, "#".into());
|
||||||
|
|
||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
@ -74,10 +78,13 @@ fn convert_to_table(iter: impl IntoIterator<Item = Value>) -> Option<nu_table::T
|
|||||||
let mut row = vec![row_num.to_string()];
|
let mut row = vec![row_num.to_string()];
|
||||||
|
|
||||||
for header in headers.iter().skip(1) {
|
for header in headers.iter().skip(1) {
|
||||||
let result = item.clone().follow_cell_path(&[PathMember::String {
|
let result = match item {
|
||||||
val: header.into(),
|
Value::Record { .. } => item.clone().follow_cell_path(&[PathMember::String {
|
||||||
span: Span::unknown(),
|
val: header.into(),
|
||||||
}]);
|
span: Span::unknown(),
|
||||||
|
}]),
|
||||||
|
_ => Ok(item.clone()),
|
||||||
|
};
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(value) => row.push(value.into_string()),
|
Ok(value) => row.push(value.into_string()),
|
||||||
|
@ -113,6 +113,11 @@ impl EngineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn print_contents(&self) {
|
||||||
|
let string = String::from_utf8_lossy(&self.file_contents);
|
||||||
|
println!("{}", string);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find_decl(&self, name: &[u8]) -> Option<DeclId> {
|
pub fn find_decl(&self, name: &[u8]) -> Option<DeclId> {
|
||||||
for scope in self.scope.iter().rev() {
|
for scope in self.scope.iter().rev() {
|
||||||
if let Some(decl_id) = scope.decls.get(name) {
|
if let Some(decl_id) = scope.decls.get(name) {
|
||||||
|
35
src/main.rs
35
src/main.rs
@ -1,11 +1,14 @@
|
|||||||
|
use std::io::Write;
|
||||||
|
|
||||||
use miette::{IntoDiagnostic, Result};
|
use miette::{IntoDiagnostic, Result};
|
||||||
use nu_cli::{report_error, NuCompleter, NuHighlighter, NuValidator};
|
use nu_cli::{report_error, NuCompleter, NuHighlighter, NuValidator};
|
||||||
use nu_command::create_default_context;
|
use nu_command::create_default_context;
|
||||||
use nu_engine::eval_block;
|
use nu_engine::eval_block;
|
||||||
use nu_parser::parse;
|
use nu_parser::parse;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
|
ast::Call,
|
||||||
engine::{EngineState, EvaluationContext, StateWorkingSet},
|
engine::{EngineState, EvaluationContext, StateWorkingSet},
|
||||||
Value,
|
ShellError, Value,
|
||||||
};
|
};
|
||||||
use reedline::DefaultCompletionActionHandler;
|
use reedline::DefaultCompletionActionHandler;
|
||||||
|
|
||||||
@ -99,6 +102,9 @@ fn main() -> Result<()> {
|
|||||||
} else if s.trim() == "stack" {
|
} else if s.trim() == "stack" {
|
||||||
stack.print_stack();
|
stack.print_stack();
|
||||||
continue;
|
continue;
|
||||||
|
} else if s.trim() == "contents" {
|
||||||
|
engine_state.borrow().print_contents();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (block, delta) = {
|
let (block, delta) = {
|
||||||
@ -125,9 +131,7 @@ fn main() -> Result<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match eval_block(&state, &block, Value::nothing()) {
|
match eval_block(&state, &block, Value::nothing()) {
|
||||||
Ok(value) => {
|
Ok(value) => print_value(value, &state)?,
|
||||||
println!("{}", value.into_string());
|
|
||||||
}
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let engine_state = engine_state.borrow();
|
let engine_state = engine_state.borrow();
|
||||||
let working_set = StateWorkingSet::new(&*engine_state);
|
let working_set = StateWorkingSet::new(&*engine_state);
|
||||||
@ -157,3 +161,26 @@ fn main() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_value(value: Value, state: &EvaluationContext) -> Result<(), ShellError> {
|
||||||
|
// If the table function is in the declarations, then we can use it
|
||||||
|
// to create the table value that will be printed in the terminal
|
||||||
|
let engine_state = state.engine_state.borrow();
|
||||||
|
let output = match engine_state.find_decl("table".as_bytes()) {
|
||||||
|
Some(decl_id) => {
|
||||||
|
let table = engine_state
|
||||||
|
.get_decl(decl_id)
|
||||||
|
.run(state, &Call::new(), value)?;
|
||||||
|
table.into_string()
|
||||||
|
}
|
||||||
|
None => value.into_string(),
|
||||||
|
};
|
||||||
|
let stdout = std::io::stdout();
|
||||||
|
|
||||||
|
match stdout.lock().write_all(output.as_bytes()) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(err) => eprintln!("{}", err),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user