This involves a little hack to insert a lambda parameter 'x' to be used at
keyword position. If the template language were dynamically typed (and were
interpreted), .map() implementation would be simpler. I considered that, but
interpreter version has its own warts (late error reporting, uneasy to cache
static object, etc.), and I don't think the current template engine is
complex enough to rewrite from scratch.
.map() returns template, which can't be join()-ed. This will be fixed later.
@joyously found `o` confusing because it's a valid change id prefix. I
don't have much preference, but `●` seems fine. The "ascii",
"ascii-large", and "legacy" graph styles still use "o".
I didn't change `@` since it seems useful to have that match the
symbol used on the CLI. I don't think we want to have users do
something like `jj co ◎-`.
A list type isn't so useful without a map operation, but List<CommitId>
is at least printable. Maybe we can experiment with it to craft a map
operation.
If a map operation is introduced, this keyword might be replaced with
"parents.map(|commit| commit.commit_id)", where parents is of List<Commit>
type, and the .map() method will probably return List<Template>.
This eliminates ambiguous parsing between "func()" and "expr ()".
I chose "++" as template concatenation operator in case we want to add
bit-wise negate operator. It's also easier to find/replace than "~".
This is ugly, but we need a special case because root_change_id and
root_commit_id aren't equal but share the same prefix bytes. In practice,
no one would care for the shortest root id prefix, but we'll need to deal
with a similar problem when migrating prefix id resolution to repo layer.
I think the intent of '- 1' here is the separator length, which was
originally ':'. Alternatively, we can ensure that prefix + remainder is
always 12 chars.
There are several reasons for this:
* We can more easily skip styling a trailing blank line, which other
internal code then can correctly detect as having a trailing
newline. This fixes the TODO in tests/test_commit_template.rs.
* Some tools (like `less -R`) add an extra newline if the final
character is not a newline (e.g. if there's a color reset after
it), which led to an annoying blank line after the diff summary in
e.g. `jj status`.
* Since each line is styled independently, you get all the necessary
escapes even when grepping through the output.
* Some terminals extend background color to the end of the terminal
(i.e. past the newline character), which is probably not what the
user wanted.
* Some tools (like `less -R`) get confused and lose coloring of lines
after a newline.
We often end up writing escape codes for one style and then
immediately after, we write escape codes for another style. That seems
harmless, but it's a little ugly. More importantly, it prepares for
not emitting any escapes for turning off attributes at the end of
formatted contents across multiple lines (see next commit).
Let's use `crossterm` to make `ColorFormatter` a little more readable,
and maybe also more portable.
This uses the `SetForegroundColor()` function, which uses the escapes
for 256-color support (code 38) instead of the 8-color escapes (codes
30-37) combined with bold/bright (code 1) we were using before. IIUC,
most terminals support the 16 base colors when using the 256-color
escape even if they don't support all the 256 colors. It seems like an
improvement to use actual color codes for the bright colors too,
instead of assuming that terminals render bold as bright (even though
most terminals do).
Before this commit, we relied on ANSI escape 1 - which is specified to
make the font bold - to make the color brighter. That's why we call
the colors "bright blue" etc. When we switch from using code 30-37 to
using 38 to let our color config just control the color (not using
escape1), we therefore lose the bold font on many terminals (at least
in iTerm2 and in the terminal application on my Debian work
computer). As a workaround, I made us still use escape 1 when the
bright colors are used. I'll make boldness a separately configurable
attribute soon. Then we'll be able to remove this hack.
With the switch to `crossterm`, we also reset just the foreground
color (code 39) instead of resetting all attributes (code 0). That
also seems like an improvement, probably making it easier for us to
later support different background colors, underlining, etc.
An important part of the `jj log` output is the commit template. I
suspect we'll have many more tests for that, so let's move it to a
separate file. The main `test_log_command.rs` can focus on which
commits to display.