From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Mauro Aranda Newsgroups: gmane.emacs.bugs Subject: bug#18: Fine-grained revert-buffer Date: Sat, 27 Apr 2019 12:10:45 -0300 Message-ID: References: <83d0l7x5og.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="00000000000070ad630587847540" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="158018"; mail-complaints-to="usenet@blaine.gmane.org" To: 18@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Apr 27 17:12:18 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hKOzw-000exg-3p for geb-bug-gnu-emacs@m.gmane.org; Sat, 27 Apr 2019 17:12:16 +0200 Original-Received: from localhost ([127.0.0.1]:33165 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hKOzv-0006bq-2N for geb-bug-gnu-emacs@m.gmane.org; Sat, 27 Apr 2019 11:12:15 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:49168) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hKOzk-0006bZ-A3 for bug-gnu-emacs@gnu.org; Sat, 27 Apr 2019 11:12:05 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hKOzi-0006wl-Hs for bug-gnu-emacs@gnu.org; Sat, 27 Apr 2019 11:12:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:50430) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hKOzi-0006wK-EU for bug-gnu-emacs@gnu.org; Sat, 27 Apr 2019 11:12:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1hKOzi-0005UA-3H for bug-gnu-emacs@gnu.org; Sat, 27 Apr 2019 11:12:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Mauro Aranda Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 27 Apr 2019 15:12:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 18 X-GNU-PR-Package: emacs Original-Received: via spool by 18-submit@debbugs.gnu.org id=B18.155637786821017 (code B ref 18); Sat, 27 Apr 2019 15:12:02 +0000 Original-Received: (at 18) by debbugs.gnu.org; 27 Apr 2019 15:11:08 +0000 Original-Received: from localhost ([127.0.0.1]:35740 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hKOyp-0005Su-KQ for submit@debbugs.gnu.org; Sat, 27 Apr 2019 11:11:08 -0400 Original-Received: from mail-lj1-f194.google.com ([209.85.208.194]:40300) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hKOyn-0005SN-HR for 18@debbugs.gnu.org; Sat, 27 Apr 2019 11:11:06 -0400 Original-Received: by mail-lj1-f194.google.com with SMTP id t10so4499998ljg.7 for <18@debbugs.gnu.org>; Sat, 27 Apr 2019 08:11:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=QfL3kGEYKhPz8FNxU45ziYpeUQ9dYdQWQ+vjNYll7EY=; b=raYt+d07lWwIMC21Z9Jv/LutFXSoE0DtSnhRJb+s+DEYsd62/BkO5boZ0zffoFvm0j 0SuqDSq7UCLL65iyryjolu0D67XrSP1w49H8VHgZpuGeH0524VA5wrz0m1sijoVjpVhV vIsJntYof+xqYZHFhkCC21v4MIAHYptaDKLeqi6k2M2NDtUnXbq2dpoYI2Q1p6ap/Yyt bC7hKTNMblYJDkd6Ebu9kCDmvGfm1TnXcDmxjv+X5lsGPY3qKGEwqY7Q7sQRG/aD91nU x485lDOJ72/mfKEwpG4ohJqi3z3VBzTtfKoLSwJ2j8Vnir0d6cl46h71P8fKTXlJtoKj kc2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=QfL3kGEYKhPz8FNxU45ziYpeUQ9dYdQWQ+vjNYll7EY=; b=K7Ai2dgQC/ljfnnVH94ahJRqcQwmReT3X78OljKZrfE9qVGtkXNTAiZKvwuA1Jk3+b qRZQYwbOJ3fuaNe+OftxLHPXuwCiLBVfitWE3pFYqfTr9kpta5NspryYrO1undUkbRcK kNPASq/3YtyKJlT3Ko2aszMsQUwBiCozIX9+NRAXiBT+JsB0M/fTra4mQSDAknnhEGrL 0F54/5L7uNASY+78/FF/ge2Zn7IYzV2fBVwOWkaZSHpAxQDyK4MRtSGBuF5DeMa3Y163 p6/utoso8j029vyKqy7JAC2KUyY/zFL1FQgw3MlGCa/92CFvGHVXOD0XSHnoGpk6al9P giZQ== X-Gm-Message-State: APjAAAVP+1bXjHReWmuCGR3k6j3UHeOiY++Yi+7gz/3tTDKi8OmXsEz7 dTHNGitSKfJGyRl+fVCOtjWYMxMBOS07RjhMzrAIR7Mi X-Google-Smtp-Source: APXvYqzk0ofMV8tr4jrzSN/RcS1nQDooLBBOvCD1rL6j4bGk54beA4Pxz9pkpsNH248CY7+nr05EqmsJnTLhQT9fxjU= X-Received: by 2002:a2e:1f02:: with SMTP id f2mr2125707ljf.86.1556377859303; Sat, 27 Apr 2019 08:10:59 -0700 (PDT) In-Reply-To: <83d0l7x5og.fsf@gnu.org> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 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.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:158354 Archived-At: --00000000000070ad630587847540 Content-Type: text/plain; charset="UTF-8" Eli and Martin, thanks for your answers. Eli Zaretskii writes: > Please take a look at replace-buffer-contents, which is new with Emacs > 26. It might allow you to implement this functionality in a much > simpler way, as it already contains an internal implementation of a > Diff-like comparison algorithm, and doesn't require the Diff program > to be installed. I didn't know of replace-buffer-contents, so I took a look at it. Nice that its documentation even mentions the problem when a marker is inside a hunk, because of the delete + insert thing (just like Martin mentions). IMO, it does most of the things required, but here is one problem I notice with respect to the expected functionality of revert-buffer-by-hunks (as I've understood it): It only calls Fundo_boundary before starting the whole set of modifications, and thus after replacing the contents (in my tests, the whole buffer), a single C-/ brings all the changes back, much like revert-buffer. And since it binds inhibit-modification-hooks to t, I think I can't bind locally after-change-functions to an expression that calls undo-boundary, to do the trick. Perhaps an optional call to Fundo_boundary in the while loop could be enough, but I'm not sure how much it will impact on the speed of replace-buffer-contents. Or more, if it is justified to add that call. Please, point out to me if I'm not seeing this right. Other than that, it looks like a perfect candidate to use (at least to me) to get the functionality wanted. > One caveat: replace-buffer-contents can be very slow when the buffer > is large and reverting it requires a large number of small changes. > It will fall back to a simpler algorithm for large numbers of changes, > and could give up entirely if making the changes takes too much time, > see its doc string. Perhaps in those cases we should fall back to a > different code, like the one you wrote. > Did you time your code? How long does it take to revert buffers of > different sizes with different amounts of changes? I haven't timed it yet. I didn't know if it would be considered good enough, to time it. For a week, I've been testing it manually with some of the changes in the Emacs sources, and the experience has been satisfactory. Are there, by any chance, such tests for replace-buffer-contents? I could use them, for comparison purposes. I will try in the following days to define some parameters (such as buffer size), and time revert-buffer-by-hunks, to provide some numbers. Provided it is fast enough, I think something like replacing by hunks a region would be a good fallback to replace-buffer-contents. I sure hope so. >> a) What variables would you think should be customizable? > > The name of the Diff command should be customizable. Or maybe just > use diff-command already provided by diff.el. Same with Diff > switches. I agree. If using diff.el, it makes total sense to use those variables. Of course, that means the patch-buffer function should be modified to work on the different diff output formats (I think --context and --unified should be enough). For the record, I don't propose to use diff-apply-hunk and other diff-mode.el functions, because when I used that, I ended up with markers at (point-min), I don't know why. But if it is desired to reuse those functions instead of repeating code, I think I will need time (and help, perhaps), to understand why that happened. martin rudalics writes: > What we probably need is an extra step to scan the buffer for markers > and save their textual context before reverting and a step to restore > them according to their textual context after reverting. But if your When I bumped into the problem of the marker being sent to the beginning of the hunk, I started looking for something to get the markers of the buffer, but didn't found anything at the Lisp level. > method allows to easily determine which hunks remain unchanged, we > could avoid such textual search for markers in unchanged hunks and, > depending on the approach used for replacing text, simply restore > these markers from their offsets from the beginning of the hunk they > belong to. Yes, I believe that by getting the diff output and with the line-offset handling in the patch-buffer function, it would be easy to determine the unchanged regions. Thanks again to both of you. Best regards, Mauro. --00000000000070ad630587847540 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Eli and Martin, thanks f= or your answers.

