[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Emacs-diffs] master 51e7e46: Font-lock elisp macros/special forms d

From: Daniel Colascione
Subject: Re: [Emacs-diffs] master 51e7e46: Font-lock elisp macros/special forms dynamically
Date: Mon, 16 Mar 2015 13:39:03 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0

On 03/16/2015 01:26 PM, Tassilo Horn wrote:
> Stefan Monnier <address@hidden> writes:
>>> using Daniel's suggestion.
>> I like the "big optimized regexp" better than the "dynamic lookup via
>> intern-soft" (should make for more efficient font-locking, tho I have
>> no idea if that really proves faster in practice and even less of an
>> idea if the difference would be measurable).
> I've tried it on the 18.000 LOC vhdl-mode.el.
> --8<---------------cut here---------------start------------->8---
> ;; That's the intern-soft variant
> (defun font-lock-benchmark ()
>   (interactive)
>   (message "Benchmark: %s"
>          (benchmark-run-compiled 30
>            (goto-char (point-min))
>            (while (lisp--el-match-keyword (point-max))))))
> (defconst macro-rx
>   (concat "(" (let (macros)
>               (mapatoms (lambda (a)
>                           (when (or (special-form-p a)
>                                     (macrop a))
>                             (push (symbol-name a) macros))))
>               (regexp-opt macros t))
>         "\\_>"))
> ;; That's the optimized-regexp variant
> (defun font-lock-benchmark2 ()
>   (interactive)
>   (message "Benchmark: %s"
>          (benchmark-run-compiled 30
>            (goto-char (point-min))
>            (while (re-search-forward macro-rx nil t)
>              (match-string 1)))))
> --8<---------------cut here---------------end--------------->8---
> Indeed, the variant with the optimized regexp is more than twice as fast
> as the intern-soft approach.  But both variants are so fast that there's
> no observable difference.
>> Also, that loses the "update existing buffers after macro definition",
>> so it's far from "clearly better" w.r.t end-user behavior (and the
>> relative simplicity advantage will probably end up vanishing if we try
>> to fill those kinds of differences).
> Yes, that's what I've said.  The reason why I haven't implemented it yet
> is that I'm not sure where to add the relevant code.  With the
> intern-soft approach, we can basically adjust fontification as soon as a
> new macro is defined or evaluated using C-c C-e because it's cheap (in
> contrast to updating existing buffers only when a file is loaded).  But
> of course if a file defines 100 macros, I don't want 100 updates of
> existing elisp buffers.
> Any suggestions how/where to update existing buffers?
> I can imagine that `defmacro' starts or resets some idle timer which
> updates existing buffers.  But having a byte-run -> lisp-mode dependency
> just seems wrong.

Isn't font-lock-flush supposed to be cheap? Running it a thousand times
on byte-run.el only takes 3ms. If that's too expensive, we can
ordinarily run font-lock-flush immediately, but during load, bind a
variable that defers the call until it's unbound. Maybe something like
this around load?

(defmacro with-deferred-emacs-lisp-fontification-updates (&rest body)
  `(let ((inhibit-emacs-lisp-fontification-update t))

>> But it's largely a question of bikeshed color, so if you all prefer the
>> intern-soft approach, go for it.
> Currently it's mostly Daniel vs. you, so let's wait for some more
> opinions.
>>>   (2) adding (declare (no-font-lock-keyword t)) to all function-like
>>>       macros we have (e.g., push, pushnew)
>> push and pushnew aren't function-like, so they *should* be highlighted
>> as keywords, I think.
> I guess they are not function-like because they deal with generalized
> variables, right?

Right. I'm okay with either opt-in or opt-out behavior. Maybe we can use
edebug specs to detect function-like macros in the absence of other

Attachment: signature.asc
Description: OpenPGP digital signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]