GNU bug report logs - #20096
25.0.50; Add Font-Lock support for subr-x macros

Previous Next

Package: emacs;

Reported by: Tassilo Horn <tsdh <at> gnu.org>

Date: Thu, 12 Mar 2015 08:43:02 UTC

Severity: wishlist

Tags: fixed

Found in version 25.0.50

Fixed in version 25.1

Done: Noam Postavsky <npostavs <at> gmail.com>

Bug is archived. No further changes may be made.

Full log


Message #11 received at 20096 <at> debbugs.gnu.org (full text, mbox):

From: Tassilo Horn <tsdh <at> gnu.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 20096 <at> debbugs.gnu.org
Subject: Re: bug#20096: 25.0.50; Add Font-Lock support for subr-x macros
Date: Sat, 14 Mar 2015 09:26:21 +0100
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

>> Is committing the following change the right thing to do?
>
> On that philosophical question, I think the answer would be:
> not quite.
>
> Instead, The Right Thing to do, might be to change elisp-mode's
> font-lock rules so they check obarray for macros (i.e. use mapatoms +
> regexp-opt to generate a macro matching all macros, and probably
> update it from after-load-functions)?

I don't understant what you mean with generating a macro matching all
macros, but the attached patch uses a regexp defconst with a matcher
function for font-lock-keywords.  The regex is updated by an
after-load-function which also refreshes fontification in existing elisp
buffers.

--8<---------------cut here---------------start------------->8---
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index 5d91209..96fa403 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -181,6 +181,30 @@
             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'."
+  (let (elisp-macros)
+    (mapatoms (lambda (a)
+		(when (macrop a)
+		  (push (symbol-name a) elisp-macros))))
+    (setq lisp--el-macro-regexp
+	  (concat "(" (regexp-opt elisp-macros t) "\\_>"))))
+
+(defun lisp--el-update-after-load (_file)
+  "Update `lisp--el-macro-regexp' and adjust font-lock in existing buffers."
+  (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 +218,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 +359,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 +540,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)
--8<---------------cut here---------------end--------------->8---

Bye,
Tassilo




This bug report was last modified 6 years and 38 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.