From 51e7e463e93708a0e40688f91200e9e9869ec662 Mon Sep 17 00:00:00 2001 From: Tassilo Horn Date: Sat, 14 Mar 2015 09:27:31 +0100 Subject: [PATCH] Font-lock elisp macros/special forms dynamically * emacs-lisp/lisp-mode.el (lisp--el-macro-regexp): New defconst. (lisp--el-update-macro-regexp, lisp--el-update-after-load) (lisp--el-match-macro): New functions. (lisp-mode-variables): Update lisp--el-macro-regexp and add lisp--el-update-after-load to after-load-functions. --- lisp/ChangeLog | 8 ++++++++ lisp/emacs-lisp/lisp-mode.el | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index fb2291c534c..73ba0353d9d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,11 @@ +2015-03-15 Tassilo Horn + + * emacs-lisp/lisp-mode.el (lisp--el-macro-regexp): New defconst. + (lisp--el-update-macro-regexp, lisp--el-update-after-load) + (lisp--el-match-macro): New functions. + (lisp-mode-variables): Update lisp--el-macro-regexp and add + lisp--el-update-after-load to after-load-functions. + 2015-03-15 Daniel Colascione * emacs-lisp/cl-indent.el diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 5d912097838..b4f87fdac66 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -181,6 +181,33 @@ nil))) res)) +(defconst lisp--el-macro-regexp nil + "A regular expression matching all loaded elisp macros. +Can be updated using `lisp--el-update-macro-regexp' after new +macros were defined.") + +(defun lisp--el-update-macro-regexp () + "Update `lisp--el-update-macro-regexp' from `obarray'. +Return non-nil only if the old and new value are different." + (let ((old-regex lisp--el-macro-regexp) + (elisp-macros nil)) + (mapatoms (lambda (a) + (when (or (macrop a) (special-form-p a)) + (push (symbol-name a) elisp-macros)))) + (setq lisp--el-macro-regexp + (concat "(" (regexp-opt elisp-macros t) "\\_>")) + (not (string= old-regex lisp--el-macro-regexp)))) + +(defun lisp--el-update-after-load (_file) + "Update `lisp--el-macro-regexp' and adjust font-lock in existing buffers." + (when (lisp--el-update-macro-regexp) + (dolist (buf (buffer-list)) + (when (derived-mode-p 'emacs-lisp-mode) + (font-lock-flush))))) + +(defun lisp--el-match-macro (limit) + (re-search-forward lisp--el-macro-regexp limit t)) + (pcase-let ((`(,vdefs ,tdefs ,el-defs-re ,cl-defs-re @@ -194,7 +221,9 @@ "when" "unless" "with-output-to-string" "ignore-errors" "dotimes" "dolist" "declare")) (lisp-errs '("warn" "error" "signal")) - ;; Elisp constructs. FIXME: update dynamically from obarray. + ;; Elisp constructs. Now they are update dynamically + ;; from obarray but they are also used for setting up + ;; the keywords for Common Lisp. (el-fdefs '("define-advice" "defadvice" "defalias" "define-derived-mode" "define-minor-mode" "define-generic-mode" "define-global-minor-mode" @@ -333,7 +362,7 @@ `( ;; Regexp negated char group. ("\\[\\(\\^\\)" 1 font-lock-negation-char-face prepend) ;; Control structures. Common Lisp forms. - (,(concat "(" el-kws-re "\\_>") . 1) + (lisp--el-match-macro . 1) ;; Exit/Feature symbols as constants. (,(concat "(\\(catch\\|throw\\|featurep\\|provide\\|require\\)\\_>" "[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?") @@ -514,6 +543,9 @@ font-lock keywords will not be case sensitive." . lisp-font-lock-syntactic-face-function))) (setq-local prettify-symbols-alist lisp--prettify-symbols-alist) (when elisp + (unless lisp--el-macro-regexp + (lisp--el-update-macro-regexp)) + (add-hook 'after-load-functions #'lisp--el-update-after-load) (setq-local electric-pair-text-pairs (cons '(?\` . ?\') electric-pair-text-pairs))) (setq-local electric-pair-skip-whitespace 'chomp) -- 2.39.2