]> git.eshelyaron.com Git - emacs.git/commitdiff
Font-lock elisp macros/special forms dynamically
authorTassilo Horn <tsdh@gnu.org>
Sat, 14 Mar 2015 08:27:31 +0000 (09:27 +0100)
committerTassilo Horn <tsdh@gnu.org>
Sun, 15 Mar 2015 08:20:13 +0000 (09:20 +0100)
* 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
lisp/emacs-lisp/lisp-mode.el

index fb2291c534c942bfb14db66339f65d1ad68bbc5e..73ba0353d9d842ae32760ad2e8e5689e97b17ea4 100644 (file)
@@ -1,3 +1,11 @@
+2015-03-15  Tassilo Horn  <tsdh@gnu.org>
+
+       * 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  <dancol@dancol.org>
 
        * emacs-lisp/cl-indent.el
index 5d912097838e79b094a38cd836f531cf752a3f30..b4f87fdac66812a0b515637c82ac19fa07173558 100644 (file)
             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
                          "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"
      `( ;; 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)