There is a very nice minor Emacs mode for programmers: which-function-mode
. It is especially useful if you are a poor programmer who writes functions longer than 20 lines, or you use a poor programming language which makes you write such functions. (OK, it was a bad joke. OTOH, there seems to be a grain of truth in it…)
The mode puts the name of the current function in the modeline. One interesting thing about which-function-mode
is that it is based on imenu
. The comments in the source claim that this dependency should be removed. I’m not sure why: imenu
seems to be a fine tool, already capable of extracting the information about where particular functions are located in the source. One possible problem is that (probably due to imenu
dependence), which-function-mode
treats places located after a function (but not inside another one) as belonging to that function. (Also, I’m not sure what would happen in case of nested functions.) This seems not to be a deal-breaker, though.
While imenu
deserves a blog post on its own, I’d like to focus on one particular issue with which-function-mode
. While I really like the fact that it works in LaTeX files (thanks to AUCTeX’s support for imenu
), I did not appreciate that the section and subsection names had spaces in front of them. Even though it does make sense with imenu
(the indentation corresponds to the sectioning level), it looked terrible in the modeline. The remedy turned out to be straightforward, though:
(add-hook 'TeX-mode-hook '(lambda () (make-local-variable 'which-func-cleanup-function) (setq which-func-cleanup-function #'string-trim-left)))
One curious thing someone might ask is: how do I know that the function which removes leading blanks from a string is called string-trim-left
? Well, the answer is quite obvious for anyone who uses the excellent Emacs help system: apropos. It is enough to say M-x apropos RET trim RET
. Depending on your Emacs config, it may list from a couple to a dozen or so functions. (Rather surprisingly, emacs -Q
does not load subr-x
by default; I’m not sure which part of my init.el
loads it, but I’m convinced it gets loaded at some point in any practical Emacs configuration.) BTW, I didn’t use the apropos
command, but the search facility provided by Icicles. What I actually did was C-h f trim S-TAB
, but this is more or less equivalent to apropos
, only more convenient: it lets the user find the docs in less keystrokes, displays the first line of the docstring in the modeline when browsing through the items, and excludes things other than function (like variables).
One more thing which is worth remembering is that imenu
‘s “Rescan buffer” option (visible in the completion menu after pressing TAB
) is not trivial to launch programmatically. Since I could not find a way to do it, I asked a relevant question on Emacs.SE, and got two reasonable answers. (Also, I filed a bug as per Stefan’s suggestion.)