[I posted this on Reddit, then realized I should copy it here so it shows up on Planet Lisp.]
In a Git diff, each consecutive subsequence of lines near a difference is called a "hunk". Each hunk has a one-line header that might look something like this:
@@ -316,8 +322,9 @@ int main(int argc, char **argv)
The numbers indicate which lines of each version of the file appear in the hunk. The rest of the line is intended to be the first line of the function, class, or other top-level definition that the hunk is within. Git finds that line using a regexp corresponding to the source language. It's just to give the reader a bit more context; nothing else depends on it — or should depend on it, anyway, since it can be missing or wrong.
The regexps that tell Git how to find the header lines are called "userdiff drivers". A driver for Scheme was added a couple of years ago, but it didn't work for Common Lisp or many other Lisps, as it failed to match (defun lines, among other things. I have modified it to be more general, and the relevant changes are in the recent Git 2.55.0 release.
I was unable to persuade the Git maintainers to name the driver "lisp", however, given that one named "scheme" already exists. The argument that Lisp is the family name, and Scheme one dialect within the family, was not sufficient to overcome their resistance to having two closely related languages with separate drivers — understandable, since too lax a policy about adding drivers would surely lead to there being hundreds of them. And of course, we couldn't just rename the "scheme" driver, because people are already using it.
So that's why, starting with Git 2.55.0, the way to get correct hunk headers for code in Common Lisp, or probably almost any other dialect of Lisp, is to have a .gitattributes file containing this line:
*.lisp diff=scheme
The Scheme regexp is still there and will still match all the same constructs, but there's also now a much more general regexp that simply matches any unindented open parenthesis, or (def preceded by one or two spaces. (The latter is to catch defining forms grouped together insde a top-level form like eval-when, but without the false positives that we would get if we didn't require a name beginning with def.)
No comments:
Post a Comment