emacs-devel
[Top][All Lists]
Advanced

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

Re: find-file-noselect needs save-match-data


From: David Kastrup
Subject: Re: find-file-noselect needs save-match-data
Date: Wed, 06 Jun 2007 09:25:13 +0200
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/23.0.51 (gnu/linux)

martin rudalics <address@hidden> writes:

>> I don't understand.  In this case, `find-file-noselect' uses regexps,
>> and is placed on `post-command-hook' indirectly (I don't know whether
>> `post-command-hook' is sensitive).
>
> Every hook is sensitive.
>
>> Following your opinion, I conclude that it's type-break's
>> responsibility to know `find-file-noselect' uses regexps and so it
>> should use `save-match-data' when placing it to `post-command-hook'.
>> While the name `find-file-noselect' does not indicate it uses regexps,
>> and so does its document, it is more or less not appropriate of this
>> conclusion to me.
>
> In any case we fill the stack with unneeded match-data.

Stupid question: why does save-match-data not use (match-data t) and
thus avoid the creation of markers?

Match-data usually is _not_ adjusted for insertion/deletion in the
buffer, is it?  So it would seem rather self-defeating that

(save-match-data
  (manipulate the buffer))

will adjust the match data for insertions/deletions in the buffer
while

(manipulate the buffer)

in itself won't (assuming that it does not do any matching itself, of
course).

Try the following:

(with-temp-buffer
  (list (progn
          (insert "woozle")
          (goto-char 1)
          (search-forward "z")
          (insert-before-markers "x")
          (match-beginning 0))
        (match-end 0)
        (progn
           (goto-char 1)
           (search-forward "z")
           (save-match-data
             (insert-before-markers "x"))
           (match-beginning 0))
        (match-end 0)))

It will output (4 5 4 6).  Namely, the _expensive_ operation of
save-match-data _changes_ the outcome.

I think this is a mistake.

Here is the code:

(defmacro save-match-data (&rest body)
  "Execute the BODY forms, restoring the global value of the match data.
The value returned is the value of the last form in BODY."
  ;; It is better not to use backquote here,
  ;; because that makes a bootstrapping problem
  ;; if you need to recompile all the Lisp files using interpreted code.
  (declare (indent 0) (debug t))
  (list 'let
        '((save-match-data-internal (match-data)))
        (list 'unwind-protect
              (cons 'progn body)
              ;; It is safe to free (evaporate) markers immediately here,
              ;; as Lisp programs should not copy from save-match-data-internal.
              '(set-match-data save-match-data-internal 'evaporate))))

If we call (match-data t) here, we don't need the 'evaporate argument.
There is one potential problem: if some filter function uses
save-match-data for the _undocumented side effect_ of adjusting the
match data upon insertion, then this change will cause a change in
behavior.

So it is probably not something we want to try in the EMACS_22_BASE
branch.  But I definitely think we want it in the trunk.  It seems way
more sane, in addition to being more efficient.

-- 
David Kastrup




reply via email to

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