forked from extern/nushell
add shape ExternalResolved
to show found externals via syntax highlighting in the repl (#11135)
# Description This PR enables a new feature that shows which externals are found in your path via the syntax highlighter as you type. ![external_resolved](https://github.com/nushell/nushell/assets/343840/e5fa91f0-6fac-485c-8afc-5711fc0ed9bc) This idea could use some improvement where it caches the items in your path and on some trigger, expires that cache and creates a new on. Right now, all it does is call the `which` crate on every character you type. This could be problematic if you have hundreds of paths in your PATH or if some of your paths in your Path point to extraordinarily slow file systems. WSL pointing to Windows comes to mind. Either way, I've thrown it up here for people to try and provide feedback. I think the novelty of showing what is valid and what isn't is pretty cool. I believe fish-shell also does this, IIRC. # 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 std testing; testing run-tests --path crates/nu-std"` 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
85c6047b71
commit
d77f1753c2
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2723,6 +2723,7 @@ dependencies = [
|
|||||||
"sysinfo",
|
"sysinfo",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
"which 5.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -40,6 +40,7 @@ pathdiff = "0.2"
|
|||||||
sysinfo = "0.29"
|
sysinfo = "0.29"
|
||||||
unicode-segmentation = "1.10"
|
unicode-segmentation = "1.10"
|
||||||
uuid = { version = "1.6.0", features = ["v4"] }
|
uuid = { version = "1.6.0", features = ["v4"] }
|
||||||
|
which = "5.0.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
plugin = []
|
plugin = []
|
||||||
|
@ -17,10 +17,27 @@ impl Highlighter for NuHighlighter {
|
|||||||
fn highlight(&self, line: &str, _cursor: usize) -> StyledText {
|
fn highlight(&self, line: &str, _cursor: usize) -> StyledText {
|
||||||
trace!("highlighting: {}", line);
|
trace!("highlighting: {}", line);
|
||||||
|
|
||||||
|
let highlight_resolved_externals =
|
||||||
|
self.engine_state.get_config().highlight_resolved_externals;
|
||||||
let mut working_set = StateWorkingSet::new(&self.engine_state);
|
let mut working_set = StateWorkingSet::new(&self.engine_state);
|
||||||
let block = parse(&mut working_set, None, line.as_bytes(), false);
|
let block = parse(&mut working_set, None, line.as_bytes(), false);
|
||||||
let (shapes, global_span_offset) = {
|
let (shapes, global_span_offset) = {
|
||||||
let shapes = flatten_block(&working_set, &block);
|
let mut shapes = flatten_block(&working_set, &block);
|
||||||
|
// Highlighting externals has a config point because of concerns that using which to resolve
|
||||||
|
// externals may slow down things too much.
|
||||||
|
if highlight_resolved_externals {
|
||||||
|
for (span, shape) in shapes.iter_mut() {
|
||||||
|
if *shape == FlatShape::External {
|
||||||
|
let str_contents =
|
||||||
|
working_set.get_span_contents(Span::new(span.start, span.end));
|
||||||
|
|
||||||
|
let str_word = String::from_utf8_lossy(str_contents).to_string();
|
||||||
|
if which::which(str_word).ok().is_some() {
|
||||||
|
*shape = FlatShape::ExternalResolved;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
(shapes, self.engine_state.next_span_start())
|
(shapes, self.engine_state.next_span_start())
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -91,6 +108,7 @@ impl Highlighter for NuHighlighter {
|
|||||||
FlatShape::InternalCall(_) => add_colored_token(&shape.1, next_token),
|
FlatShape::InternalCall(_) => add_colored_token(&shape.1, next_token),
|
||||||
FlatShape::External => add_colored_token(&shape.1, next_token),
|
FlatShape::External => add_colored_token(&shape.1, next_token),
|
||||||
FlatShape::ExternalArg => add_colored_token(&shape.1, next_token),
|
FlatShape::ExternalArg => add_colored_token(&shape.1, next_token),
|
||||||
|
FlatShape::ExternalResolved => add_colored_token(&shape.1, next_token),
|
||||||
FlatShape::Keyword => add_colored_token(&shape.1, next_token),
|
FlatShape::Keyword => add_colored_token(&shape.1, next_token),
|
||||||
FlatShape::Literal => add_colored_token(&shape.1, next_token),
|
FlatShape::Literal => add_colored_token(&shape.1, next_token),
|
||||||
FlatShape::Operator => add_colored_token(&shape.1, next_token),
|
FlatShape::Operator => add_colored_token(&shape.1, next_token),
|
||||||
|
@ -15,6 +15,7 @@ pub fn default_shape_color(shape: String) -> Style {
|
|||||||
"shape_directory" => Style::new().fg(Color::Cyan),
|
"shape_directory" => Style::new().fg(Color::Cyan),
|
||||||
"shape_external" => Style::new().fg(Color::Cyan),
|
"shape_external" => Style::new().fg(Color::Cyan),
|
||||||
"shape_externalarg" => Style::new().fg(Color::Green).bold(),
|
"shape_externalarg" => Style::new().fg(Color::Green).bold(),
|
||||||
|
"shape_external_resolved" => Style::new().fg(Color::LightYellow).bold(),
|
||||||
"shape_filepath" => Style::new().fg(Color::Cyan),
|
"shape_filepath" => Style::new().fg(Color::Cyan),
|
||||||
"shape_flag" => Style::new().fg(Color::Blue).bold(),
|
"shape_flag" => Style::new().fg(Color::Blue).bold(),
|
||||||
"shape_float" => Style::new().fg(Color::Purple).bold(),
|
"shape_float" => Style::new().fg(Color::Purple).bold(),
|
||||||
|
@ -18,6 +18,7 @@ pub enum FlatShape {
|
|||||||
Directory,
|
Directory,
|
||||||
External,
|
External,
|
||||||
ExternalArg,
|
ExternalArg,
|
||||||
|
ExternalResolved,
|
||||||
Filepath,
|
Filepath,
|
||||||
Flag,
|
Flag,
|
||||||
Float,
|
Float,
|
||||||
@ -57,6 +58,7 @@ impl Display for FlatShape {
|
|||||||
FlatShape::Directory => write!(f, "shape_directory"),
|
FlatShape::Directory => write!(f, "shape_directory"),
|
||||||
FlatShape::External => write!(f, "shape_external"),
|
FlatShape::External => write!(f, "shape_external"),
|
||||||
FlatShape::ExternalArg => write!(f, "shape_externalarg"),
|
FlatShape::ExternalArg => write!(f, "shape_externalarg"),
|
||||||
|
FlatShape::ExternalResolved => write!(f, "shape_external_resolved"),
|
||||||
FlatShape::Filepath => write!(f, "shape_filepath"),
|
FlatShape::Filepath => write!(f, "shape_filepath"),
|
||||||
FlatShape::Flag => write!(f, "shape_flag"),
|
FlatShape::Flag => write!(f, "shape_flag"),
|
||||||
FlatShape::Float => write!(f, "shape_float"),
|
FlatShape::Float => write!(f, "shape_float"),
|
||||||
|
@ -72,6 +72,7 @@ pub struct Config {
|
|||||||
pub datetime_table_format: Option<String>,
|
pub datetime_table_format: Option<String>,
|
||||||
pub error_style: ErrorStyle,
|
pub error_style: ErrorStyle,
|
||||||
pub use_kitty_protocol: bool,
|
pub use_kitty_protocol: bool,
|
||||||
|
pub highlight_resolved_externals: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
@ -137,6 +138,7 @@ impl Default for Config {
|
|||||||
error_style: ErrorStyle::Fancy,
|
error_style: ErrorStyle::Fancy,
|
||||||
|
|
||||||
use_kitty_protocol: false,
|
use_kitty_protocol: false,
|
||||||
|
highlight_resolved_externals: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -622,6 +624,9 @@ impl Value {
|
|||||||
"use_kitty_protocol" => {
|
"use_kitty_protocol" => {
|
||||||
process_bool_config(value, &mut errors, &mut config.use_kitty_protocol);
|
process_bool_config(value, &mut errors, &mut config.use_kitty_protocol);
|
||||||
}
|
}
|
||||||
|
"highlight_resolved_externals" => {
|
||||||
|
process_bool_config(value, &mut errors, &mut config.highlight_resolved_externals);
|
||||||
|
}
|
||||||
// Menus
|
// Menus
|
||||||
"menus" => match create_menus(value) {
|
"menus" => match create_menus(value) {
|
||||||
Ok(map) => config.menus = map,
|
Ok(map) => config.menus = map,
|
||||||
|
@ -42,6 +42,7 @@ let dark_theme = {
|
|||||||
shape_directory: cyan
|
shape_directory: cyan
|
||||||
shape_external: cyan
|
shape_external: cyan
|
||||||
shape_externalarg: green_bold
|
shape_externalarg: green_bold
|
||||||
|
shape_external_resolved: light_yellow_bold
|
||||||
shape_filepath: cyan
|
shape_filepath: cyan
|
||||||
shape_flag: blue_bold
|
shape_flag: blue_bold
|
||||||
shape_float: purple_bold
|
shape_float: purple_bold
|
||||||
@ -106,6 +107,7 @@ let light_theme = {
|
|||||||
shape_directory: cyan
|
shape_directory: cyan
|
||||||
shape_external: cyan
|
shape_external: cyan
|
||||||
shape_externalarg: green_bold
|
shape_externalarg: green_bold
|
||||||
|
shape_external_resolved: light_purple_bold
|
||||||
shape_filepath: cyan
|
shape_filepath: cyan
|
||||||
shape_flag: blue_bold
|
shape_flag: blue_bold
|
||||||
shape_float: purple_bold
|
shape_float: purple_bold
|
||||||
@ -233,7 +235,8 @@ $env.config = {
|
|||||||
edit_mode: emacs # emacs, vi
|
edit_mode: emacs # emacs, vi
|
||||||
shell_integration: false # enables terminal shell integration. Off by default, as some terminals have issues with this.
|
shell_integration: false # enables terminal shell integration. Off by default, as some terminals have issues with this.
|
||||||
render_right_prompt_on_last_line: false # true or false to enable or disable right prompt to be rendered on last line of the prompt.
|
render_right_prompt_on_last_line: false # true or false to enable or disable right prompt to be rendered on last line of the prompt.
|
||||||
use_kitty_protocol: false # enables keyboard enhancement protocol implemented by kitty console, only if your terminal support this
|
use_kitty_protocol: false # enables keyboard enhancement protocol implemented by kitty console, only if your terminal support this.
|
||||||
|
highlight_resolved_externals: false # true enables highlighting of external commands in the repl resolved by which.
|
||||||
|
|
||||||
hooks: {
|
hooks: {
|
||||||
pre_prompt: [{ null }] # run before the prompt is shown
|
pre_prompt: [{ null }] # run before the prompt is shown
|
||||||
|
Loading…
Reference in New Issue
Block a user