Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃殌 Support for "git grep" colorization, specifically with the -W / --function-context flag #769

Closed
zachriggle opened this issue Nov 8, 2021 · 5 comments 路 Fixed by #774

Comments

@zachriggle
Copy link

zachriggle commented Nov 8, 2021

Hey @dandavison! Thanks for making such an absolutely indispensable tool like delta!

Feature Request

delta is great for diffs (and soon blame?), but I have a suggestion* for an additional mode that might be useful to others -- the ability to syntax-highlight git grep output!

Why git grep?

I mention git grep specifically as opposed to grep / ack / ag/ pt / rg because of two extremely powerful features of git grep that the competition lack.

Boolean Expressions

First, let's look at its ability to have complex nested boolean expressions like --and --not and grouping which make git grep very powerful. For example, let's say we wanted to search for certain kmalloc invocations that also DO NOT have GFP_KERNEL or GFP_ATOMIC. Yes, you could do e.g. `grep kmalloc | grep -vE 'GFP_(KERNEL|ATOMIC)', but for the sake of demonstration...

Screen Shot 2021-11-08 at 12 06 29 PM

Full Function Context

More importantly, it also has the ability to show the entire function in which a match resides with --function-context (-W).

Note the =, :, and - markers after the line numbers, indicating lines-with-match, the function name, and context lines.

(Large screenshot warning)

Screen Shot 2021-11-08 at 12 07 34 PM

Example Output

I've jury rigged a (very ugly zsh-based) solution** that gives me effectively what I'm asking for in this feature request, but it would be better if it were directly integrated into delta (and others would also be able to benefit from this). Effectively, I parse the markers and shells out to bat to show and highlight the correct lines.

Screen Shot 2021-11-08 at 12 13 07 PM

Added Bonus Functionality!

While git grep is very powerful, if you look at the second screenshot above, you'll note that there is only ONE line matching the query -- line 1482. However, every instance of sizeof and ; etc that are in the query are also highlighted.

I'm not sure why Git does this, but by parsing out the symbols at the beginning of the line, delta could be even BETTER by not highlighting these partial-matches-in-the-same-function. Note that my example output (third screenshot) does not replicate this undesirable behavior.

Additional Niceties

For many of the default themes, the "highlight" color for bat is not ideal. I work around this by using a custom-compiled theme based off solarized-dark, to effectively achieve the same highlight color as delta uses for added (green) lines.

Hopefully this isn't an issue for delta, because you can just use the internal setting for whatever the "line added" theme color is.

Closing Remarks & Comments

Let me know what you think of the idea!

* This suggestion might belong better in the bat project, but I feel like it fits with delta better due to the useful functionality is based on Git (i.e., git grep -W and git log -p -W), delta having good support and features for lots of Git things with highlighting, and because bat is just a highlighter for languages and should probably remain pure that way.

** _Technically it's a wrapper around bat, i.e. it parses the --function-context markers. I showed the command-line that it generates in the screenshot above, for an example.

@dandavison
Copy link
Owner

dandavison commented Nov 10, 2021

Hi @zachriggle, this seems like a great idea. It's tempting to think that it shouldn't be too hard to have an initial go at, based on way the git blame handler that we already have is added. Thanks also for the detailed write-up with extra suggestions.

Would you mind expanding on this?

by parsing out the symbols at the beginning of the line

dandavison added a commit that referenced this issue Nov 11, 2021
dandavison added a commit that referenced this issue Nov 11, 2021
@dandavison
Copy link
Owner

I've made a start at this in branch 769-git-grep

dandavison added a commit that referenced this issue Nov 11, 2021
dandavison added a commit that referenced this issue Nov 11, 2021
dandavison added a commit that referenced this issue Nov 11, 2021
dandavison added a commit that referenced this issue Nov 12, 2021
dandavison added a commit that referenced this issue Nov 12, 2021
dandavison added a commit that referenced this issue Nov 12, 2021
dandavison added a commit that referenced this issue Nov 12, 2021
dandavison added a commit that referenced this issue Nov 13, 2021
dandavison added a commit that referenced this issue Nov 14, 2021
dandavison added a commit that referenced this issue Nov 14, 2021
dandavison added a commit that referenced this issue Nov 14, 2021
dandavison added a commit that referenced this issue Nov 14, 2021
dandavison added a commit that referenced this issue Nov 14, 2021
dandavison added a commit that referenced this issue Nov 14, 2021
dandavison added a commit that referenced this issue Nov 14, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 14, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 14, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 14, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 15, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 15, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 15, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 15, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 16, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
@zachriggle
Copy link
Author

To expound upon

by parsing out the symbols at the beginning of the line

Ultimately, Git internally knows when a line matches the query given to it.

Consider:

git grep --no-index -C1 -e foo --and -e bar --and -e fizz --and -e buzz file.txt

It will only return hits / "matching" lines for lines that contain ALL FOUR queries, due to --and.

However, if you use -W or --function-context, when displaying the rest of the function (or -C for contextual lines) it will use ANSI escape codes to highlight ANY match.

# file.txt
This is fizz
All four: foo bar fizz buzz
This is buzz

The middle line will have a beginning-of-line marker indicating it's a matching line.

Due to Git's incorrect behavior, it will actually highlight fizz and buzz on the first/last line, despite the line not being a full match.

I would expect any tool building on top of git grep to honor the beginning-of-line marker for this-line-is-a-match, rather than replicating git grep's incorrect behavior to

* Note: I've not actually tested the behavior with -C, but I know this occurs with -W.

@dandavison
Copy link
Owner

dandavison commented Nov 16, 2021

Thanks for that explanation @zachriggle. When you have a moment, this branch is ready for testing: #774. I believe that it implements most of what you proposed, but there's some complexity so it would be great to know how close the behavior is to what you have in mind.

I would expect any tool building on top of git grep to honor the beginning-of-line marker for this-line-is-a-match

One minor thing is that some terminal emulators recognize file.txt:7: and render it as a clickable link, but they do not do this for file.txt-7- nor for file.txt=7=. (At least, this is so for VSCode with its integrated terminal emulator). If you enable navigate, you'll see that what I've done currently is emit the -7- and =7= forms verbatim, but not when navigate is enabled, since then we have a good visual indicator of where the match lines are and so I think it's nice to have open-at-line-in-editor-on-click functionality, i.e. I change them to :7:.

dandavison added a commit that referenced this issue Nov 17, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 17, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 17, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 17, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 18, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 21, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 22, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 22, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 22, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 22, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
dandavison added a commit that referenced this issue Nov 22, 2021
- Handle standard filepath:code and filepath:line_number:code output
  as produced by `git grep`, `rg -H`, `grep -H`, etc (with -n for line
  numbers).

- Retain the match highlighting as produced by the grep tool, and
  expose it in delta's color output styled with grep-match-style.
  (Note that --color=always is needed to retain the color if piping
  into delta, but not for `git grep` when delta is configured as git's
  pager)

- Special handling of -p, and -W options of `git grep`: these display
  the function context in which the matches occur.

- `navigate` keybindings jump between match function contexts under
  `git grep -p` and between matching lines under `git grep -W`.

Thanks @zachriggle for the proposal.
Fixes #769
@dandavison
Copy link
Owner

Update: @joshtriplett solved the parse ambiguities that were afflicting git grep in #1634. The latest delta release (0.17.0) has the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants