-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
color_config now accepts closures as color values #7141
Conversation
Requesting @zhiburt's thoughts on this… |
fwiw, i think this is a cool change + feature! nice idea! |
Haven't had a chance to look through the code, but this functionality looks very cool+useful. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went through it lightly, seems good.
Thought outloud:
Maybe we could pipe more data to the closure?
For example for tables we could provide and index (row, col), table length, etc.
So we could pass like a context.
But is it worth it?
// It stores the engine state and stack needed to run closures that | ||
// may be defined as a user style. | ||
// | ||
pub struct StyleComputer<'a> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it belongs to nu_table
?
I mean it could be used by many, not only for table construction, in which case there's no reason to depend on nu_table
.
c205571
to
95d9b50
Compare
Did some more investigating and realised the perf isn't actually that bad after all - turns out |
it seems like the problem we'd have with having a parallel table command is that items would be drawn in random order. although there are some parallel methods that always return a consistent order, I believe, which would be ok. it would be an interesting experiment if it could run in parallel and yet maintain the same order. |
We could parallelize an initial width/height calculation which we do for each cell. |
I was thinking more in terms of just the scope of this PR - parallelising the running of each closure. That could be done by shoving the StyleComputer calculation further up the line. I mean, the LS_COLORS colours are applied in a loop at the top of |
0285077
to
88557ab
Compare
21b5847
to
176f902
Compare
Managed to parallelise style closure execution in convert_to_table()… had some good perf results. Still want to try and tackle the other table-making fns before I'm satisfied. |
nice job parallelizing it. what type of perf results are you seeing? |
Well, using a config similar to the first post (with dates and filesizes coloured by size), I benchmarked running |
Wow! That's a great performance improvement. |
let mut cells: Vec<Vec<_>> = Vec::new(); | ||
cells.par_extend(data.into_par_iter().map(|row| { | ||
let mut new_row = Vec::new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi there;
I wonder if you could use Vec::with_capacity
and use index instead of extend
.
As I see collect_into_vec
must do exactly that?
(Presumably must be a little bit efficient.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I was writing those lines I was making some misassumptions about what Rayon methods would guarantee preserved ordering… I have a better sense of it now and can write this a bit different.
0ff9d99
to
66a722b
Compare
(UNRELATED)
Tested it shortly and seem like it slower on a small data set but on a bigger ones a bit faster.
PS: Just didn't know where to put it. |
That perf table makes me wonder if we could do something like,
But I think that assumes the rows are collected which isn't always the case. |
Could be worth it if there will be real benefit (hard to tell, I guess need to run in nushell to see if there are any benefits).
Actually we DO collect rows before the printing. But we basically can't eliminate it completely. |
I'm still interested in moving forward with this as time permits. I just think it's so cool to have a closure used to help determine how to color your output. |
Thanks for the continued support. #7059 took longer than I expected but I'll get back to this. Hmm… I guess I need to rebase this commit 718ee3d onto it… seems I'd better just do that manually. Starting to think I should skip further optimisations on this until after merging, if all the table making code is being constantly moved around like this… |
agreed. i'd wait a bit for more stabilization. |
66a722b
to
ac72423
Compare
OK, I've fixed up basically all the other stuff I wanted other than optimisation (namely: closure runtime errors are now printed, examples are added to default_config.nu, a few tests were added, and StyleComputer was moved to the nu_color_config crate).
|
d3cea75
to
0c71a7e
Compare
Everything should now be ready to merge (again) (again). |
I agree 100% @webbedspace. I think we've done a miserable job with this PR, specifically around feedback to you and landing it when it was ready. I'm going to land it now. Thanks for all your support and patience. |
@webbedspace I had one more thought about this that we may have to change in a new PR. There are terminals that do not support 24-bit color, namely MacOS's terminal.app. So, things like this, might need to be ported over to indexed color. Paying attention to only the date column, this is what it looks like in WezTerm that does support 24-bit color. |
I tried this but it just returns them as light gray or default, i can't tell which.
I also tried The only other thing I can think of is adding all the xterm 256 named colors so the color resolves properly, but I'm not sure if that would work. https://www.ditig.com/256-colors-cheat-sheet https://github.com/jonasjacek/colors/blob/master/data.json Thinking through this. We'd have to allow people to say |
I actually think adding all the xterm colours would be a good idea in itself (mainly because they are already relatively well-known via CSS3). |
I agree 100%. I just figured out that nu-ansi-term supports these indexed colors as AnsiCode{ short_name: Some("red3"), long_name: "xterm_red3", code: Color::Fixed(160).prefix().to_string()}, although I haven't tested it yet. |
Doesn't the |
ugh, you're right it does. oh well, i just added them all to ansi anyway. :) Let me see if I can retrofit them into lookup_style. Thanks for the tip! |
aaaaarg! these xterm colors have duplicate names! |
# Description Follow up to #7141 to map @webbedspace's rgb colors to xterm 256 color indexes. Also added the xterm 256 named colors to `ansi --list` in the process. The few dozen or so names that were duplicate in the xterm 256 names from [here](https://www.ditig.com/256-colors-cheat-sheet) were renamed by appending a,b,c,d. So, instead of two blue3's there will be blue3a and blue3b. # User-Facing Changes More colors. # 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 -A clippy::needless_collect` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass # 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.
it's crazy how slow this is, |
It's faster if, as I said upthread, you take out |
If anyone wants to optimize regex performance in these closures (and elsewhere), there is some low-hanging fruit for optimization: nushell/crates/nu-protocol/src/value/mod.rs Lines 2626 to 2628 in 046e46b
I imagine we could do something like a global cache of compiled regexes, based on a FIFO queue. |
Description
Closes #6909. You can now add closures to your
color_config
themes. Whenever a value would be printed withtable
, the closure is run with the value piped-in. The closure must return either a {fg,bg,attr} record or a color name ('light_red'
etc.). This returned style is used to colour the value.This is entirely backwards-compatible with existing config.nu files.
Example code excerpt:
Example output with this in effect:
Slightly important notes:
null
instead of a value.string: { if $in =~ '^#\w{6}$' { $in } else { 'white' } }
for serious work, mainly because of the abundance of string-type data in the world. Nevertheless, lesser-used types like "date" and "duration" work well with this.eval_block()
that late in table rendering. I invented a new struct called "StyleComputer" which holds the engine_state and stack of the initialtable
command (implicit or explicit).compute()
method which takes a color_config name and a nu value, and always returns the correct Style, so you don't have to worry about A) the color_config value was set at all, B) whether it was set to a closure or not, or C) which default style to use in those cases.table
run, thus causing subsequent output to just be Style::default().)nu!
to take an alternative config, and for some reasonlet-env config =
statements don't seem to work insidenu!
pipelines(???)User-Facing Changes
See above.
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 --features=extra -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect
to check that you're using the standard code stylecargo test --workspace --features=extra
to check that all tests passAfter Submitting
If your PR had any user-facing changes, update the documentation after the PR is merged, if necessary. This will help us keep the docs up to date.