Adds a --color flag to diff(1) that supports the same options as GNU's diff(1). The colors are customizable with the env var DIFFCOLORS in a format similar to grep(1)'s GREPCOLORS. An example would be 04;36:41 for additions to be underlined light blue, and deletions have a red background.
Details
- Reviewers
pstef - Group Reviewers
Contributor Reviews (src) - Commits
- rGf38702e5a52e: diff(1): Add --color support
Diff Detail
- Repository
- rS FreeBSD src repository - subversion
- Lint
Lint Passed - Unit
No Test Coverage - Build Status
Buildable 39564 Build 36453: arc lint + arc unit
Event Timeline
I want to test this soon, but for now I'll just make a style-related note.
usr.bin/diff/diffreg.c | ||
---|---|---|
1196 | This binary operator and the few below will need spaces around it. |
Apart from inline comments I would like to ask you to consider adding at least one test case.
usr.bin/diff/diff.c | ||
---|---|---|
41 | I would move these to diff.h. | |
46 | They are all initialized to 0 anyway. | |
603 | What is the intention of this part? Would it be possible to avoid the strdup? This is not a hard requirement but maybe there's a more elegant way to do this. | |
usr.bin/diff/diffreg.c | ||
1206 | Purely for stylistic reasons I would rewrite this as \033[m |
usr.bin/diff/diff.c | ||
---|---|---|
603 | getenv(3) says: The application should not modify the string pointed to by the getenv() function. So I'm copying it, because strsep(3) modifies the string passed to it. |
usr.bin/diff/diff.c | ||
---|---|---|
602 | This is unimportant so feel free to ignore, but I would parse both substrings with strtonum() and handle possible errors. Then store that as char in del_code and add_code. That change would of course require the printfs to use %c instead of %s. | |
usr.bin/diff/diff.h | ||
94 | I asked about this before so maybe I'm wrong and they need to be defined as the same value? If so, why? |
usr.bin/diff/diff.c | ||
---|---|---|
602 | Ah, I assumed the format is as simple as "A:B" where A and B are unsigned integers, but that's not (always) the case. |
Fix COLORFLAG_* values.
Fix init_code() to return proper value.
usr.bin/diff/diff.h | ||
---|---|---|
94 | Whoops, that's a mistake, they should all be different. |
usr.bin/diff/diff.1 | ||
---|---|---|
343 | DIFFCOLOR or DIFFCOLORS? |
usr.bin/diff/diff.1 | ||
---|---|---|
343 | The format should be explained here if only shortly. I'd also make it clear that it's ok not to set it and in that case the colors will be set to default red and green. |
usr.bin/diff/diff.1 | ||
---|---|---|
341 | Should this not be .It Fl -color= for consistency? Also style for this manpage seems to be to not include the =. | |
usr.bin/diff/diff.c | ||
582 | This case is only actually use for COLORFLAG_UNSET, right? Would be clearer to have this as a case below rather than almost always override the variable and make it look like dead code. Especially if you reorder the cases below you can have this and the COLORFLAG_AUTO case share the isatty call and make it clearer when things are equivalent. | |
583 | Doesn't isatty already always return either 1 or 0? | |
592 | return (ret) is the correct style (issue repeated throughout) |
Fix return styling.
Default to never
auto only applies when COLORTERM or CLICOLOR is set (the same as ls(1)).
usr.bin/diff/diff.1 | ||
---|---|---|
341 | Optional arguments don't support arguments without a =, so removing it from the manpage wouldn't make sense. |
usr.bin/diff/diff.c | ||
---|---|---|
336–340 | I would do it like this: if (do_color()) { char *p; char const *env; color = 1; add_code = "32"; del_code = "31"; env = getenv("DIFFCOLORS"); if (env != NULL && *env != '\0' && (p = strdup(env))) { add_code = p; strsep(&p, ":"); if (p != NULL) del_code = p; } } and abandon init_code(). The function is not easy to write in a way that doesn't leak memory. | |
599 | When I commit this, I really want to do return (0) and return (1) where appropriate, instead of returning this pascal-style variable ret. |
I made some stylistic changes and rebased this patch on top of it. I also modified it to clear color (especially background color) before newlines.
Are you OK with me committing your change like this?