Use 'table' during internal->external (#898)

* Use 'table' during internal->external

* Preserve more of config
This commit is contained in:
JT 2022-01-31 07:52:05 -05:00 committed by GitHub
parent def5869c1c
commit d62716c83e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 29 deletions

View file

@ -8,7 +8,7 @@ use std::sync::mpsc;
use nu_engine::env_to_strings; use nu_engine::env_to_strings;
use nu_protocol::engine::{EngineState, Stack}; use nu_protocol::engine::{EngineState, Stack};
use nu_protocol::{ast::Call, engine::Command, ShellError, Signature, SyntaxShape, Value}; use nu_protocol::{ast::Call, engine::Command, ShellError, Signature, SyntaxShape, Value};
use nu_protocol::{Category, Config, PipelineData, RawStream, Span, Spanned}; use nu_protocol::{Category, PipelineData, RawStream, Span, Spanned};
use itertools::Itertools; use itertools::Itertools;
@ -96,7 +96,7 @@ impl Command for External {
last_expression, last_expression,
env_vars: env_vars_str, env_vars: env_vars_str,
}; };
command.run_with_input(engine_state, input, config) command.run_with_input(engine_state, stack, input)
} }
} }
@ -111,8 +111,8 @@ impl ExternalCommand {
pub fn run_with_input( pub fn run_with_input(
&self, &self,
engine_state: &EngineState, engine_state: &EngineState,
stack: &mut Stack,
input: PipelineData, input: PipelineData,
config: Config,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let head = self.name.span; let head = self.name.span;
@ -155,34 +155,43 @@ impl ExternalCommand {
self.name.span, self.name.span,
)), )),
Ok(mut child) => { Ok(mut child) => {
if !input.is_nothing() {
let engine_state = engine_state.clone();
let mut stack = stack.clone();
stack.update_config(
"use_ansi_coloring",
Value::Bool {
val: false,
span: Span::new(0, 0),
},
);
// 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
if let Some(mut stdin_write) = child.stdin.take() { if let Some(mut stdin_write) = child.stdin.take() {
std::thread::spawn(move || { std::thread::spawn(move || {
let input = crate::Table::run(
&crate::Table,
&engine_state,
&mut stack,
&Call::new(),
input,
);
if let Ok(input) = input {
for value in input.into_iter() { for value in input.into_iter() {
match value { if let Value::String { val, span: _ } = value {
Value::String { val, span: _ } => {
if stdin_write.write(val.as_bytes()).is_err() { if stdin_write.write(val.as_bytes()).is_err() {
return Ok(()); return Ok(());
} }
} } else {
Value::Binary { val, span: _ } => {
if stdin_write.write(&val).is_err() {
return Ok(());
}
}
x => {
if stdin_write
.write(x.into_string(", ", &config).as_bytes())
.is_err()
{
return Err(()); return Err(());
} }
} }
} }
}
Ok(()) Ok(())
}); });
} }
}
let last_expression = self.last_expression; let last_expression = self.last_expression;
let span = self.name.span; let span = self.name.span;

View file

@ -178,11 +178,21 @@ impl Stack {
match config { match config {
Ok(config) => config.into_config(), Ok(config) => config.into_config(),
Err(e) => { Err(e) => Err(e),
println!("Can't find {} in {:?}", CONFIG_VARIABLE_ID, self);
Err(e)
} }
} }
pub fn update_config(&mut self, name: &str, value: Value) {
if let Some(Value::Record { cols, vals, .. }) = self.vars.get_mut(&CONFIG_VARIABLE_ID) {
for col_val in cols.iter().zip(vals.iter_mut()) {
if col_val.0 == name {
*col_val.1 = value;
return;
}
}
cols.push(name.to_string());
vals.push(value);
}
} }
pub fn print_stack(&self) { pub fn print_stack(&self) {

View file

@ -75,6 +75,10 @@ impl PipelineData {
self self
} }
pub fn is_nothing(&self) -> bool {
matches!(self, PipelineData::Value(Value::Nothing { .. }, ..))
}
pub fn into_value(self, span: Span) -> Value { pub fn into_value(self, span: Span) -> Value {
match self { match self {
PipelineData::Value(Value::Nothing { .. }, ..) => Value::nothing(span), PipelineData::Value(Value::Nothing { .. }, ..) => Value::nothing(span),