mirror of
https://github.com/nushell/nushell
synced 2024-12-26 13:03:07 +00:00
Add metadata on open --raw
with bytestreams (#14141)
# Description This PR closes #14137 and allows the display hook to be set on byte streams. So, with a hook like this below. ```nushell display_output: { metadata access {|meta| match $meta.content_type? { "application/x-nuscript" | "application/x-nuon" | "text/x-nushell" => { nu-highlight }, "application/json" => { ^bat --language=json --color=always --style=plain --paging=never }, _ => {}, } } | table } ``` You could type `open toolkit.nu` and the text of toolkit.nu would be highlighted by nu-highlight. This PR also changes the way content-type is assigned with `open`. Previously it would only assign it if `--raw` was specified. Lastly, it changes the `is_external()` function to only say `ByteStreamSource::Child`'s are external instead of both Child and `ByteStreamSource::File`. Again, this was to allow the hook to function properly. I'm not sure what negative ramifications changing `is_external()` could have, but there may be some? # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass (on Windows make sure to [enable developer mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging)) - `cargo run -- -c "use toolkit.nu; toolkit test stdlib"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. -->
This commit is contained in:
parent
abb6fca5e3
commit
af9c31152a
4 changed files with 27 additions and 13 deletions
|
@ -282,8 +282,22 @@ fn evaluate_source(
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
if let PipelineData::ByteStream(..) = pipeline {
|
if let PipelineData::ByteStream(..) = pipeline {
|
||||||
pipeline.print(engine_state, stack, false, false)
|
// run the display hook on bytestreams too
|
||||||
} else if let Some(hook) = engine_state.get_config().hooks.display_output.clone() {
|
run_display_hook(engine_state, stack, pipeline, false)
|
||||||
|
} else {
|
||||||
|
run_display_hook(engine_state, stack, pipeline, true)
|
||||||
|
}?;
|
||||||
|
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_display_hook(
|
||||||
|
engine_state: &mut EngineState,
|
||||||
|
stack: &mut Stack,
|
||||||
|
pipeline: PipelineData,
|
||||||
|
no_newline: bool,
|
||||||
|
) -> Result<(), ShellError> {
|
||||||
|
if let Some(hook) = engine_state.get_config().hooks.display_output.clone() {
|
||||||
let pipeline = eval_hook(
|
let pipeline = eval_hook(
|
||||||
engine_state,
|
engine_state,
|
||||||
stack,
|
stack,
|
||||||
|
@ -292,14 +306,11 @@ fn evaluate_source(
|
||||||
&hook,
|
&hook,
|
||||||
"display_output",
|
"display_output",
|
||||||
)?;
|
)?;
|
||||||
pipeline.print(engine_state, stack, false, false)
|
pipeline.print(engine_state, stack, no_newline, false)
|
||||||
} else {
|
} else {
|
||||||
pipeline.print(engine_state, stack, true, false)
|
pipeline.print(engine_state, stack, no_newline, false)
|
||||||
}?;
|
}
|
||||||
|
|
||||||
Ok(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -146,6 +146,9 @@ impl Command for Open {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Assigning content type should only happen in raw mode. Otherwise, the content
|
||||||
|
// will potentially be in one of the built-in nushell `from xxx` formats and therefore
|
||||||
|
// cease to be in the original content-type.... or so I'm told. :)
|
||||||
let content_type = if raw {
|
let content_type = if raw {
|
||||||
path.extension()
|
path.extension()
|
||||||
.map(|ext| ext.to_string_lossy().to_string())
|
.map(|ext| ext.to_string_lossy().to_string())
|
||||||
|
@ -283,6 +286,9 @@ fn detect_content_type(extension: &str) -> Option<String> {
|
||||||
match extension {
|
match extension {
|
||||||
// Per RFC-9512, application/yaml should be used
|
// Per RFC-9512, application/yaml should be used
|
||||||
"yaml" | "yml" => Some("application/yaml".to_string()),
|
"yaml" | "yml" => Some("application/yaml".to_string()),
|
||||||
|
"nu" => Some("application/x-nuscript".to_string()),
|
||||||
|
"json" | "jsonl" | "ndjson" => Some("application/json".to_string()),
|
||||||
|
"nuon" => Some("application/x-nuon".to_string()),
|
||||||
_ => mime_guess::from_ext(extension)
|
_ => mime_guess::from_ext(extension)
|
||||||
.first()
|
.first()
|
||||||
.map(|mime| mime.to_string()),
|
.map(|mime| mime.to_string()),
|
||||||
|
|
|
@ -394,7 +394,7 @@ fn test_content_types_with_open_raw() {
|
||||||
let result = nu!(cwd: dirs.formats(), "open --raw sample_data.xlsx | metadata");
|
let result = nu!(cwd: dirs.formats(), "open --raw sample_data.xlsx | metadata");
|
||||||
assert!(result.out.contains("vnd.openxmlformats-officedocument"));
|
assert!(result.out.contains("vnd.openxmlformats-officedocument"));
|
||||||
let result = nu!(cwd: dirs.formats(), "open --raw sample_def.nu | metadata");
|
let result = nu!(cwd: dirs.formats(), "open --raw sample_def.nu | metadata");
|
||||||
assert!(!result.out.contains("content_type"));
|
assert!(result.out.contains("application/x-nuscript"));
|
||||||
let result = nu!(cwd: dirs.formats(), "open --raw sample.eml | metadata");
|
let result = nu!(cwd: dirs.formats(), "open --raw sample.eml | metadata");
|
||||||
assert!(result.out.contains("message/rfc822"));
|
assert!(result.out.contains("message/rfc822"));
|
||||||
let result = nu!(cwd: dirs.formats(), "open --raw cargo_sample.toml | metadata");
|
let result = nu!(cwd: dirs.formats(), "open --raw cargo_sample.toml | metadata");
|
||||||
|
|
|
@ -41,10 +41,7 @@ impl ByteStreamSource {
|
||||||
|
|
||||||
/// Source is a `Child` or `File`, rather than `Read`. Currently affects trimming
|
/// Source is a `Child` or `File`, rather than `Read`. Currently affects trimming
|
||||||
fn is_external(&self) -> bool {
|
fn is_external(&self) -> bool {
|
||||||
matches!(
|
matches!(self, ByteStreamSource::Child(..))
|
||||||
self,
|
|
||||||
ByteStreamSource::File(..) | ByteStreamSource::Child(..)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue