I'm trying to custom color my Git.
After reading through the documentation, I've found my options I wanted to set.
Everything was working fine except the Grep.
I've realised, I haven't really used it in the past.
I wanted to set colors for it with the same palette, but I could not test some of them...
I have no idea what matchContext
and match
refer to and how they're different than matchSelected
and selected
.
matchSelected
sets a color for the actual text I searched for, while as selected
referred to the line-level(?) context of that match.
So, what is match
doing? What does matchContext
set? And where the hell is a good, detailed description for these?
Anyone?
Here's what the linked documentation says, trimmed a bit to make it all work out better:
context
non-matching text in context lines (when using -A
, -B
, or -C
)
matchContext
matching text in context lines
matchSelected
matching text in selected lines
selected
non-matching text in selected lines
(I've left out match
; we'll put that back in a moment). Let's say we run git grep findme
, just so we have a search word.
The three technical terms, such as they are, here are:
matching text: This should be pretty obvious. We're searching for the literal string findme
so this is each occurrence of that string. Color-coding the match is not as necessary for these kinds of fixed strings as it is for patterns: if we were searching for a pattern, it might be particularly useful to see just what the pattern matched.
context lines: The clue here is the mention of the three flags. You can get "before" context (-B
), "after" context (-A
), or both (-C
), which basically means that if you are searching for findme
and Git finds that, it will print out not just the line with the word findme
in it, but also some lines before and after that line.
Note that these before-and/or-after lines might not have findme
in them—but then again, they might!
selected lines: Git kind of hides what this means, but building on the above, it's fairly guess-able: we were searching for the word findme
and it occurred in some line(s). So those lines are selected, which distinguishes them from any context lines that did not have findme
in them; those lines are not selected. (But see below!)
Here's an example, in searching for the word or
. Git will color or
in red, and otherwise do no coloring, by default, so I ran:
git -c color.grep.selected=green grep -C 2 -n or
which adds line numbers as well as using selected=green
. Unfortunately I can't get StackOverflow to color code this for me, so instead I'll use bold where Git uses green, and italics where it uses red:
pfod.py-11-
pfod.py-12-This is basically a hybrid of a class and an OrderedDict,
pfod.py:13:or, sort of a data-only class. When an instance of the
pfod.py-14-class is created, all its fields are set to None if not
pfod.py-15-initialized.
Here we had two non-selected lines on either side, not in any color at all; and one selected line in the middle, with two occurrences of or
within the one selected line.
In some cases the lines that would just be context, actually have a match:
pfod.py-47- self[field] = None
pfod.py-48- if len(kwargs):
pfod.py:49: raise TypeError('unexpected kwargs %s' % kwargs.keys())
pfod.py-50- if len(args):
pfod.py:51: raise TypeError('unconsumed args %r' % tuple(args))
pfod.py-52-
pfod.py-53- def __getattr__
(self, attr):
Here we had two non-selected lines at the outer edges, then two selected lines with a non-selected line in between. This implies context lines can also be selected lines! They can have both non-matching text and matching text. There's something particularly weird about this, because if a context line has a match, it becomes a selected line—so why is there a matchContext
at all? If a context line has a match, it changes into a selected line.
Normally, setting color.grep.matchContext
never has any effect, because if there is a match within what would have been a context line, it changes into a selected line and color.grep.matchContext
no longer applies. But when using -v
everything gets swapped around. This is where the documentation defines (albeit not very well) the term selected:
-v
, --invert-match
Select non-matching lines.
That is, grep's -v
option inverts the line selection. Normally, finding a match means the line is selected, so you get selected
(default = none, but I set green
above) and matchSelected
(default = "bold red") colors. But with -v
, every line that has a match is de-selected, and only non-matching lines are selected. So now what were context lines are selected, and matching lines are de-selected. So now for matching lines we get no color again, except for the match itself, where we get any matchContext
color we set (default again "bold red"). (Of course, lines with the match only come out if you turn on context, since grep only outputs non-selected lines as context lines. You can also set color.grep.context
to get those -v
context-ized lines colorized.)
Finally:
match
matching text (same as setting matchContext
and matchSelected
)
This is just shorthand to set both. When matchContext
is useless (non--v
), it effectively works out as an alias for matchSelected
. When matchSelected
is useless (-v
), it effectively works out as an alias for matchContext
. Git uses it internally to set the "bold red" default.