* Editing change groups
@ 2018-11-09 7:52 Michael Heerdegen
2018-11-09 8:39 ` Joost Kremers
` (3 more replies)
0 siblings, 4 replies; 16+ messages in thread
From: Michael Heerdegen @ 2018-11-09 7:52 UTC (permalink / raw)
To: Emacs mailing list
Hello,
I have the following requirement for a user interface: if the user hits
a key, something in the buffer is replaced with something else. Doing
this potentially involves several editing operations. If the user hits
the same key again, the old contents are restored.
My question is: are change groups, as described in (info "(elisp) Atomic
Changes"), a suitable tool to do this? AFAIK it works, but I must admit
I don't understand the implementation of change groups. I tried to use
an example like
(defun my-test-change-groups ()
(interactive)
(insert "0\n")
(let ((g (prepare-change-group)))
(insert "a\n")
(activate-change-group g)
(insert "b\n")
(insert "c\n")
(cancel-change-group g)))
to see how things work but that doesn't work as I expected: calling the
command leaves all insertions intact as if the change group G hadn't
been canceled. OTOH, if I remove the first insertion (insert "0\n")
from the example, calling the function causes nothing to be inserted at
all.
Seems I'm missing something?
Thanks,
Michael.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-09 7:52 Editing change groups Michael Heerdegen
@ 2018-11-09 8:39 ` Joost Kremers
2018-11-09 11:58 ` Noam Postavsky
` (2 subsequent siblings)
3 siblings, 0 replies; 16+ messages in thread
From: Joost Kremers @ 2018-11-09 8:39 UTC (permalink / raw)
To: Michael Heerdegen
On Fri, Nov 09, 2018 at 08:52:16AM +0100, Michael Heerdegen wrote:
> Hello,
>
> I have the following requirement for a user interface: if the user hits
> a key, something in the buffer is replaced with something else. Doing
> this potentially involves several editing operations. If the user hits
> the same key again, the old contents are restored.
>
> My question is: are change groups, as described in (info "(elisp) Atomic
> Changes"), a suitable tool to do this?
From the description in the manual, it would seem they're not: you can only finish the change group once, so once the change has been accepted (and becomes visible for the user), they cannot be undone as a group.
The purpose of atomic change groups seems to be to make changes that can be undone as a group when an error occurs *while the changes are being made*. You want to be able for a group of editing operations to be undone as a group.
> AFAIK it works, but I must admit
> I don't understand the implementation of change groups. I tried to use
> an example like
>
> (defun my-test-change-groups ()
> (interactive)
> (insert "0\n")
> (let ((g (prepare-change-group)))
> (insert "a\n")
> (activate-change-group g)
> (insert "b\n")
> (insert "c\n")
> (cancel-change-group g)))
>
> to see how things work but that doesn't work as I expected: calling the
> command leaves all insertions intact as if the change group G hadn't
> been canceled.
That's something I cannot make sense of. Looks like a bug, though might very well not be.
> OTOH, if I remove the first insertion (insert "0\n")
> from the example, calling the function causes nothing to be inserted at
> all.
Because the change group is being undone. ;-) Try adding an insert after the cancel-change-group:
```
(defun my-test-change-groups ()
(interactive)
(let ((g (prepare-change-group)))
(insert "a\n")
(activate-change-group g)
(insert "b\n")
(insert "c\n")
(cancel-change-group g)
(insert "d\n")))
```
You'll see "d" inserted in the buffer.
--
Joost Kremers
Life has its moments
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
[not found] <mailman.3697.1541749970.1284.help-gnu-emacs@gnu.org>
@ 2018-11-09 11:41 ` Ben Bacarisse
2018-11-09 12:10 ` Michael Heerdegen
[not found] ` <mailman.3721.1541765458.1284.help-gnu-emacs@gnu.org>
0 siblings, 2 replies; 16+ messages in thread
From: Ben Bacarisse @ 2018-11-09 11:41 UTC (permalink / raw)
To: help-gnu-emacs
Michael Heerdegen <michael_heerdegen@web.de> writes:
> I have the following requirement for a user interface: if the user hits
> a key, something in the buffer is replaced with something else. Doing
> this potentially involves several editing operations. If the user hits
> the same key again, the old contents are restored.
Would fiddling with the undo mechanism not be a better way to do this?
https://www.gnu.org/software/emacs/manual/html_node/elisp/Undo.html
I've never tried to do what you ask this way (so I'm, just speculating)
but it looks like one place to start.
--
Ben.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-09 7:52 Editing change groups Michael Heerdegen
2018-11-09 8:39 ` Joost Kremers
@ 2018-11-09 11:58 ` Noam Postavsky
2018-11-09 12:39 ` Michael Heerdegen
2018-11-09 13:12 ` Michael Heerdegen
2018-11-09 13:52 ` Stefan Monnier
3 siblings, 1 reply; 16+ messages in thread
From: Noam Postavsky @ 2018-11-09 11:58 UTC (permalink / raw)
To: Michael Heerdegen; +Cc: Help Gnu Emacs mailing list
On Fri, 9 Nov 2018 at 02:53, Michael Heerdegen <michael_heerdegen@web.de> wrote:
> I have the following requirement for a user interface: if the user hits
> a key, something in the buffer is replaced with something else. Doing
> this potentially involves several editing operations. If the user hits
> the same key again, the old contents are restored.
Possible alternative approach with prior art in string-rectangle: fake
the change with overlays for preview, then it's easy to remove.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-09 11:41 ` Ben Bacarisse
@ 2018-11-09 12:10 ` Michael Heerdegen
[not found] ` <mailman.3721.1541765458.1284.help-gnu-emacs@gnu.org>
1 sibling, 0 replies; 16+ messages in thread
From: Michael Heerdegen @ 2018-11-09 12:10 UTC (permalink / raw)
To: Ben Bacarisse; +Cc: help-gnu-emacs
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Would fiddling with the undo mechanism not be a better way to do this?
Well, since it's my program that changes the buffer, I can't just call
`undo', which is a user command. Change groups look like the right tool
because they seem to implement exact that fiddling with the undo
mechanism that I need.
Michael.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-09 11:58 ` Noam Postavsky
@ 2018-11-09 12:39 ` Michael Heerdegen
2018-11-09 13:14 ` Eli Zaretskii
0 siblings, 1 reply; 16+ messages in thread
From: Michael Heerdegen @ 2018-11-09 12:39 UTC (permalink / raw)
To: Noam Postavsky; +Cc: Help Gnu Emacs mailing list
Noam Postavsky <npostavs@gmail.com> writes:
> Possible alternative approach with prior art in string-rectangle: fake
> the change with overlays for preview, then it's easy to remove.
Hmm - does that mean you also don't know how these change groups work
;-)
Michael.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-09 7:52 Editing change groups Michael Heerdegen
2018-11-09 8:39 ` Joost Kremers
2018-11-09 11:58 ` Noam Postavsky
@ 2018-11-09 13:12 ` Michael Heerdegen
2018-11-09 13:52 ` Stefan Monnier
3 siblings, 0 replies; 16+ messages in thread
From: Michael Heerdegen @ 2018-11-09 13:12 UTC (permalink / raw)
To: Emacs mailing list
Michael Heerdegen <michael_heerdegen@web.de> writes:
> (defun my-test-change-groups ()
> (interactive)
> (insert "0\n")
> (let ((g (prepare-change-group)))
> (insert "a\n")
> (activate-change-group g)
> (insert "b\n")
> (insert "c\n")
> (cancel-change-group g)))
I instrumented `prepare-change-group', `activate-change-group' and
`cancel-change-group' with Edebug - only to see that after finishing the
Edebug session what was left in the test buffer was the lines with "0"
and "a" - exactly what is expected! Seems user interaction is making a
difference here.
Michael.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-09 12:39 ` Michael Heerdegen
@ 2018-11-09 13:14 ` Eli Zaretskii
0 siblings, 0 replies; 16+ messages in thread
From: Eli Zaretskii @ 2018-11-09 13:14 UTC (permalink / raw)
To: Michael Heerdegen, Richard Stallman; +Cc: help-gnu-emacs, npostavs
> From: Michael Heerdegen <michael_heerdegen@web.de>
> Date: Fri, 09 Nov 2018 13:39:05 +0100
> Cc: Help Gnu Emacs mailing list <help-gnu-emacs@gnu.org>
>
> Noam Postavsky <npostavs@gmail.com> writes:
>
> > Possible alternative approach with prior art in string-rectangle: fake
> > the change with overlays for preview, then it's easy to remove.
>
> Hmm - does that mean you also don't know how these change groups work
> ;-)
If we want an explanation how it should work, we should ask Richard
(CC'ed), because he designed and implemented this.
FWIW, the following does work for me as expected:
(catch 'foo
(atomic-change-group
(insert "a\n")
(insert "b\n")
(throw 'foo 1)))
If you evaluate this, you get 1 as the value, and nothing inserted
into the buffer.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
[not found] ` <mailman.3721.1541765458.1284.help-gnu-emacs@gnu.org>
@ 2018-11-09 13:36 ` Ben Bacarisse
2018-11-09 13:58 ` Michael Heerdegen
0 siblings, 1 reply; 16+ messages in thread
From: Ben Bacarisse @ 2018-11-09 13:36 UTC (permalink / raw)
To: help-gnu-emacs
Michael Heerdegen <michael_heerdegen@web.de> writes:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>
>> Would fiddling with the undo mechanism not be a better way to do this?
>
> Well, since it's my program that changes the buffer, I can't just call
> `undo', which is a user command.
I was suggesting you call the more basic undo functions to roll back the
changes.
> Change groups look like the right tool
> because they seem to implement exact that fiddling with the undo
> mechanism that I need.
I've not looked at them in detail but they look more like a way to make
atomic updates rather than what you need.
--
Ben.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-09 7:52 Editing change groups Michael Heerdegen
` (2 preceding siblings ...)
2018-11-09 13:12 ` Michael Heerdegen
@ 2018-11-09 13:52 ` Stefan Monnier
2018-11-10 4:53 ` Michael Heerdegen
3 siblings, 1 reply; 16+ messages in thread
From: Stefan Monnier @ 2018-11-09 13:52 UTC (permalink / raw)
To: help-gnu-emacs
> (let ((g (prepare-change-group)))
> (insert "a\n")
> (activate-change-group g)
You (*really*) shouldn't modify the buffer between prepare-change-group
and activate-change-group.
Stefan
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-09 13:36 ` Ben Bacarisse
@ 2018-11-09 13:58 ` Michael Heerdegen
0 siblings, 0 replies; 16+ messages in thread
From: Michael Heerdegen @ 2018-11-09 13:58 UTC (permalink / raw)
To: Ben Bacarisse; +Cc: help-gnu-emacs
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> I was suggesting you call the more basic undo functions to roll back the
> changes.
Ah, ok.
Seems the manual doesn't explain all of them, however. I hoped I don't
need to read the whole source code.
Thanks,
Michael.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-09 13:52 ` Stefan Monnier
@ 2018-11-10 4:53 ` Michael Heerdegen
2018-11-10 13:15 ` Stefan Monnier
0 siblings, 1 reply; 16+ messages in thread
From: Michael Heerdegen @ 2018-11-10 4:53 UTC (permalink / raw)
To: Stefan Monnier; +Cc: help-gnu-emacs
Stefan Monnier <monnier@iro.umontreal.ca> writes:
> > (let ((g (prepare-change-group)))
> > (insert "a\n")
> > (activate-change-group g)
>
> You (*really*) shouldn't modify the buffer between
> prepare-change-group and activate-change-group.
Oh, it really means really, I see.
But the effect on the experiment is negligible, the behavior is still
not what I expect if I change that.
Thanks,
Michael.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-10 4:53 ` Michael Heerdegen
@ 2018-11-10 13:15 ` Stefan Monnier
2018-11-10 16:23 ` Michael Heerdegen
0 siblings, 1 reply; 16+ messages in thread
From: Stefan Monnier @ 2018-11-10 13:15 UTC (permalink / raw)
To: Michael Heerdegen; +Cc: help-gnu-emacs
>> > (let ((g (prepare-change-group)))
>> > (insert "a\n")
>> > (activate-change-group g)
>>
>> You (*really*) shouldn't modify the buffer between
>> prepare-change-group and activate-change-group.
>
> Oh, it really means really, I see.
The world won't collapse, but the behavior will be different depending
on whether undo is enabled in the buffer and the semantics is unclear.
> But the effect on the experiment is negligible, the behavior is still
> not what I expect if I change that.
I'm not sure which experiment this refers to.
Stefan
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-10 13:15 ` Stefan Monnier
@ 2018-11-10 16:23 ` Michael Heerdegen
2018-11-10 18:07 ` Stefan Monnier
0 siblings, 1 reply; 16+ messages in thread
From: Michael Heerdegen @ 2018-11-10 16:23 UTC (permalink / raw)
To: Stefan Monnier; +Cc: help-gnu-emacs
Stefan Monnier <monnier@IRO.UMontreal.CA> writes:
> I'm not sure which experiment this refers to.
My original example (now with the line you criticized removed):
#+begin_src emacs-lisp
(defun my-test-change-groups ()
(interactive)
(insert "0\n")
(let ((g (prepare-change-group)))
(activate-change-group g)
(insert "b\n")
(insert "c\n")
(cancel-change-group g)))
#+end_src
and why it doesn't behave as I expect (I guess you can guess what I
expect).
Michael.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-10 16:23 ` Michael Heerdegen
@ 2018-11-10 18:07 ` Stefan Monnier
2018-11-11 8:01 ` Michael Heerdegen
0 siblings, 1 reply; 16+ messages in thread
From: Stefan Monnier @ 2018-11-10 18:07 UTC (permalink / raw)
To: Michael Heerdegen; +Cc: help-gnu-emacs
> My original example (now with the line you criticized removed):
>
> #+begin_src emacs-lisp
> (defun my-test-change-groups ()
> (interactive)
> (insert "0\n")
> (let ((g (prepare-change-group)))
> (activate-change-group g)
> (insert "b\n")
> (insert "c\n")
> (cancel-change-group g)))
> #+end_src
>
> and why it doesn't behave as I expect (I guess you can guess what I
> expect).
Oh, yes, it's a bug in the change-groups code: the undo entries for
(insert "0\n"), (insert "b\n"), and (insert "c\n") are merged into
a single entry in the undo log (as a form of optimization).
The change-group code should prevent such a merge, e.g. by adding some
dummy undo element which will work like a "fence".
Can you file this as a proper bug report (and put me in X-Debbugs-Cc)?
Stefan
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Editing change groups
2018-11-10 18:07 ` Stefan Monnier
@ 2018-11-11 8:01 ` Michael Heerdegen
0 siblings, 0 replies; 16+ messages in thread
From: Michael Heerdegen @ 2018-11-11 8:01 UTC (permalink / raw)
To: Stefan Monnier; +Cc: help-gnu-emacs
Stefan Monnier <monnier@IRO.UMontreal.CA> writes:
> Can you file this as a proper bug report (and put me in X-Debbugs-Cc)?
Ok, done, #33341.
I think I'm lucky and this amalgating is not a problem in my real use
case.
Thanks,
Michael.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2018-11-11 8:01 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-09 7:52 Editing change groups Michael Heerdegen
2018-11-09 8:39 ` Joost Kremers
2018-11-09 11:58 ` Noam Postavsky
2018-11-09 12:39 ` Michael Heerdegen
2018-11-09 13:14 ` Eli Zaretskii
2018-11-09 13:12 ` Michael Heerdegen
2018-11-09 13:52 ` Stefan Monnier
2018-11-10 4:53 ` Michael Heerdegen
2018-11-10 13:15 ` Stefan Monnier
2018-11-10 16:23 ` Michael Heerdegen
2018-11-10 18:07 ` Stefan Monnier
2018-11-11 8:01 ` Michael Heerdegen
[not found] <mailman.3697.1541749970.1284.help-gnu-emacs@gnu.org>
2018-11-09 11:41 ` Ben Bacarisse
2018-11-09 12:10 ` Michael Heerdegen
[not found] ` <mailman.3721.1541765458.1284.help-gnu-emacs@gnu.org>
2018-11-09 13:36 ` Ben Bacarisse
2018-11-09 13:58 ` Michael Heerdegen
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).