-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Make --style
parameter more flexible
#74
Conversation
617ec34
to
ee06c2e
Compare
src/main.rs
Outdated
fn from_str(s: &str) -> Result<Self> { | ||
match s { | ||
"full" => Ok(PredefinedStyle::Full), | ||
"line-numbers" => Ok(PredefinedStyle::LineNumbers), |
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.
Just a small heads-up: Do we actually need this combined/predefined style if it is equivalent to "numbers"?
(there is no need to maintain backwards-compatibility. The --style
option has not been released)
f64bb5b
to
df6ce07
Compare
I have updated the PR to work with the new From my tests this seems to work correctly, but I'd appreciate if somebody could verify this! 👍 |
src/printer.rs
Outdated
self.print_horizontal_line('┼') | ||
} else { | ||
writeln!(self.handle, "File {}", self.colors.filename.paint(filename)) | ||
.map_err(Into::into) |
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.
Is this necessary? doesn't the ?
operator suffice?
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.
Since I am returning the result here, no. It would complain about getting a Result<_, io::Error>
instead of Result<_, Error>
. I can use ?;
though and simply return Ok(())
at the end instead.
Let me know if you think that would be easier to understand!
src/printer.rs
Outdated
); | ||
|
||
// Print decorations | ||
decorations |
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.
Hmm i'm not sure why this change was made. Is this better? There are more writes and a vector that isn't being used. Also, the changes don't seem related to the rest
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.
I would assume that the write!
s would be optimized extremely well, especially since we have stdout
locked.
To me it felt wasteful allocating a Vec
for every line, when we don't even have varying amount of elements in that vector. I'm fine with going back to a Vec
on this, though.
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.
After thinking about it a bit more, I have come up with the following solution:
let line_number_output = self.print_line_number(line_number).unwrap_or("".into());
let git_marker_output = self.print_git_marker(line_number).unwrap_or("".into());
let line_border_output = self.print_line_border().unwrap_or("".into());
let line = as_terminal_escaped(
®ions,
self.options.true_color,
self.options.colored_output,
);
write!(
self.handle,
"{}{}{}{}",
line_number_output, git_marker_output, line_border_output, line
).map_err(Into::into)
What do you think about that?
@@ -417,8 +479,7 @@ fn run() -> Result<()> { | |||
.arg( | |||
Arg::with_name("style") | |||
.long("style") | |||
.possible_values(&["auto", "plain", "line-numbers", "full"]) |
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.
no more list of possible values?
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.
I have updated the handling of the comma-separated argument and could re-add the possible values! 👍
src/main.rs
Outdated
match s { | ||
"full" => Ok(PredefinedStyle::Full), | ||
"plain" => Ok(PredefinedStyle::Plain), | ||
_ => Err(ErrorKind::UnknownStyleName(s.to_owned()).into()), |
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.
Should it fail or just default to full? The other options take this more forgiving style
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.
Defaulting to full
happens in the clap-configuration: the default value for --style
is full
. Also, defaulting here would negate the selection-logic.
I'm sorry for not being too active on this pull request, but unfortunately this is quite hard to review as there are many changes that are unrelated to the actual feature. While some of these changes are really good, it would be better to split these into separate pull requests (in the future). I agree with @BrainMaestro, the parsing logic seems quite complex. Maybe things would also be simpler if we remove |
The `--style` parameter now accepts a comma-separated list of strings, where every element defines either a single output component (`changes`, `grid`, `header`, `numbers`) or a predefined style (`full`, `line-numbers`, `plain`). If available, bat picks the first predefined style in the user-supplied style-list and ignores everything else. If no predefined style was requested, the other parameters that are simple output components will be used. Examples: --style changes,full,numbers Will internally be reduced to only the predefined style `full`. --style plain,full Will internally be reduced to only the predefined style `plain`. --style changes,numbers Will not be reduced, because the list does not contain any predefined styles. (Note: if `grid` is requested but no other parameters, bat still creates the left-most column with a width of `PANEL_WIDTH`. I didn't want to introduce further logic in this PR that drops or adapts the width of the left column.)
This commit tries to simply the change. Instead of separating an `OutputComponent` and a `PredefinedStyle`, I have combined the two into just `OutputComponent`. To still have the styles work, I added an impl to `OutputComponent` with a function `components` which returns the components related to the specified component. For a simple output component this is trivial, but for the predefined styles this is a list of other components. The evaluating of the command-line parameter simplified significantly, making use of Claps `values_t!` macro to parse the supplied parameters into a `Vec<OutputComponent>`. After that it is simply a task of combining all supplied output components into one vector. Important: this means that the styles are now additive, rather than one of the predefined styles overruling other parameters supplied.
I have rebased the PR and performed a few changes:
Let me know if this change fits better, or if there are more open points! 👍 Removing the |
@@ -545,18 +598,17 @@ fn run() -> Result<()> { | |||
}) | |||
.unwrap_or_else(|| vec![None]); // read from stdin (None) if no args are given | |||
|
|||
let output_components = values_t!(app_matches.values_of("style"), OutputComponent)? |
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.
very nice 👍
src/main.rs
Outdated
let output_components = values_t!(app_matches.values_of("style"), OutputComponent)? | ||
.into_iter() | ||
.map(|style| style.components()) | ||
.fold(vec![], |mut acc, x| { |
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.
Vec::new()
would be better since it's empty right?
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.
src/printer.rs
Outdated
.output_components | ||
.contains(&OutputComponent::Grid) | ||
{ | ||
self.print_horizontal_line('┬')?; |
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.
Since this function is only relevant for grid, you could put a check in the function itself to print nothing if grid is not present. it would simplify a lot. what do you think?
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.
That depends: the way it is implemented here right now, the header can also be shown regardless of if the grid is enabled or not. I suppose this is a decision to make: do we want to display a header if the grid is not requested and if so, how should it be formatted?
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.
Sorry if I wasn't clear, I was actually specifically talking about print_horizontal_line
, but you're right about the header thing. 🤷♂️
src/printer.rs
Outdated
|
||
self.print_horizontal_line('┼') | ||
} else { | ||
writeln!( |
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.
This is not quite the same behavior. probably best to avoid the duplication
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.
True, thanks for noticing. I'll leave this unchanged for the time being until we have a decision on whether header
should have an effect without grid
.
src/printer.rs
Outdated
write!( | ||
self.handle, | ||
"{}", | ||
decorations | ||
.into_iter() | ||
.filter_map(|dec| dec) | ||
.filter_map(|dec| if grid_requested { | ||
Some(dec.unwrap_or(" ".into())) |
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.
Hmm not sure I follow
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.
In a grid we have to at least have a space for a non-existing element to have the right spacing in the left column. Unfortunately I haven't found a cleaner way to express this spacing, without going back to the multiple writes.
Nice, this is much easier to follow!
|
Agreed. I'll go back to
I was thinking about how to make this simpler. I like your suggestion and will give it a try!
Good point, I'll update that too. Thanks for the thorough reviews, by the way. I really appreciate them! |
Newest updates:
|
src/printer.rs
Outdated
Some(&LineChange::Modified) => self.colors.git_modified.paint("~"), | ||
_ => Style::default().paint(" "), | ||
} | ||
fn print_git_marker<'s>(&self, line_number: usize) -> Option<String> { |
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.
unused lifetime
src/printer.rs
Outdated
fn print_line_border(&self) -> Option<String> { | ||
if let OptionsStyle::Plain = self.options.style { | ||
return None; | ||
fn print_line_border<'s>(&self) -> Option<String> { |
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.
ditto
Awesome! You've been very patient. Thanks for that |
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.
@pitkley I really like the new changes, thank you very much!
@BrainMaestro Thank you for reviewing!
The
--style
parameter now accepts a comma-separated list of strings, where every element defines either a single output component (changes
,grid
,header
,numbers
) or a predefined style (full
,line-numbers
,plain
).If available, bat picks the first predefined style in the user-supplied style-list and ignores everything else. If no predefined style was requested, the other parameters that are simple output components will be used.
Examples:
--style changes,full,numbers
Will be reduced to only the predefined style
full
.--style plain,full
Will be reduced to only the predefined style
plain
.--style changes,numbers
Will not be reduced, because the list does not contain any predefined styles.
(Note: if
grid
is requested but no other parameters, bat still creates the left-most column with a width ofPANEL_WIDTH
. I didn't want to introduce further logic in this PR that drops or adapts the width of the left column.)(This PR supersedes #63.)