Eli Zaretskii <e= liz@gnu.org> writes:

> Please take a look at replace-buffe= r-contents, which is new with Emacs
> 26.=C2=A0 It might allow you to= implement this functionality in a much
> simpler way, as it already = contains an internal implementation of a
> Diff-like comparison algor= ithm, and doesn't require the Diff program
> to be installed.
=
I didn't know of replace-buffer-contents, so I took a look at it.= =C2=A0 Nice
that its documentation even mentions the problem when a mark= er is
inside a hunk, because of the delete + insert thing (just like Mar= tin
mentions).=C2=A0 IMO, it does most of the things required, but here = is one
problem I notice with respect to the expected functionality ofrevert-buffer-by-hunks (as I've understood it):

It only calls F= undo_boundary before starting the whole set of
modifications, and thus a= fter replacing the contents (in my tests, the
whole buffer), a single C-= / brings all the changes back, much like
revert-buffer.=C2=A0 And since = it binds inhibit-modification-hooks to t, I
think I can't bind local= ly after-change-functions to an expression that
calls undo-boundary, to = do the trick.

Perhaps an optional call to Fundo_boundary in the whil= e loop could be
enough, but I'm not sure how much it will impact on = the speed of
replace-buffer-contents.=C2=A0 Or more, if it is justified = to add that call.
Please, point out to me if I'm not seeing this rig= ht.

Other than that, it looks like a perfect candidate to use (at le= ast to me)
to get the functionality wanted.

&g= t; One caveat: replace-buffer-contents can be very slow when the buffer
= > is large and reverting it requires a large number of small changes.> It will fall back to a simpler algorithm for large numbers of changes= ,
> and could give up entirely if making the changes takes too much t= ime,
> see its doc string.=C2=A0 Perhaps in those cases we should fal= l back to a
> different code, like the one you wrote.

> Did= you time your code?=C2=A0 How long does it take to revert buffers of
&g= t; different sizes with different amounts of changes?

I haven't = timed it yet.=C2=A0 I didn't know if it would be considered good
eno= ugh, to time it.=C2=A0 For a week, I've been testing it manually with s= ome
of the changes in the Emacs sources, and the experience has been satisfactory.=C2=A0 Are there, by any chance, such tests for
replace-bu= ffer-contents?=C2=A0 I could use them, for comparison purposes.
I will t= ry in the following days to define some parameters (such as
buffer size)= , and time revert-buffer-by-hunks, to provide some numbers.

Provided= it is fast enough, I think something like replacing by hunks a
region w= ould be a good fallback to replace-buffer-contents.=C2=A0 I sure hope
so= .

>> a) What variables would you think should be customizable?=
>
> The name of the Diff command should be customizable.=C2=A0= Or maybe just
> use diff-command already provided by diff.el.=C2=A0 = Same with Diff
> switches.

