Always pretty print binary values in table (#12294)

# Description
Binary values passed to `table` may or may not be pretty formatted based
on the output destination. This leads to weird behavior as documented in
#12287. This PR changes `table` to always pretty print binary values.
However, binary values passed to external commands will not be formatted
(this is the existing behavior).

# User-Facing Changes
This is a breaking change. E.g.:
```nushell
0x[8989] | table | cat -
```
used to print raw bytes, but it will now print the pretty formatted
bytes.

# After Submitting
Add to 0.92.0 release notes and update documentation.
This commit is contained in:
Ian Manske 2024-03-26 18:22:34 +00:00 committed by GitHub
parent b07e206b36
commit b752fdb0dc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 25 additions and 30 deletions

View File

@ -466,20 +466,26 @@ impl ExternalCommand {
thread::Builder::new() thread::Builder::new()
.name("external stdin worker".to_string()) .name("external stdin worker".to_string())
.spawn(move || { .spawn(move || {
let stack = &mut stack.start_capture(); let input = match input {
// Attempt to render the input as a table before piping it to the external. input @ PipelineData::Value(Value::Binary { .. }, ..) => {
// This is important for pagers like `less`; Ok(input)
// they need to get Nu data rendered for display to users. }
// input => {
// TODO: should we do something different for list<string> inputs? let stack = &mut stack.start_capture();
// Users often expect those to be piped to *nix tools as raw strings separated by newlines // Attempt to render the input as a table before piping it to the external.
let input = crate::Table::run( // This is important for pagers like `less`;
&crate::Table, // they need to get Nu data rendered for display to users.
&engine_state, //
stack, // TODO: should we do something different for list<string> inputs?
&Call::new(head), // Users often expect those to be piped to *nix tools as raw strings separated by newlines
input, crate::Table.run(
); &engine_state,
stack,
&Call::new(head),
input,
)
}
};
if let Ok(input) = input { if let Ok(input) = input {
for value in input.into_iter() { for value in input.into_iter() {

View File

@ -9,9 +9,9 @@ use nu_engine::{env::get_config, env_to_string, CallExt};
use nu_protocol::{ use nu_protocol::{
ast::Call, ast::Call,
engine::{Command, EngineState, Stack}, engine::{Command, EngineState, Stack},
record, Category, Config, DataSource, Example, IntoPipelineData, IoStream, ListStream, record, Category, Config, DataSource, Example, IntoPipelineData, ListStream, PipelineData,
PipelineData, PipelineMetadata, RawStream, Record, ShellError, Signature, Span, SyntaxShape, PipelineMetadata, RawStream, Record, ShellError, Signature, Span, SyntaxShape, TableMode, Type,
TableMode, Type, Value, Value,
}; };
use nu_table::common::create_nu_table_config; use nu_table::common::create_nu_table_config;
use nu_table::{ use nu_table::{
@ -370,21 +370,10 @@ fn handle_table_command(
match input.data { match input.data {
PipelineData::ExternalStream { .. } => Ok(input.data), PipelineData::ExternalStream { .. } => Ok(input.data),
PipelineData::Value(Value::Binary { val, .. }, ..) => { PipelineData::Value(Value::Binary { val, .. }, ..) => {
let stream_list = if matches!( let bytes = format!("{}\n", nu_pretty_hex::pretty_hex(&val)).into_bytes();
input.stack.stdout(),
IoStream::Pipe | IoStream::Capture | IoStream::Null
) {
vec![Ok(val)]
} else {
let hex = format!("{}\n", nu_pretty_hex::pretty_hex(&val))
.as_bytes()
.to_vec();
vec![Ok(hex)]
};
let ctrlc = input.engine_state.ctrlc.clone(); let ctrlc = input.engine_state.ctrlc.clone();
let stream = RawStream::new( let stream = RawStream::new(
Box::new(stream_list.into_iter()), Box::new([Ok(bytes)].into_iter()),
ctrlc, ctrlc,
input.call.head, input.call.head,
None, None,