From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Tassilo Horn Newsgroups: gmane.emacs.devel Subject: Re: [Emacs-diffs] master 51e7e46: Font-lock elisp macros/special forms dynamically Date: Mon, 16 Mar 2015 15:47:22 +0100 Message-ID: <871tkpov7p.fsf@gnu.org> References: <20150315082509.21193.18465@vcs.savannah.gnu.org> <55054CE9.6010702@dancol.org> <87bnjt4e00.fsf@gnu.org> <550681E3.7080407@dancol.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1426517376 28154 80.91.229.3 (16 Mar 2015 14:49:36 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 16 Mar 2015 14:49:36 +0000 (UTC) Cc: Daniel Colascione , Artur Malabarba , emacs-devel To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Mar 16 15:49:27 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1YXWK7-0001jm-CX for ged-emacs-devel@m.gmane.org; Mon, 16 Mar 2015 15:48:55 +0100 Original-Received: from localhost ([::1]:49802 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YXWJw-0007pI-QF for ged-emacs-devel@m.gmane.org; Mon, 16 Mar 2015 10:48:44 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:44814) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YXWIj-0006PS-7c for emacs-devel@gnu.org; Mon, 16 Mar 2015 10:47:33 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YXWIe-0007Wz-FB for emacs-devel@gnu.org; Mon, 16 Mar 2015 10:47:29 -0400 Original-Received: from deliver.uni-koblenz.de ([141.26.64.15]:39192) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YXWIe-0007Wr-5R for emacs-devel@gnu.org; Mon, 16 Mar 2015 10:47:24 -0400 Original-Received: from thinkpad-t440p (dhcp132.uni-koblenz.de [141.26.71.132]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by deliver.uni-koblenz.de (Postfix) with ESMTPSA id 940541A84A7; Mon, 16 Mar 2015 15:47:22 +0100 (CET) Mail-Followup-To: Stefan Monnier , Daniel Colascione , Artur Malabarba , emacs-devel In-Reply-To: (Stefan Monnier's message of "Mon, 16 Mar 2015 08:58:00 -0400") User-Agent: Gnus/5.130012 (Ma Gnus v0.12) Emacs/25.0.50 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 141.26.64.15 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:183908 Archived-At: Stefan Monnier writes: >> Instead of doing it this way, why not make a font-lock matcher that >> looks at *every* initial sexp atom, calls intern-soft on it, > > That would be a valid alternative implementation, of course. > It's not clear it would be better, OTOH. > > So until proved otherwise by a concrete problem, I think we're better > off staying with the current implementation. Here's a patch which implements your preferred opt-out variant using Daniel's suggestion. --8<---------------cut here---------------start------------->8--- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 747a1d6..78db49e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,15 @@ +2015-03-16 Tassilo Horn + + * emacs-lisp/byte-run.el (macro-declarations-alist): New + declaration no-font-lock-keyword. + + * emacs-lisp/lisp-mode.el (lisp--el-update-after-load) + (lisp--el-update-macro-regexp, lisp--el-macro-regexp): Delete + functions and defconst. + (lisp--el-match-keyword): Rename from lisp--el-match-macro. + (lisp-mode-variables): Remove code for updating/initializing + lisp--el-macro-regexp. + 2015-03-15 Michael Albinus * net/tramp-adb.el: diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index caa7e3d..ea70b11 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -151,7 +151,13 @@ This is used by `declare'.") (list 'progn :autoload-end (list 'put (list 'quote name) ''edebug-form-spec (list 'quote spec))))) - defun-declarations-alist) + (cons + (list 'no-font-lock-keyword + #'(lambda (name _args val) + (list 'progn :autoload-end + (list 'put (list 'quote name) + ''no-font-lock-keyword (list 'quote val))))) + defun-declarations-alist)) "List associating properties of macros to their macro expansion. Each element of the list takes the form (PROP FUN) where FUN is a function. For each (PROP . VALUES) in a macro's declaration, the FUN corresponding diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index b4f87fd..8039f7a 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -181,32 +181,14 @@ 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)) +(defun lisp--el-match-keyword (limit) + (catch 'found + (while (re-search-forward "(\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>" limit t) + (let ((sym (intern-soft (match-string 1)))) + (when (or (special-form-p sym) + (and (macrop sym) + (not (get sym 'no-font-lock-keyword)))) + (throw 'found t)))))) (pcase-let ((`(,vdefs ,tdefs @@ -362,7 +344,7 @@ Return non-nil only if the old and new value are different." `( ;; Regexp negated char group. ("\\[\\(\\^\\)" 1 font-lock-negation-char-face prepend) ;; Control structures. Common Lisp forms. - (lisp--el-match-macro . 1) + (lisp--el-match-keyword 1 font-lock-keyword-face) ;; Exit/Feature symbols as constants. (,(concat "(\\(catch\\|throw\\|featurep\\|provide\\|require\\)\\_>" "[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?") @@ -543,9 +525,6 @@ 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--- IMHO, it's better than the regexp-based variant because there's less and simpler code, and no refresh of the regexp is needed. I also can't see any negative point like slowness (testing with our largest elisp file, vhdl-mode.el). What the patch is still missing is (1) some code to flush font-lock in existing elisp buffers to make changes to no-font-lock-keyword declarations effective (2) adding (declare (no-font-lock-keyword t)) to all function-like macros we have (e.g., push, pushnew) Bye, Tassilo