Elisp linting options
13 Feb 2015I discovered today that I was using declare-function
in a wrong way.
So I'll share how to use it properly.
declare-function
I was just using it to shut up the byte compiler's "not known to be
defined"
warning. Turns out that it can also be used to check if the
functions actually exist in the file to which they point to. You can
use check-declare-file
to check one file, or
check-declare-directory
to recursively check the whole directory.
Here's an example output:
Warning (check-declare): helm-info.el said `Info-goto-node' was defined in info.el.gz: arglist mismatch
Warning (check-declare): helm-info.el said `Info-find-node' was defined in info.el.gz: arglist mismatch
Warning (check-declare): helm-plugin.el said `Info-goto-node' was defined in info.el.gz: arglist mismatch
Warning (check-declare): helm-plugin.el said `Info-find-node' was defined in info.el.gz: arglist mismatch
Warning (check-declare): helm-emms.el said `with-current-emms-playlist' was defined in emms.el: function not found
Warning (check-declare): projectile.el said `ggtags-ensure-project' was defined in ggtags.el: file not found
Warning (check-declare): projectile.el said `ggtags-update-tags' was defined in ggtags.el: file not found
Warning (check-declare): async-bytecomp.el said `package-desc-reqs' was defined in package.el.gz: function not found
My mistake was assuming that the FILE
argument of declare-function
was somehow related to require
. But of course it had to be simply
the name of the file that contains the said function. If the referenced file is in an external package,
e.g. (declare-function cider-repl-return "ext:cider-repl")
can be used.
checkdoc
This one is actually very useful once you embrace it. It will tsk-tsk you until all your functions are documented. And since you're already writing a docstring, might as well make it good. Sometimes this leads me to removing a function that's called only once, just so that I don't have to document it.
byte-compile-file
Leaving the obvious for last. This will speed up the code in addition to checking for errors.
In dired
you can use:
- several m (
dired-mark
) followed by B (dired-do-byte-compile
). - a single *% (
dired-mark-files-regexp
)el$
followed by B.
I even have a compile
target in lispy
's Makefile:
compile:
$(CASK) exec $(EMACS) -batch $(LOAD) -l lispy-test.el -l compile.elt
Here are the contents of compile.elt:
(require 'check-declare)
(setq check-declare-ext-errors t)
(setq files '("lispy.el"
"lispy-inline.el"
"le-clojure.el"
"le-scheme.el"
"le-lisp.el"))
(mapc #'byte-compile-file files)
(ert t)
(apply #'check-declare-files files)