Matt Tucker <tuck(a)whistlingfish.net> writes:
I've been experimenting with this patch (attached to Message-ID
<30940000.983237796ï¼ benzene>), and have discovered that it slows
down beginning-of-defun considerably when used deep into a large
file. This is because the new method does a `parse-partial-sexp'
from the beginning of the file each time it's called. This is
necessary to properly deal with syntax in a file. However, a
consequence of this is a significant performance impact on such
functions as `*-indent-command' and `*-indent-exp' (to name a
couple).
...the worst thing being that these commands are not very fast to
begin with, especially in C mode.
To achieve a performance boost, the
`font-lock-fontify-syntactically- region' which I ported from GNU
Emacs uses a marker `font-lock-cache-position' and a variable
`font-lock-cache-state' to store the most recently parsed-to state
of `parse-partial-sexp'.
Aha! This is the piece of the puzzle I've always missed. Thanks for
digging it up.
Presumably `beginning-of-defun' could benefit from a similar
method.
But if I'm going to do that, it occurs to me that perhaps I should
just move the functionality into syntax.c and let everything that
calls `parse-partial-sexp' take advantage of it.
Yes, that would be great.
Presumably this would also require a way to invalidate the cached
state if an insertion/deletion is made to the buffer prior to the
cache point (somewhere in buffer.c)?
Yes. You can add such code to signal_before_change or to
signal_after_change in insdel.c.
Even smarter than hacking insdel.c, you can use the (still
undocumented, eek!) extent before/after-change-functions. It's
simple: create an extent from the beginning of the buffer to the
cached position, and set its `after-change-functions' property to a
function that invalidates the cache, and possibly detaches the extent.
You would probably want to make the extent invisible (= undetectable
by Lisp code), and reuse the same extent for the same buffer.