From d55c7896f12a9493cc3f3460b1f14feac26a2eec Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Wed, 27 Jun 2018 18:48:01 +0200 Subject: [PATCH] Fix lazy loading of elisp-mode config elisp-mode is loaded at startup, so the usual methods won't work. Instead, we tie a transient advice to the emacs-lisp-mode function, *however*, this function is commonly called by various packages to parse elisp code! So we have to make sure the emacs lisp module only initializes the first time it is used interactively. --- modules/lang/emacs-lisp/config.el | 118 ++++++++++++++++-------------- 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/modules/lang/emacs-lisp/config.el b/modules/lang/emacs-lisp/config.el index a39f2da66..224b53944 100644 --- a/modules/lang/emacs-lisp/config.el +++ b/modules/lang/emacs-lisp/config.el @@ -2,66 +2,72 @@ (add-to-list 'auto-mode-alist '("\\.Cask\\'" . emacs-lisp-mode)) -(defun +emacs-lisp|init () - (set-repl-handler! 'emacs-lisp-mode #'+emacs-lisp/repl) - (set-eval-handler! 'emacs-lisp-mode #'+emacs-lisp-eval) - (set-lookup-handlers! 'emacs-lisp-mode :documentation 'info-lookup-symbol) - (set-docset! '(lisp-mode emacs-lisp-mode) "Emacs Lisp") - (set-pretty-symbols! 'emacs-lisp-mode :lambda "lambda") - (set-rotate-patterns! 'emacs-lisp-mode - :symbols '(("t" "nil") - ("let" "let*") - ("when" "unless") - ("append" "prepend") - ("advice-add" "advice-remove") - ("add-hook" "remove-hook") - ("add-hook!" "remove-hook!"))) +(add-hook! 'emacs-lisp-mode-hook + #'(;; 3rd-party functionality + auto-compile-on-save-mode doom|enable-delete-trailing-whitespace + ;; fontification + rainbow-delimiters-mode highlight-quoted-mode highlight-numbers-mode +emacs-lisp|extra-fontification + ;; initialization + +emacs-lisp|init-imenu +emacs-lisp|disable-flycheck-maybe)) - (add-hook! 'emacs-lisp-mode-hook - #'(;; 3rd-party functionality - auto-compile-on-save-mode doom|enable-delete-trailing-whitespace - ;; fontification - rainbow-delimiters-mode highlight-quoted-mode highlight-numbers-mode +emacs-lisp|extra-fontification - ;; initialization - +emacs-lisp|init-imenu +emacs-lisp|disable-flycheck-maybe)) +(defun +emacs-lisp|init (&rest _) + ;; Some plugins will run `emacs-lisp-mode' with `emacs-lisp-mode-hook' set to + ;; nil (cough yasnippet cough) or its mode hooks delayed. This prematurely + ;; fires this function. Most of these setters affect emacs-lisp-mode-hook, so + ;; they'd be swallowed up if it's letbound to nil, causing a half-initialized + ;; elisp-mode in some sessions. + (when (and emacs-lisp-mode-hook (not delay-mode-hooks)) + (set-repl-handler! 'emacs-lisp-mode #'+emacs-lisp/repl) + (set-eval-handler! 'emacs-lisp-mode #'+emacs-lisp-eval) + (set-lookup-handlers! 'emacs-lisp-mode :documentation 'info-lookup-symbol) + (set-docset! '(lisp-mode emacs-lisp-mode) "Emacs Lisp") + (set-pretty-symbols! 'emacs-lisp-mode :lambda "lambda") + (set-rotate-patterns! 'emacs-lisp-mode + :symbols '(("t" "nil") + ("let" "let*") + ("when" "unless") + ("append" "prepend") + ("advice-add" "advice-remove") + ("add-hook" "remove-hook") + ("add-hook!" "remove-hook!"))) + ;; + (advice-remove #'emacs-lisp-mode #'+emacs-lisp|init))) +(advice-add #'emacs-lisp-mode :before #'+emacs-lisp|init) - ;; - (defun +emacs-lisp|extra-fontification () - "Display lambda as a smybol and fontify doom module functions." - (font-lock-add-keywords - nil `(;; Highlight custom Doom cookies - ("^;;;###\\(autodef\\|if\\)[ \n]" (1 font-lock-warning-face t)) - ;; Highlight doom/module functions - ("\\(^\\|\\s-\\|,\\)(\\(\\(doom\\|\\+\\)[^) ]+\\|[^) ]+!\\)[) \n]" (2 font-lock-keyword-face))))) +(defun +emacs-lisp|extra-fontification () + "Display lambda as a smybol and fontify doom module functions." + (font-lock-add-keywords + nil `(;; Highlight custom Doom cookies + ("^;;;###\\(autodef\\|if\\)[ \n]" (1 font-lock-warning-face t)) + ;; Highlight doom/module functions + ("\\(^\\|\\s-\\|,\\)(\\(\\(doom\\|\\+\\)[^) ]+\\|[^) ]+!\\)[) \n]" (2 font-lock-keyword-face))))) - (defun +emacs-lisp|init-imenu () - "Improve imenu support with better expression regexps and Doom-specific forms." - (setq imenu-generic-expression - '(("Evil Commands" "^\\s-*(evil-define-\\(?:command\\|operator\\|motion\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1) - ("Unit tests" "^\\s-*(\\(?:ert-deftest\\|describe\\) +\"\\([^\")]+\\)\"" 1) - ("Package" "^\\s-*(\\(?:def-\\)?package! +\\(\\_<[^ ()\n]+\\_>\\)" 1) - ("Settings" "^\\s-*(def-setting! +\\([^ ()\n]+\\)" 1) - ("Major modes" "^\\s-*(define-derived-mode +\\([^ ()\n]+\\)" 1) - ("Modelines" "^\\s-*(def-modeline! +\\([^ ()\n]+\\)" 1) - ("Modeline Segments" "^\\s-*(def-modeline-segment! +\\([^ ()\n]+\\)" 1) - ("Advice" "^\\s-*(def\\(?:\\(?:ine-\\)?advice\\))") - ("Modes" "^\\s-*(define-\\(?:global\\(?:ized\\)?-minor\\|generic\\|minor\\)-mode +\\([^ ()\n]+\\)" 1) - ("Macros" "^\\s-*(\\(?:cl-\\)?def\\(?:ine-compile-macro\\|macro\\) +\\([^ )\n]+\\)" 1) - ("Inline Functions" "\\s-*(\\(?:cl-\\)?defsubst +\\([^ )\n]+\\)" 1) - ("Functions" "^\\s-*(\\(?:cl-\\)?def\\(?:un\\|un\\*\\|method\\|generic\\|-memoized!\\) +\\([^ ,)\n]+\\)" 1) - ("Variables" "^\\s-*(\\(def\\(?:c\\(?:onst\\(?:ant\\)?\\|ustom\\)\\|ine-symbol-macro\\|parameter\\)\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2) - ("Variables" "^\\s-*(defvar\\(?:-local\\)?\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)[[:space:]\n]+[^)]" 1) - ("Types" "^\\s-*(\\(cl-def\\(?:struct\\|type\\)\\|def\\(?:class\\|face\\|group\\|ine-\\(?:condition\\|error\\|widget\\)\\|package\\|struct\\|t\\(?:\\(?:hem\\|yp\\)e\\)\\)\\)\\s-+'?\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2)))) +(defun +emacs-lisp|init-imenu () + "Improve imenu support with better expression regexps and Doom-specific forms." + (setq imenu-generic-expression + '(("Evil Commands" "^\\s-*(evil-define-\\(?:command\\|operator\\|motion\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1) + ("Unit tests" "^\\s-*(\\(?:ert-deftest\\|describe\\) +\"\\([^\")]+\\)\"" 1) + ("Package" "^\\s-*(\\(?:def-\\)?package! +\\(\\_<[^ ()\n]+\\_>\\)" 1) + ("Settings" "^\\s-*(def-setting! +\\([^ ()\n]+\\)" 1) + ("Major modes" "^\\s-*(define-derived-mode +\\([^ ()\n]+\\)" 1) + ("Modelines" "^\\s-*(def-modeline! +\\([^ ()\n]+\\)" 1) + ("Modeline Segments" "^\\s-*(def-modeline-segment! +\\([^ ()\n]+\\)" 1) + ("Advice" "^\\s-*(def\\(?:\\(?:ine-\\)?advice\\))") + ("Modes" "^\\s-*(define-\\(?:global\\(?:ized\\)?-minor\\|generic\\|minor\\)-mode +\\([^ ()\n]+\\)" 1) + ("Macros" "^\\s-*(\\(?:cl-\\)?def\\(?:ine-compile-macro\\|macro\\) +\\([^ )\n]+\\)" 1) + ("Inline Functions" "\\s-*(\\(?:cl-\\)?defsubst +\\([^ )\n]+\\)" 1) + ("Functions" "^\\s-*(\\(?:cl-\\)?def\\(?:un\\|un\\*\\|method\\|generic\\|-memoized!\\) +\\([^ ,)\n]+\\)" 1) + ("Variables" "^\\s-*(\\(def\\(?:c\\(?:onst\\(?:ant\\)?\\|ustom\\)\\|ine-symbol-macro\\|parameter\\)\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2) + ("Variables" "^\\s-*(defvar\\(?:-local\\)?\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)[[:space:]\n]+[^)]" 1) + ("Types" "^\\s-*(\\(cl-def\\(?:struct\\|type\\)\\|def\\(?:class\\|face\\|group\\|ine-\\(?:condition\\|error\\|widget\\)\\|package\\|struct\\|t\\(?:\\(?:hem\\|yp\\)e\\)\\)\\)\\s-+'?\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2)))) - (defun +emacs-lisp|disable-flycheck-maybe () - "Disable flycheck-mode if in emacs.d." - (when (or (not buffer-file-name) - (cl-loop for dir in (list doom-emacs-dir doom-private-dir) - if (file-in-directory-p buffer-file-name dir) - return t)) - (flycheck-mode -1)))) - -(add-transient-hook! 'emacs-lisp-mode (+emacs-lisp|init)) +(defun +emacs-lisp|disable-flycheck-maybe () + "Disable flycheck-mode if in emacs.d." + (when (or (not buffer-file-name) + (cl-loop for dir in (list doom-emacs-dir doom-private-dir) + if (file-in-directory-p buffer-file-name dir) + return t)) + (flycheck-mode -1))) ;;