From: Stefan Monnier via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Eli Zaretskii <eliz@gnu.org>
Cc: acm@muc.de, yantar92@posteo.net, 70077@debbugs.gnu.org
Subject: bug#70077: An easier way to track buffer changes
Date: Tue, 09 Apr 2024 19:30:17 -0400 [thread overview]
Message-ID: <jwvedbe6z7e.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <865xwrxk88.fsf@gnu.org> (Eli Zaretskii's message of "Tue, 09 Apr 2024 06:56:07 +0300")
>> +Using @code{before-change-functions} and @code{after-change-functions}
>> +can be difficult in practice because of a number of pitfalls, such as
>> +the fact that the two calls are not always properly paired, or some
>> +calls may be missing, either because of bugs in the C code or because of
>> +inappropriate use of @code{inhibit-modification-hooks}.
>
> I don't think we should talk about bugs in C code in the manual, at
> least not so explicitly. I would rephrase
>
> the fact that the two calls are not always properly paired, or some
> calls may be missing, either because some Emacs primitives cannot
> properly pair them or because of incorrect use of
> @code{inhibit-modification-hooks}.
Thanks.
>> +@code{track-changes-register}, passing it a @var{signal} function as
>> +argument. This will return a tracker @var{id} which is used to identify
>> +your tracker to the other functions of the library. The other main
>> +function of the library is @code{track-changes-fetch} which lets you
>> +fetch the changes you have not yet processed.
>
> The last sentence is redundant, since you are about to describe
> track-changes-fetch shortly.
Good point.
>> +When the buffer is modified, the library will call the @var{signal}
>> +function to inform you of that change and will immediately start
>> +accumulating subsequent changes into a single combined change.
>> +The @var{signal} function serves only to warn that a modification
>> +occurred but does not receive a description of the change. Also the
>> +library will not call it again until after you processed
>> +the change.
>
> The last sentence should IMO say "...until after you retrieved the
> change by calling @code{track-changes-fetch}." The important part
> here is to say what "process" means in practice, instead of leaving it
> unsaid.
But then we get:
...until after you retrieved the
change by calling @code{track-changes-fetch}.
To process changes, you need to call @code{track-changes-fetch}, ...
which again is kind of redundant/heavy.
I went with:
To start tracking changes, you have to call
@code{track-changes-register}, passing it a @var{signal} function as
argument. This returns a tracker @var{id} which is used to
identify your change tracker to the other functions of the library.
When the buffer is modified, the library calls the @var{signal}
function to inform you of that change and immediately starts
accumulating subsequent changes into a single combined change.
The @var{signal} function serves only to warn that a modification
occurred but does not receive a description of the change. Also the
library will not call it again until after you retrieved the change.
To retrieve changes, you need to call @code{track-changes-fetch},
which provides you with the bounds of the changes accumulated
since the last call, as well as the previous content of that region.
It also ``re-arms'' the @var{signal} function so that the
library will call it again after the next buffer modification.
[ Where I also switched to the present tense. Not sure why I used the
future tense. ]
>> +@defun track-changes-register signal &key nobefore disjoint immediate
>> +This function creates a new @emph{tracker}. Trackers are kept abstract,
>
> I suggest to use "change tracker" instead of just "tracker". On my
> daytime job, "tracker" has a very different meaning, so I stumble each
> time I see this used like that.
>
> Also, I suggest to use @dfn for its markup (and add a @cindex for it
> for good measure).
I turned some uses of "tracker" into "change tracker" and I think it's
indeed an improvement. I tried to do it more systematically but with
all the "track-changes" and "change trackers" I started to feel like I was
writing a tongue twister.
>> +By default, the call to the @var{signal} function does not happen
>> +immediately, but is instead postponed with a 0 seconds timer.
> ^^^^^^^^^^^^^^^
> A cross-reference to where timers are described is in order there.
Thanks.
>> +usually desired to make sure the @var{signal} function is not called too
>> +frequently and runs in a permissive context, freeing the client from
>> +performance concerns or worries about which operations might be
>> +problematic. If a client wants to have more control, they can provide
>> +a non-nil value as the @var{immediate} argument in which case the
> ^^^
> @code{nil}
Duh.
>> +Once @var{func} finishes, @code{track-changes-fetch} re-enables the
>> +@var{signal} function so that it will be called the next time a change
>> +occurs. This is the reason why it calls @var{func} instead of returning
>> +a description: it makes sure that the @var{signal} function will not be
>> +called while you're still processing past changes.
>
> I think there's a subtler issue here that needs to be described
> explicitly: if the entire processing of the change is not done inside
> FUNC, there's no guarantee that by the time some other function
> processes it, the change is still valid and in particular SIGNAL will
> not have been called again. This is not a trivial aspect, since a
> program can use FUNC to do just some partial processing, like squirrel
> the changes to some buffer for later processing.
I tried to be more explicit about that as follows:
Once @var{func} finishes, @code{track-changes-fetch} re-enables the
@var{signal} function so that it will be called the next time a change
occurs. This is the reason why it calls @var{func} instead of returning
a description: it lets you process the change without worrying about the
risk that the @var{signal} function gets triggered in the middle of it,
because the @var{signal} is re-enabled only after @var{func} finishes.
Note that calling SIGNAL before the change is "processed" is not
necessarily a problem. E.g. Eglot does exactly that: its FUNC just
turns the NEWBEG/NEWEND/BEFORE into something like OLDBEG/OLDEND/AFTER
and pushes it on a list for later processing, it then waits for more
changes to come before later sending them to the server.
>> * New Modes and Packages in Emacs 30.1
>> +** New package Track-Changes.
> This should be marked with "+++".
Thanks.
>> No, what it's saying is that these slots can contain values of any type
>> (since any type is a subtype of t).
>> This `Type` information is a way to document what kind of values can be
>> found in those slots. Very often we don't bother specifying it, in
>> which case `t` is used as a default.
> Then maybe show "Any" or even "N/A". t is simply not informative at
> all. Actually, it is counter-productive: it makes a simple issue look
> complex and strange.
OK, I just used the empty string.
Stefan
next prev parent reply other threads:[~2024-04-09 23:30 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-29 16:15 bug#70077: An easier way to track buffer changes Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-29 18:12 ` Eli Zaretskii
2024-03-29 18:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-30 6:34 ` Eli Zaretskii
2024-03-30 14:58 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-30 16:45 ` Eli Zaretskii
2024-03-31 2:57 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-01 11:53 ` Ihor Radchenko
2024-04-01 14:51 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-01 17:49 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-02 14:22 ` Ihor Radchenko
2024-04-02 15:17 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-02 16:21 ` Ihor Radchenko
2024-04-02 17:51 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-03 12:34 ` Ihor Radchenko
2024-04-03 12:45 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-04 17:58 ` Ihor Radchenko
2024-03-30 3:17 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-30 5:09 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-29 22:20 ` phillip.lord
2024-03-29 22:59 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-30 6:46 ` Eli Zaretskii
2024-03-30 12:06 ` phillip.lord
2024-03-30 13:39 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-30 9:51 ` Ihor Radchenko
2024-03-30 12:49 ` Eli Zaretskii
2024-03-30 13:19 ` Ihor Radchenko
2024-03-30 13:31 ` Eli Zaretskii
2024-03-30 14:09 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-05 22:12 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-06 8:43 ` Eli Zaretskii
2024-04-08 15:24 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-08 15:53 ` Eli Zaretskii
2024-04-08 17:17 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-08 17:27 ` Andrea Corallo
2024-04-08 18:36 ` Eli Zaretskii
2024-04-08 20:57 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-09 4:10 ` Eli Zaretskii
2024-04-08 20:45 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-09 3:56 ` Eli Zaretskii
2024-04-09 23:30 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2024-04-13 13:44 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-06 17:37 ` Dmitry Gutov
2024-04-06 19:44 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-07 14:40 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-07 15:47 ` Dmitry Gutov
2024-04-07 14:07 ` Ihor Radchenko
2024-04-08 16:06 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-09 17:35 ` Ihor Radchenko
2024-04-10 2:02 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=jwvedbe6z7e.fsf-monnier+emacs@gnu.org \
--to=bug-gnu-emacs@gnu.org \
--cc=70077@debbugs.gnu.org \
--cc=acm@muc.de \
--cc=eliz@gnu.org \
--cc=monnier@iro.umontreal.ca \
--cc=yantar92@posteo.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).