added nu-utils crate, fixed issue where externals turn off vt processing (#4857)

* added `nu-utils` crate, fixed issue where externals turn off vt processing

* hopefully make work in non-windows environments

* clippy
This commit is contained in:
Darren Schroeder 2022-03-16 17:21:06 -05:00 committed by GitHub
parent 460d635ed0
commit ca12f39db3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 104 additions and 30 deletions

10
Cargo.lock generated
View File

@ -2173,6 +2173,7 @@ dependencies = [
"nu-table", "nu-table",
"nu-term-grid", "nu-term-grid",
"nu-test-support", "nu-test-support",
"nu-utils",
"pretty_assertions", "pretty_assertions",
"pretty_env_logger", "pretty_env_logger",
"rayon", "rayon",
@ -2207,6 +2208,7 @@ dependencies = [
"nu-parser", "nu-parser",
"nu-path", "nu-path",
"nu-protocol", "nu-protocol",
"nu-utils",
"reedline", "reedline",
"thiserror", "thiserror",
] ]
@ -2267,6 +2269,7 @@ dependencies = [
"nu-table", "nu-table",
"nu-term-grid", "nu-term-grid",
"nu-test-support", "nu-test-support",
"nu-utils",
"num 0.4.0", "num 0.4.0",
"pathdiff", "pathdiff",
"polars", "polars",
@ -2448,6 +2451,13 @@ dependencies = [
"tempfile", "tempfile",
] ]
[[package]]
name = "nu-utils"
version = "0.59.1"
dependencies = [
"crossterm_winapi",
]
[[package]] [[package]]
name = "nu_plugin_example" name = "nu_plugin_example"
version = "0.59.1" version = "0.59.1"

View File

@ -27,6 +27,7 @@ members = [
"crates/nu_plugin_gstat", "crates/nu_plugin_gstat",
"crates/nu_plugin_example", "crates/nu_plugin_example",
"crates/nu_plugin_query", "crates/nu_plugin_query",
"crates/nu-utils",
] ]
[dependencies] [dependencies]
@ -50,6 +51,7 @@ nu-protocol = { path = "./crates/nu-protocol", version = "0.59.1" }
nu-system = { path = "./crates/nu-system", version = "0.59.1" } nu-system = { path = "./crates/nu-system", version = "0.59.1" }
nu-table = { path = "./crates/nu-table", version = "0.59.1" } nu-table = { path = "./crates/nu-table", version = "0.59.1" }
nu-term-grid = { path = "./crates/nu-term-grid", version = "0.59.1" } nu-term-grid = { path = "./crates/nu-term-grid", version = "0.59.1" }
nu-utils = { path = "./crates/nu-utils", version = "0.59.1" }
pretty_env_logger = "0.4.0" pretty_env_logger = "0.4.0"
rayon = "1.5.1" rayon = "1.5.1"
reedline = { git = "https://github.com/nushell/reedline", branch = "main" } reedline = { git = "https://github.com/nushell/reedline", branch = "main" }
@ -90,7 +92,7 @@ opt-level = "s" # Optimize for size
strip = "debuginfo" strip = "debuginfo"
lto = "thin" lto = "thin"
# build with `cargo build --profile profiling` # build with `cargo build --profile profiling`
# to analyze performance with tooling like linux perf # to analyze performance with tooling like linux perf
[profile.profiling] [profile.profiling]
inherits = "release" inherits = "release"

View File

@ -8,7 +8,7 @@ nu-engine = { path = "../nu-engine", version = "0.59.1" }
nu-path = { path = "../nu-path", version = "0.59.1" } nu-path = { path = "../nu-path", version = "0.59.1" }
nu-parser = { path = "../nu-parser", version = "0.59.1" } nu-parser = { path = "../nu-parser", version = "0.59.1" }
nu-protocol = { path = "../nu-protocol", version = "0.59.1" } nu-protocol = { path = "../nu-protocol", version = "0.59.1" }
# nu-ansi-term = { path = "../nu-ansi-term", version = "0.59.1" } nu-utils = { path = "../nu-utils", version = "0.59.1" }
nu-ansi-term = "0.42.0" nu-ansi-term = "0.42.0"
nu-color-config = { path = "../nu-color-config" } nu-color-config = { path = "../nu-color-config" }

View File