I agree.=C2=A0 If using diff.el, it= makes total sense to use those
variables.=C2=A0 Of course, that means t= he patch-buffer function should
be modified to work on the different dif= f output formats (I think --context
and --unified sho= uld be enough).=C2=A0 For the record, I don't propose to use
= diff-apply-hunk and other diff-mode.el functions, because when I used
=
that, I ended up with markers at (point-min), I don't know why.=C2= =A0 But if
it is desired to reuse those functions instead of repe= ating code, I
think I will need time (and help, perhaps), to unde= rstand why that
happened.


martin rudalics <rudalics@gmx.at> writes:

> What we pr= obably need is an extra step to scan the buffer for markers
> and sav= e their textual context before reverting and a step to restore
> them= according to their textual context after reverting.=C2=A0 But if your
<= br>When I bumped into the problem of the marker being sent to the
beginn= ing of the hunk, I started looking for something to get the
markers of t= he buffer, but didn't found anything at the Lisp level.

> met= hod allows to easily determine which hunks remain unchanged, we
> cou= ld avoid such textual search for markers in unchanged hunks and,
> de= pending on the approach used for replacing text, simply restore
> the= se markers from their offsets from the beginning of the hunk they
> b= elong to.

Yes, I believe that by getting the diff output and with th= e line-offset
handling in the patch-buffer function, it would be easy to= determine the
unchanged regions.


Thanks again to both of you.

=
Best regards,
Mauro.

--00000000000070ad630587847540--