I use Magit for almost all my interactions with Git and love it. As many have said before, Magit is invaluable and by far the best Git porcelaine I've ever used.
Of course, that doesn't mean that there is nothing to improve! At work, I merge branches on a daily basis. Thereby, I oftentimes have to resolve conflicts in code written by some colleagues. When I'm not absolutely certain that my resolution is correct, I'll drop them a mail or text message asking them to review my fix.
In order to do that quickly, it would be nice to have a short description of
the commit at point including just the most important information such as the
commit author, and a diffstat of the files touched in that commit. Of course,
all that information is accessible in the magit-revision: <project>
buffer
you get when hitting RET
or SPACE
(magit-show-commit
) on the commit but
something more condensed which doesn't pop to another buffer would be even
better.
Well, there is already such a facility: eldoc
. While it is usually used in
order to show a brief documentation for the function or variable at point in
programming mode buffers, it also works just fine in the scenario at hand.
Eldoc can be extended for a new purpose by adding a function to
eldoc-documentation-functions
. The function receives one argument, a
callback function, and in the simplest case ignores the argument, and returns
the documentation as a string directly. That's what I do here:
(defun th/magit-eldoc-for-commit (_callback)
(let ((commit (magit-commit-at-point)))
(when commit
(with-temp-buffer
(magit-git-insert "show"
"--format=format:%an <%ae>, %ar"
(format "--stat=%d" (window-width))
commit)
(goto-char (point-min))
(put-text-property (point-min)
(line-end-position)
'face 'bold)
(buffer-string)))))
So if there is a commit at point, just get the output of git show --format=format:%an <%ae>, %ar --stat=<window-width>
, add some formatting, and
return it. (magit-commit-at-point
doesn't actually require that point is on
a SHA1 commit hash; it works anywhere in a line in the "Recent commits" section
of a status buffer, or in a log buffer.)
The next step is to add this new function to eldoc-documentation-functions
buffer-locally. I do that for Magit status and log buffers like so.
(defun th/magit-eldoc-setup ()
(add-hook 'eldoc-documentation-functions
#'th/magit-eldoc-for-commit nil t)
(eldoc-mode 1))
(add-hook 'magit-status-mode-hook #'th/magit-eldoc-setup)
(add-hook 'magit-log-mode-hook #'th/magit-eldoc-setup))
Finally, we need to tell Eldoc when to show the commit description. Normally, Eldoc will do that after most motion and editing commands, however since Magit has its own navigation commands, we have to make it aware of them.
(eldoc-add-command 'magit-next-line)
(eldoc-add-command 'magit-previous-line)
That's it. And the below screenshot shows how it looks like.
Note: The code was written with and for Emacs 28 (the current Emacs master branch) where Eldoc has received a major overhaul recently. I'm not sure if some adaptions have to be made in order for the code to work on older Emacs versions. If so, feel free to drop me a mail.
EDIT 2021-06-22: Thanks to tastytea, it is now confirmed that the above doesn't work as-is for older (or actually all released) Emacs versions but the required adaptions are quite simple.
- You have to remove the
_callback
argument fromth/magit-eldoc-for-commit
. - Instead of
(add-hook 'eldoc-documentation-functions
#'th/magit-eldoc-for-commit nil t)
you have to use:
(add-function :before-until
(local 'eldoc-documentation-function)
#'th/magit-eldoc-for-commit)
Notice that it is eldoc-documentation-function
(singular, emacs < 28)
instead of eldoc-documentation-functions
(plural, emacs 28).
EDIT 2024-12-09: There's now a package implementing eldoc support for commits, see eldoc-diffstat.
Back to the blog by tags or to the overview of all posts.
Also, you can subscribe to my rss feed.