@ -1,16 +1,17 @@
use crate::CliError;
use log::trace; use log::trace;
use nu_engine::eval_block; use nu_engine::eval_block;
use nu_parser::{lex, parse, trim_quotes, Token, TokenContents}; use nu_parser::{lex, parse, trim_quotes, Token, TokenContents};
use std::io::Write;
use std::path::PathBuf;
use crate::CliError;
use nu_protocol::engine::StateWorkingSet; use nu_protocol::engine::StateWorkingSet;
use nu_protocol::{ use nu_protocol::{
ast::Call, ast::Call,
engine::{EngineState, Stack}, engine::{EngineState, Stack},
PipelineData, ShellError, Span, Value, PipelineData, ShellError, Span, Value,
}; };
#[cfg(windows)]
use nu_utils::enable_vt_processing;
use std::io::Write;
use std::path::PathBuf;
pub fn print_pipeline_data( pub fn print_pipeline_data(
input: PipelineData, input: PipelineData,
@ -459,29 +460,6 @@ pub fn external_exceptions(engine_state: &EngineState, stack: &Stack) -> Vec<Vec
executables executables
} }
#[cfg(windows)]
pub fn enable_vt_processing() -> Result<(), ShellError> {
use crossterm_winapi::{ConsoleMode, Handle};
pub const ENABLE_PROCESSED_OUTPUT: u32 = 0x0001;
pub const ENABLE_VIRTUAL_TERMINAL_PROCESSING: u32 = 0x0004;
// let mask = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
let console_mode = ConsoleMode::from(Handle::current_out_handle()?);
let old_mode = console_mode.mode()?;
// researching odd ansi behavior in windows terminal repo revealed that
// enable_processed_output and enable_virtual_terminal_processing should be used
// also, instead of checking old_mode & mask, just set the mode already
// if old_mode & mask == 0 {
console_mode
.set_mode(old_mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING)?;
// }
Ok(())
}
pub fn report_error( pub fn report_error(
working_set: &StateWorkingSet, working_set: &StateWorkingSet,
error: &(dyn miette::Diagnostic + Send + Sync + 'static), error: &(dyn miette::Diagnostic + Send + Sync + 'static),
@ -490,7 +468,7 @@ pub fn report_error(
// reset vt processing, aka ansi because illbehaved externals can break it // reset vt processing, aka ansi because illbehaved externals can break it
#[cfg(windows)] #[cfg(windows)]
{ {
let _ = enable_vt_processing(); let _ = nu_utils::enable_vt_processing();
} }
} }

View File

@ -23,6 +23,7 @@ nu-system = { path = "../nu-system", version = "0.59.1" }
nu-table = { path = "../nu-table", version = "0.59.1" } nu-table = { path = "../nu-table", version = "0.59.1" }
nu-term-grid = { path = "../nu-term-grid", version = "0.59.1" } nu-term-grid = { path = "../nu-term-grid", version = "0.59.1" }
nu-test-support = { path = "../nu-test-support", version = "0.59.1" } nu-test-support = { path = "../nu-test-support", version = "0.59.1" }
nu-utils = { path = "../nu-utils", version = "0.59.1" }
# Potential dependencies for extras # Potential dependencies for extras
base64 = "0.13.0" base64 = "0.13.0"

View File

@ -63,6 +63,12 @@ impl Command for Table {
80usize 80usize
}; };
// reset vt processing, aka ansi because illbehaved externals can break it
#[cfg(windows)]
{
let _ = nu_utils::enable_vt_processing();
}
match input { match input {
PipelineData::ExternalStream { .. } => Ok(input), PipelineData::ExternalStream { .. } => Ok(input),
PipelineData::Value(Value::Binary { val, .. }, ..) => { PipelineData::Value(Value::Binary { val, .. }, ..) => {

22
crates/nu-utils/.gitignore vendored Normal file
View File

@ -0,0 +1,22 @@
/target
/scratch
**/*.rs.bk
history.txt
tests/fixtures/nuplayground
crates/*/target
# Debian/Ubuntu
debian/.debhelper/
debian/debhelper-build-stamp
debian/files
debian/nu.substvars
debian/nu/
# macOS junk
.DS_Store
# JetBrains' IDE items
.idea/*
# VSCode's IDE items
.vscode/*

View File

@ -0,0 +1,17 @@
[package]
authors = ["The Nushell Project Developers"]
description = "Nushell utility functions"
edition = "2021"
license = "MIT"
name = "nu-utils"
version = "0.59.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bin]]
name = "utils"
path = "src/main.rs"
[dependencies]
[target.'cfg(windows)'.dependencies]
crossterm_winapi = "0.9.0"

View File

@ -0,0 +1,3 @@
pub mod utils;
pub use utils::enable_vt_processing;

View File

@ -0,0 +1,10 @@
#[cfg(windows)]
use nu_utils::utils::enable_vt_processing;
fn main() {
// reset vt processing, aka ansi because illbehaved externals can break it
#[cfg(windows)]
{
let _ = enable_vt_processing();
}
}

View File

@ -0,0 +1,25 @@
use std::io::Result;
pub fn enable_vt_processing() -> Result<()> {
#[cfg(windows)]
{
use crossterm_winapi::{ConsoleMode, Handle};
pub const ENABLE_PROCESSED_OUTPUT: u32 = 0x0001;
pub const ENABLE_VIRTUAL_TERMINAL_PROCESSING: u32 = 0x0004;
// let mask = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
let console_mode = ConsoleMode::from(Handle::current_out_handle()?);
let old_mode = console_mode.mode()?;
// researching odd ansi behavior in windows terminal repo revealed that
// enable_processed_output and enable_virtual_terminal_processing should be used
// also, instead of checking old_mode & mask, just set the mode already
// if old_mode & mask == 0 {
console_mode
.set_mode(old_mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING)?;
// }
}
Ok(())
}