[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#31586: 27.0.50; `frame-title-format' doesn't save match data
From: |
Stefan Monnier |
Subject: |
bug#31586: 27.0.50; `frame-title-format' doesn't save match data |
Date: |
Sun, 27 May 2018 15:32:44 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) |
>> FWIW, I think this qualifies as a bug in query-replace: Elisp code
>> should never presume that the match-data is preserved across something
>> like sit-for, read-char, or any other function which can run process
>> filters, redisplay, timers, or contains a yield-point.
> Is this practical? We have any number of hooks, advices, and other
> means to make arbitrary Lisp run almost off any function call. Given
> that redisplay can be entered by such Lisp by calling 'redisplay' or
> 'message' or one of the other functions you mentioned, your suggestion
> would mean we need to save-match-data around any call to any
> function. That would make our code very cluttered, indeed.
That's how we've lived so far, except that the need for save-match-data
is not around "any" call, but only around "any call except for <...>"
where <...> is the set of "primitive enough" functions. The main
problem so far is that this set is not formally defined (and also that
the byte-compiler doesn't warn you if you use a function outside of this
set without wrapping with save-match-data), but other than that it works
well in practice, because in 99% there is *very* little code executed
between a regexp match and the use of the match-data.
[ Side question: while `message` does cause a form of redisplay, IIUC it
doesn't cause a *real* redisplay in the sense that it won't recompute
mode-lines, frame-titles, nor will it run jit-lock, IOW it won't run
elisp code. ]
> My POV is that using :eval is intrinsically tricky, and whoever does
> that should take the necessary precautions.
I think it would be preferable to save the match-data around the whole
redisplay than have each :eval do it.
More to the point: AFAICT in the problem at hand, between the
regexp-match and the call to buffer-substring-no-properties, process
filters can be executed, so it's not just the match data which could be
changed, but the whole buffer's contents, so save-match-data around
the :eval call will just patch over one particular instance of a more
general problem, I think.
This said, having looked at the code this time, the bug is not quite as
clear as I thought: perform-replace does already save&restore the match
data, as evidenced by:
(setq key (read-event))
;; Necessary in case something happens during
;; read-event that clobbers the match data.
(set-match-data real-match-data)
But it does it in a fairly complex way, so the exact problem is hard
to pinpoint. If someone can understand what replace-match-data really
does, maybe they can figure out the origin of the problem.
Stefan