1

I have this in my personal spacemacs layer's packages.el:

(setq mylayer-packages
      '(general
        (mylayer :location local)
        evil-org
        ))

Then later in the same file:

(defun mylayer/post-init-evil-org ()
  (spacemacs/set-leader-keys-for-minor-mode 'evil-org-mode
    "ot" 'counsel-org-tag
    )
  (general-define-key
   :states
   '(normal)
   :keymaps 'evil-org-mode-map
   "O" 'mylayer/either-O-or-org-open-above
   "o" 'mylayer/either-o-or-insert-heading-respect-content
   )
  )

When I start spacemacs (conventionallly configured: ~/.emacs.d is a symlink to my spacemacs git repo), I get this:

An error occurred while post-configuring evil-org in layer mylayer (error: (void-function general-define-key))

general-autoloads.el is there in the package directory as I expected:

spacemacs/elpa/25.1/general-20171106.818/general-autoloads.el

I expected that emacs would have read that autoload file at startup before my layer's post-init function for evil-org was read, and that I would therefore be able to call general-define-key.

What's going on, and how can I avoid the error?

2 Answers 2

1

The problem is that spacemacs' init.el defers package activation. Package activation involves reading <package>-autoloads.el files so that e.g. the elisp for general-define-key gets loaded when it's first called (otherwise, emacs knows nothing about that function). That normally happens because emacs calls (package-initialize) automatically, unless there is a special comment in init.el. Spacemacs uses that special comment, does (setq package-enable-at-startup nil), and calls only (package-initialize 'no-activate), and then explicitly activates packages one-by-one, as a means of optimizing startup time.

It seems that if you need some package for use as a library, you must therefore arrange for it to be activated yourself.

I suspect the following is not the most "spacemacsy" answer possible: perhaps there is some way to tell spacemacs you need a library during the spacemacs startup process, in a way that's more declarative.

Until somebody points that way out, this seems to work for me (though I'll also point out that I'm not yet sure how well spacemacs and general.el will play together):

(defun mylayer/post-init-evil-org ()
  ;; here's what I added to make use of general.el work
  (package-activate 'general)
  ;; end of what I added
  (spacemacs/set-leader-keys-for-minor-mode 'evil-org-mode
    "ot" 'counsel-org-tag
    )
  (general-define-key
   :states
   '(normal)
   :keymaps 'evil-org-mode-map
   "O" 'mylayer/either-O-or-org-open-above
   "o" 'mylayer/either-o-or-insert-heading-respect-content
   )
  )
0

Nice detective work investigating Spacemacs's treatment of package-initialize! However, I believe the "spacemacsy" solution would simply be

(defun mylayer/init-general ()
  (use-package general))

If you want general to be lazy-loaded, you can probably just add :commands (general-define-key) to the use-package declaration. (Disclaimer: I have no idea how use-package interacts with "traditional" Emacs autoloads in e.g. general-autoloads.el...)

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.