Description
Hi Noctuid! I'm a big fan of your work. I think that evil-lispyville
and general
are excellent packages. And your dotfiles are a great example to look at. I actually agree a lot with your dotfiles readme. It should definitely be in awesome emacs configs. Actually I'll probably pull request it soon.
In your awaken.org
file you mention that you aggressively autoload functions to reduce startup time. With functions from other packages, I see how that happens using the :commands
keywords. However, for some packages I have a lot of functions that are defined by me in my big org file. If it's a just a few, using with-eval-after-load
on them (or the :config
keyword in use-package
) is fine. But what if there are a lot, like hundreds of them? If we try to use with-eval-after-load
it will likely produce a small lag when the feature is loaded because many functions are being defined. In your awaken.org
file it doesn't look like you've run into such a case yet, you only define a relatively small number of functions for each package.
The basic problem is that emacs's autoload
facility assumes you're going to use separate files for your autoloads.
There are two ways I thought of to deal with this.
- is to tangle to multiple autoload
.el
files and place calls toautoload
in the org file. (This could be automated say with a:autoload
switch in code blocks so you wouldn't actually have to create your ownautoload
calls).)
The problem is that tangling time (with a custom tangle function) increases significantly when tangling to multiple files. This potentially could be resolved if you could somehow only tangle to a file only if source blocks that tangle to it have changed, but I'm not sure how to check that.
- Use a custom autoload method powered by
with-eval-after-load
I hacked together my own autoload method. The gist is to have a list alist of (FEATURE . LOAD-FEATURE-FN)
. When you have a function you want to autoload (in this example it's an autoload adding evil integration to eshell) function:
(with-eval-after-load '+eshell-evil-autoloads
(defun my-autoload-fun ()
...))
(fset 'my-autoload-fun (alist-get '+eshell-evil=autoloads my-autoload-alist))
The call to the my-autoload-alist
will return this lambda:
(lambda (&rest args)
(interactive)
(provide 'eshell-evil-autoloads)
(funcall this-command args))
So all of the evil eshell autoloads point to the same lambda.
Of course this needs to be tidied up a bit perhaps one lambda for all interactive
functions and one lambda for all non-interactive
. Also if we only create one lambda the neither docstring will nor the arguments not be available in advance.
The big qualm I have is I'm not sure how efficient this is and whether it's worth it. I know autoload
is coded in c
which I assume was to avoid the overhead of creating these so many functions in lisp.
I'd appreciate any ideas you'd have on this.
Activity