unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
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






  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).