Skip to content

Commit

Permalink
add shape ExternalResolved to show found externals via syntax highl…
Browse files Browse the repository at this point in the history
…ighting in the repl (nushell#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.
-->
  • Loading branch information
fdncred committed Nov 25, 2023
1 parent 85c6047 commit d77f175
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 2 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/nu-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pathdiff = "0.2"
sysinfo = "0.29"
unicode-segmentation = "1.10"
uuid = { version = "1.6.0", features = ["v4"] }
which = "5.0.0"

[features]
plugin = []
20 changes: 19 additions & 1 deletion crates/nu-cli/src/syntax_highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,27 @@ impl Highlighter for NuHighlighter {
fn highlight(&self, line: &str, _cursor: usize) -> StyledText {
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 block = parse(&mut working_set, None, line.as_bytes(), false);
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())
};

Expand Down Expand Up @@ -91,6 +108,7 @@ impl Highlighter for NuHighlighter {
FlatShape::InternalCall(_) => 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::ExternalResolved => 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::Operator => add_colored_token(&shape.1, next_token),
Expand Down
1 change: 1 addition & 0 deletions crates/nu-color-config/src/shape_color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub fn default_shape_color(shape: String) -> Style {
"shape_directory" => Style::new().fg(Color::Cyan),
"shape_external" => Style::new().fg(Color::Cyan),
"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_flag" => Style::new().fg(Color::Blue).bold(),
"shape_float" => Style::new().fg(Color::Purple).bold(),
Expand Down
2 changes: 2 additions & 0 deletions crates/nu-parser/src/flatten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub enum FlatShape {
Directory,
External,
ExternalArg,
ExternalResolved,
Filepath,
Flag,
Float,
Expand Down Expand Up @@ -57,6 +58,7 @@ impl Display for FlatShape {
FlatShape::Directory => write!(f, "shape_directory"),
FlatShape::External => write!(f, "shape_external"),
FlatShape::ExternalArg => write!(f, "shape_externalarg"),
FlatShape::ExternalResolved => write!(f, "shape_external_resolved"),
FlatShape::Filepath => write!(f, "shape_filepath"),
FlatShape::Flag => write!(f, "shape_flag"),
FlatShape::Float => write!(f, "shape_float"),
Expand Down
5 changes: 5 additions & 0 deletions crates/nu-protocol/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub struct Config {
pub datetime_table_format: Option<String>,
pub error_style: ErrorStyle,
pub use_kitty_protocol: bool,
pub highlight_resolved_externals: bool,
}

impl Default for Config {
Expand Down Expand Up @@ -137,6 +138,7 @@ impl Default for Config {
error_style: ErrorStyle::Fancy,

use_kitty_protocol: false,
highlight_resolved_externals: false,
}
}
}
Expand Down Expand Up @@ -622,6 +624,9 @@ impl Value {
"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" => match create_menus(value) {
Ok(map) => config.menus = map,
Expand Down
5 changes: 4 additions & 1 deletion crates/nu-utils/src/sample_config/default_config.nu
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ let dark_theme = {
shape_directory: cyan
shape_external: cyan
shape_externalarg: green_bold
shape_external_resolved: light_yellow_bold
shape_filepath: cyan
shape_flag: blue_bold
shape_float: purple_bold
Expand Down Expand Up @@ -106,6 +107,7 @@ let light_theme = {
shape_directory: cyan
shape_external: cyan
shape_externalarg: green_bold
shape_external_resolved: light_purple_bold
shape_filepath: cyan
shape_flag: blue_bold
shape_float: purple_bold
Expand Down Expand Up @@ -233,7 +235,8 @@ $env.config = {
edit_mode: emacs # emacs, vi
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.
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: {
pre_prompt: [{ null }] # run before the prompt is shown
Expand Down

0 comments on commit d77f175

Please sign in to comment.