From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#70077: An easier way to track buffer changes Date: Sat, 30 Mar 2024 09:34:39 +0300 Message-ID: <86cyrcdy80.fsf@gnu.org> References: <86frw8ewk9.fsf@gnu.org> Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="9495"; mail-complaints-to="usenet@ciao.gmane.io" Cc: yantar92@posteo.net, 70077@debbugs.gnu.org, casouri@gmail.com, qhong@alum.mit.edu, frederic.bour@lakaban.net, joaotavora@gmail.com, mail@nicolasgoaziou.fr, acm@muc.de, stephen_leake@stephe-leake.org, alan.zimm@gmail.com, phillip.lord@russet.org.uk To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Mar 30 07:35:23 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1rqSJH-0002F3-0j for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 30 Mar 2024 07:35:23 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rqSIw-0005sG-Lp; Sat, 30 Mar 2024 02:35:02 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rqSIu-0005s3-U4 for bug-gnu-emacs@gnu.org; Sat, 30 Mar 2024 02:35:00 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rqSIu-0000WL-Hn for bug-gnu-emacs@gnu.org; Sat, 30 Mar 2024 02:35:00 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1rqSIv-0001No-KC for bug-gnu-emacs@gnu.org; Sat, 30 Mar 2024 02:35:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 30 Mar 2024 06:35:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 70077 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 70077-submit@debbugs.gnu.org id=B70077.17117805005303 (code B ref 70077); Sat, 30 Mar 2024 06:35:01 +0000 Original-Received: (at 70077) by debbugs.gnu.org; 30 Mar 2024 06:35:00 +0000 Original-Received: from localhost ([127.0.0.1]:43793 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rqSIt-0001NT-MI for submit@debbugs.gnu.org; Sat, 30 Mar 2024 02:35:00 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:56080) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rqSIr-0001Mv-1e for 70077@debbugs.gnu.org; Sat, 30 Mar 2024 02:34:58 -0400 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rqSId-0000B0-56; Sat, 30 Mar 2024 02:34:43 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=TCzeSQQItuKpPzmPouypKkrrX394edArCH9odaiuJkA=; b=cyDNHCrOXn6d WkLONLPweTEMKrvuFvB4exZjGlR+jNNNkhIBjAuOpw3wV+fx3L9f2C8q+kN6kh4TCLQbJTiPlVdFB +HhAfPh3Ch5Ri0HX4Yd8xjKDaaw7fz5mYr2uhG6V4TLV7vtGm0AdgjxOoiZF9DxSdf09dRXzgTG35 axP0saa27hOY0/oNKhSHCQwRrK8EkY8goc9eTtUENQLR+1ZmkUh8ApTD7XBgdnfFX51Id1USNcpzT mzO+odezijEpYaeChsid1UY0gL1RS6XEwA9aRgIG5GKa3gA6BM8gFVkvtXKAvmNPqyvvho2oZ42Se vE/3MCDIOQNXpUpmaip2YA==; In-Reply-To: (message from Stefan Monnier on Fri, 29 Mar 2024 14:53:41 -0400) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:282326 Archived-At: > From: Stefan Monnier > Cc: 70077@debbugs.gnu.org, mail@nicolasgoaziou.fr, yantar92@posteo.net, > acm@muc.de, joaotavora@gmail.com, alan.zimm@gmail.com, > frederic.bour@lakaban.net, phillip.lord@russet.org.uk, > stephen_leake@stephe-leake.org, casouri@gmail.com, qhong@alum.mit.edu > Date: Fri, 29 Mar 2024 14:53:41 -0400 > > > I cannot imagine how applications would use these APIs. I'm probably > > missing something, org the above documentation does. Can you show > > some real-life examples? > > Haven't written real code for it yes, no. > The best I can offer is the sample code in the file: > > (defvar my-foo--change-tracker nil) > (define-minor-mode my-foo-mode > "Fooing like there's no tomorrow." > (if (null my-foo-mode) > (when my-foo--change-tracker > (track-changes-unregister my-foo--change-tracker) > (setq my-foo--change-tracker nil)) > (unless my-foo--change-tracker > (setq my-foo--change-tracker > (track-changes-register > (lambda () > (track-changes-fetch > my-foo--change-tracker > (lambda (beg end before) > ..DO THE THING..)))))))) > > Where "DO THE THING" is run similarly to what would happen in an > `after-change-functions`, except: > > - BEFORE is a string holding the content of what was in BEG..END > instead of being limited to its length. > - It's run at most once per command, so there's no performance worries. > - It's run "outside" of the modifications themselves, > so `inhibit-modification-hooks` is nil and the code can wait, modify > the buffer, or do any kind of crazy things. Thanks. I understand the last point, but that still doesn't explain enough for me to see the light. (I've also looked at the two real-life uses you posted, and it didn't help, probably because the important ideas drowned in the sea of modifications to code I'm not familiar with well enough to understand what's important and what isn't.) If the last point, i.e. the problems caused by limitations on what can be safely done from modification hooks, is basically the main advantage, then I think I understand the rationale. Otherwise, the above looks like doing all the job in after-change-functions, and it is not clear to me how is that better, since if track-changes-fetch will fetch a series of changes, deciding how to handle them could be much harder than handling them one by one when each one happens. For example, the BEGIN..END values no longer reflect the current buffer contents, and each fetched change refers to a different content of the buffer (so the same values of BEG..END don't necessarily mean the same places in the buffer). I think the need for the eglot--virtual-pos-to-lsp-position function in one of your examples is the tip of that iceberg. Also, all of your examples seem to have the signal function just call track-changes-fetch and do almost nothing else, so I wonder why we need a separate function for that, and more specifically what would be a use case where the registered signal function does NOT call track-changes-fetch, but does something else, and track-changes-fetch is then called outside of the signal function. Finally, the doc string of track-changes-register does not describe the exact place in the buffer-change sequence where the signal function will be called, which makes it harder to reason about it. Will it be called where we now call signal_after_change or somewhere else? And how do you guarantee that the signal function will not be called again until track-changes-fetch is called?