From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Newsgroups: gmane.emacs.bugs Subject: bug#37700: 27.0.50; undo mouse-drag-and-drop-region ineffective Date: Wed, 30 Oct 2019 20:09:40 +0100 Message-ID: <9FE0E2D6-E4EA-4D7C-871C-3483AC53B295@acm.org> References: <3311689D-B1DF-4BAC-86BA-E3D2C6D2ECF1@acm.org> <94D2DE0C-8BD0-4CCF-B77D-5606A1D227DD@acm.org> <5be797bb-9d6b-cebe-edf4-21b4a5944595@gmx.at> <60b5bfa7-0aaf-40c0-3a1d-d0c0c5c662c6@gmx.at> <354ABF35-C5D0-4045-B9F0-5615A64408E6@acm.org> <83k199nasx.fsf@gnu.org> <83ftjxn94q.fsf@gnu.org> <37DDF48D-FC37-47A8-8CEC-C6EB66AB2BF7@acm.org> Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_5FCBA9A8-24B8-4303-BF14-1383F574FFC1" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="268155"; mail-complaints-to="usenet@blaine.gmane.org" Cc: tkk@misasa.okayama-u.ac.jp, 37700@debbugs.gnu.org, homeros.misasa@gmail.com To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Oct 30 20:10:55 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.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1iPtMt-0017cU-5V for geb-bug-gnu-emacs@m.gmane.org; Wed, 30 Oct 2019 20:10:55 +0100 Original-Received: from localhost ([::1]:43562 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iPtMp-0003Fj-GA for geb-bug-gnu-emacs@m.gmane.org; Wed, 30 Oct 2019 15:10:52 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:33750) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iPtM4-00038a-IC for bug-gnu-emacs@gnu.org; Wed, 30 Oct 2019 15:10:05 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iPtM3-0001t2-73 for bug-gnu-emacs@gnu.org; Wed, 30 Oct 2019 15:10:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:42651) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iPtM3-0001sF-2I for bug-gnu-emacs@gnu.org; Wed, 30 Oct 2019 15:10:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1iPtM2-0004sZ-Nc for bug-gnu-emacs@gnu.org; Wed, 30 Oct 2019 15:10:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 30 Oct 2019 19:10:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 37700 X-GNU-PR-Package: emacs Original-Received: via spool by 37700-submit@debbugs.gnu.org id=B37700.157246259318728 (code B ref 37700); Wed, 30 Oct 2019 19:10:02 +0000 Original-Received: (at 37700) by debbugs.gnu.org; 30 Oct 2019 19:09:53 +0000 Original-Received: from localhost ([127.0.0.1]:51472 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iPtLq-0004ru-1U for submit@debbugs.gnu.org; Wed, 30 Oct 2019 15:09:50 -0400 Original-Received: from mail203c50.megamailservers.eu ([91.136.10.213]:55262 helo=mail193c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iPtLn-0004rj-6z for 37700@debbugs.gnu.org; Wed, 30 Oct 2019 15:09:48 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1572462585; bh=dmFkd4dK8s6O9jM/FQgkVulKLxuTa+kYvs1EZs4Xibw=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=cmEfNJYKPzyzYw9wGPbNssVIrdhE8nzmGsAJeN9e8UqZDdVvKEUiiaikqsLnNSbu2 Y3qCNeHZy3eVJJ9a4VkUea2XIjnzYkixhrPd/9/witttfEgzlqTodphHr07cjioRRI dIEwmRsfRUEhuHXXNY4tpfxG4Oi9MjLwbqzkZJT8= Feedback-ID: mattiase@acm.or Original-Received: from [192.168.0.4] (c188-150-171-71.bredband.comhem.se [188.150.171.71]) (authenticated bits=0) by mail193c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x9UJ9eFZ004912; Wed, 30 Oct 2019 19:09:42 +0000 In-Reply-To: X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B0202.5DB9DFF9.0005, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=E6OzWpVl c=1 sm=1 tr=0 a=SF+I6pRkHZhrawxbOkkvaA==:117 a=SF+I6pRkHZhrawxbOkkvaA==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=M51BFTxLslgA:10 a=iRZporoAAAAA:8 a=mh0XpIdruJMawyzGlmcA:9 a=CjuIK1q_8ugA:10 a=y2fPTyxOXttb7gH-QJsA:9 a=B2y7HmGcmWMA:10 a=m3gybRlJfkf931b4_iEA:9 a=NOBgFS-JBQ2l-kSd6-zu:22 a=pHzHmUro8NiASowvMSCR:22 a=xoEH_sTeL_Rfw54TyV31:22 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:170437 Archived-At: --Apple-Mail=_5FCBA9A8-24B8-4303-BF14-1383F574FFC1 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii 28 okt. 2019 kl. 21.01 skrev Stefan Monnier : > Indeed, that's also my experience [ and as a result I stay away from > text's drag-and-drop since I find C-w ... C-y to be easier since it > avoids this trial-and-error problem ;-) ] Thanks for taking a look. It seems that the only happy users are those = that use redo+.el or similar packages that do not restrict undo to = region. Unfortunately, even with the patch, undoing a drag-and-drop does not = leave the region active the way it was before the undo, so the user has = to reselect the text in order to try again. Reactivating the region = automatically on undo is tempting but incompatible with undo-in-region = (the same problem but in the other direction). Partly because of this, I = believe that providing an option to disable undo-in-region altogether is = a better solution. > Rather than add a special new kind of entry you can use some version = of > (apply DELTA BEG END FUN-NAME . ARGS), presumably with DELTA=3D0 and > BEG=3DEND, so you don't need to modify the docstring of = `buffer-undo-list` > nor the implementation of primitive-undo. I'm not sure how that would be done in practice since = 'undo-elt-in-region' is nil for any (apply ...) element. This could be = remedied, of course, but that would entail undo machinery changes which = we wanted to avoid in the first place. In addition, it is unclear how = the 'apply' mechanism could be used in a way that is sensitive to = whether it's the first record to be undone. > As a user of undo-in-region, I think I'd be surprised if my undo = started > to modify parts of the buffer outside the region, so I think a better > approach would be to only pay attention to the `unconfined' marker = when > it appears at the top of the `buffer-undo-list` (i.e. only if the > drag-and-drop was the very last operation). The patch has now been modified to that effect. (I'm still not sure it's = the right solution.) > Also I think it would > deserve a message in the minibuffer explaining that the undo is not > confined to the region. It was tricky to do that cleanly, given the structure of the undo code, = so it went into a separate patch. --Apple-Mail=_5FCBA9A8-24B8-4303-BF14-1383F574FFC1 Content-Disposition: attachment; filename=0001-Don-t-confine-undo-of-mouse-drag-and-drop-to-the-reg.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-Don-t-confine-undo-of-mouse-drag-and-drop-to-the-reg.patch" Content-Transfer-Encoding: quoted-printable =46rom=20a857757e9f7d92b2acb9817399c9a4af49a4154c=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20= =0ADate:=20Wed,=2016=20Oct=202019=2015:32:22=20+0200=0A= Subject:=20[PATCH=201/2]=20Don't=20confine=20undo=20of=20= mouse-drag-and-drop=20to=20the=20region=0A=20(bug#37700)=0AMIME-Version:=20= 1.0=0AContent-Type:=20text/plain;=20charset=3DUTF-8=0A= Content-Transfer-Encoding:=208bit=0A=0ASince=20the=20region=20is=20= active=20after=20a=20mouse-drag-and-drop,=20the=20change=0Acannot=20= immediately=20be=20undone.=20=20To=20get=20around=20this,=20tell=20the=20= undo=0Amachinery=20to=20ignore=20the=20region=20confinement=20for=20this=20= operation=20if=0Ait=20is=20undone=20right=20away.=0A=0A*=20= lisp/simple.el=20(primitive-undo,=20undo-make-selective-list):=0A*=20= src/buffer.c=20(buffer-undo-list):=0ANew=20`buffer-undo-list=E2=80=99=20= element=20`unconfined'.=0A*=20lisp/mouse.el=20= (mouse-drag-and-drop-region):=0AMark=20the=20operation=20as=20unconfined=20= upon=20undo.=0A---=0A=20lisp/mouse.el=20=20|=20=207=20++++++-=0A=20= lisp/simple.el=20|=2013=20+++++++++++--=0A=20src/buffer.c=20=20=20|=20=20= 4=20++++=0A=203=20files=20changed,=2021=20insertions(+),=203=20= deletions(-)=0A=0Adiff=20--git=20a/lisp/mouse.el=20b/lisp/mouse.el=0A= index=2076fec507e7..533ad606fb=20100644=0A---=20a/lisp/mouse.el=0A+++=20= b/lisp/mouse.el=0A@@=20-2657,7=20+2657,12=20@@=20= mouse-drag-and-drop-region=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(let=20(deactivate-mark)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(dolist=20(overlay=20mouse-drag-and-drop-overlays)=0A=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(delete-region=20= (overlay-start=20overlay)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(overlay-end=20= overlay)))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(overlay-end=20= overlay))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20= Since=20we=20will=20leave=20the=20destination=20text=20selected,=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20make=20sure=20an=20undo=20= operation=20disregards=20the=20region=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20;;=20or=20the=20operation=20will=20only=20be=20partially=20= undone.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(when=20= (consp=20buffer-undo-list)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(push=20'unconfined=20buffer-undo-list)))=0A=20=20=20=20=20=20=20= =20=20=20=20=20=20;;=20When=20source=20buffer=20and=20destination=20= buffer=20are=20different,=0A=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20= keep=20(set=20back=20the=20original=20text=20as=20region)=20or=20remove=20= the=0A=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20original=20text.=0A= diff=20--git=20a/lisp/simple.el=20b/lisp/simple.el=0Aindex=20= 29e195bca6..83be410074=20100644=0A---=20a/lisp/simple.el=0A+++=20= b/lisp/simple.el=0A@@=20-2753,6=20+2753,7=20@@=20primitive-undo=0A=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(set-marker=20marker=0A=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(-=20marker=20= offset)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(marker-buffer=20marker))))=0A+=20=20=20=20=20=20=20=20=20= =20(unconfined)=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;=20= Ignore=20this=20directive=20here.=0A=20=20=20=20=20=20=20=20=20=20=20(_=20= (error=20"Unrecognized=20entry=20in=20undo=20list=20%S"=20next))))=0A=20=20= =20=20=20=20=20(setq=20arg=20(1-=20arg)))=0A=20=20=20=20=20;;=20Make=20= sure=20an=20apply=20entry=20produces=20at=20least=20one=20undo=20entry,=0A= @@=20-2855,9=20+2856,15=20@@=20undo-make-selective-list=0A=20=20=20(let=20= ((ulist=20buffer-undo-list)=0A=20=20=20=20=20=20=20=20=20;;=20A=20list=20= of=20position=20adjusted=20undo=20elements=20in=20the=20region.=0A=20=20=20= =20=20=20=20=20=20(selective-list=20(list=20nil))=0A+=20=20=20=20=20=20=20= =20(unconfined=20nil)=20=20=20;=20Whether=20to=20include=20whole=20= record=20unconditionally.=0A=20=20=20=20=20=20=20=20=20;;=20A=20list=20= of=20undo-deltas=20for=20out=20of=20region=20undo=20elements.=0A=20=20=20= =20=20=20=20=20=20undo-deltas=0A=20=20=20=20=20=20=20=20=20undo-elt)=0A+=20= =20=20=20;;=20The=20`unconfined'=20directive=20only=20applies=20to=20the=20= very=20first=20record.=0A+=20=20=20=20(pcase=20ulist=0A+=20=20=20=20=20=20= (`(nil=20unconfined=20.=20,rest)=0A+=20=20=20=20=20=20=20(setq=20= unconfined=20t)=0A+=20=20=20=20=20=20=20(setq=20ulist=20rest)))=0A=20=20=20= =20=20(while=20ulist=0A=20=20=20=20=20=20=20(when=20undo-no-redo=0A=20=20= =20=20=20=20=20=20=20(while=20(gethash=20ulist=20undo-equiv-table)=0A@@=20= -2867,7=20+2874,8=20@@=20undo-make-selective-list=0A=20=20=20=20=20=20=20= =20((null=20undo-elt)=0A=20=20=20=20=20=20=20=20=20;;=20Don't=20put=20= two=20nils=20together=20in=20the=20list=0A=20=20=20=20=20=20=20=20=20= (when=20(car=20selective-list)=0A-=20=20=20=20=20=20=20=20=20=20(push=20= nil=20selective-list)))=0A+=20=20=20=20=20=20=20=20=20=20(push=20nil=20= selective-list))=0A+=20=20=20=20=20=20=20=20(setq=20unconfined=20nil))=0A= =20=20=20=20=20=20=20=20((and=20(consp=20undo-elt)=20(eq=20(car=20= undo-elt)=20t))=0A=20=20=20=20=20=20=20=20=20;;=20This=20is=20a=20"was=20= unmodified"=20element.=20=20Keep=20it=0A=20=20=20=20=20=20=20=20=20;;=20= if=20we=20have=20kept=20everything=20thus=20far.=0A@@=20-2877,10=20= +2885,11=20@@=20undo-make-selective-list=0A=20=20=20=20=20=20=20=20;;=20= on=20finding=20them=20after=20(TEXT=20.=20POS)=20elements=0A=20=20=20=20=20= =20=20=20((markerp=20(car-safe=20undo-elt))=0A=20=20=20=20=20=20=20=20=20= nil)=0A+=20=20=20=20=20=20=20((eq=20undo-elt=20'unconfined))=20=20;=20= This=20directive=20has=20no=20further=20effect.=0A=20=20=20=20=20=20=20=20= (t=0A=20=20=20=20=20=20=20=20=20(let=20((adjusted-undo-elt=20= (undo-adjust-elt=20undo-elt=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20undo-deltas)))=0A-=20=20=20=20=20=20=20=20= =20=20(if=20(undo-elt-in-region=20adjusted-undo-elt=20start=20end)=0A+=20= =20=20=20=20=20=20=20=20=20(if=20(or=20(undo-elt-in-region=20= adjusted-undo-elt=20start=20end)=20unconfined)=0A=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(progn=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(setq=20end=20(+=20end=20(cdr=20(undo-delta=20= adjusted-undo-elt))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (push=20adjusted-undo-elt=20selective-list)=0Adiff=20--git=20= a/src/buffer.c=20b/src/buffer.c=0Aindex=2080eaa971a3..16012a97a2=20= 100644=0A---=20a/src/buffer.c=0A+++=20b/src/buffer.c=0A@@=20-6128,6=20= +6128,10=20@@=20from=20(abs=20POSITION).=20=20If=20POSITION=20is=20= positive,=20point=20was=20at=20the=20front=0A=20Entries=20with=20value=20= nil=20mark=20undo=20boundaries.=20=20The=20undo=20command=20treats=0A=20= the=20changes=20between=20two=20undo=20boundaries=20as=20a=20single=20= step=20to=20be=20undone.=0A=20=0A+An=20entry=20with=20the=20value=20= `unconfined'=20disables=20selective=20undo=20until=20the=0A+next=20undo=20= boundary=20even=20if=20the=20region=20is=20active.=20=20It=20only=20has=20= effect=0A+on=20the=20first=20record=20to=20be=20undone.=0A+=0A=20If=20= the=20value=20of=20the=20variable=20is=20t,=20undo=20information=20is=20= not=20recorded.=20=20*/);=0A=20=0A=20=20=20DEFVAR_PER_BUFFER=20= ("mark-active",=20&BVAR=20(current_buffer,=20mark_active),=20Qnil,=0A--=20= =0A2.21.0=20(Apple=20Git-122)=0A=0A= --Apple-Mail=_5FCBA9A8-24B8-4303-BF14-1383F574FFC1 Content-Disposition: attachment; filename=0002-Adapt-undo-message-when-undoing-unconfined-actions-i.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0002-Adapt-undo-message-when-undoing-unconfined-actions-i.patch" Content-Transfer-Encoding: quoted-printable =46rom=2071bc4e8352c6662458d5d18f328bd955054a91cc=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20= =0ADate:=20Wed,=2030=20Oct=202019=2019:13:47=20+0100=0A= Subject:=20[PATCH=202/2]=20Adapt=20undo=20message=20when=20undoing=20= unconfined=20actions=20in=0A=20region=0A=0A*=20lisp/simple.el=20(undo):=20= Don't=20say=20"Undo=20in=20region"=20when=20the=20action=0Aundone=20= explicitly=20ignores=20region=20confinement=20(bug#37700).=0A= (undo--first-record-unconfined):=20New.=0A(undo-make-selective-list):=20= Use=20undo--first-record-unconfined.=0A---=0A=20lisp/simple.el=20|=2037=20= ++++++++++++++++++++++++-------------=0A=201=20file=20changed,=2024=20= insertions(+),=2013=20deletions(-)=0A=0Adiff=20--git=20a/lisp/simple.el=20= b/lisp/simple.el=0Aindex=2083be410074..e08c9b6a89=20100644=0A---=20= a/lisp/simple.el=0A+++=20b/lisp/simple.el=0A@@=20-2508,6=20+2508,8=20@@=20= undo=0A=20=09=20(base-buffer=20(or=20(buffer-base-buffer)=20= (current-buffer)))=0A=20=09=20(recent-save=20(with-current-buffer=20= base-buffer=0A=20=09=09=09(recent-auto-save-p)))=0A+=20=20=20=20=20=20=20= =20=20(unconfined=20nil)=0A+=20=20=20=20=20=20=20=20=20(count=20(if=20= (numberp=20arg)=20(prefix-numeric-value=20arg)=201))=0A=20=09=20message)=0A= =20=20=20=20=20;;=20If=20we=20get=20an=20error=20in=20undo-start,=0A=20=20= =20=20=20;;=20the=20next=20command=20should=20not=20be=20a=20= "consecutive=20undo".=0A@@=20-2527,7=20+2529,9=20@@=20undo=0A=20=20=20=20= =20=20=20(setq=20undo-in-region=0A=20=09=20=20=20=20(or=20= (region-active-p)=20(and=20arg=20(not=20(numberp=20arg)))))=0A=20=20=20=20= =20=20=20(if=20undo-in-region=0A-=09=20=20(undo-start=20= (region-beginning)=20(region-end))=0A+=20=20=20=20=20=20=20=20=20=20= (progn=0A+=20=20=20=20=20=20=20=20=20=20=20=20(setq=20unconfined=20= (undo--first-record-unconfined=20buffer-undo-list))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20(undo-start=20(region-beginning)=20(region-end)))=0A=20= =09(undo-start))=0A=20=20=20=20=20=20=20;;=20get=20rid=20of=20initial=20= undo=20boundary=0A=20=20=20=20=20=20=20(undo-more=201))=0A@@=20-2537,20=20= +2541,20=20@@=20undo=0A=20=20=20=20=20;;=20so,=20ask=20the=20user=20= whether=20she=20wants=20to=20skip=20the=20redo/undo=20pair.=0A=20=20=20=20= =20(let=20((equiv=20(gethash=20pending-undo-list=20undo-equiv-table)))=0A= =20=20=20=20=20=20=20(or=20(eq=20(selected-window)=20= (minibuffer-window))=0A-=09=20=20(setq=20message=20(format=20"%s%s"=0A-=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(if=20(or=20undo-no-redo=20(not=20equiv))=0A-=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20"Undo"=20"Redo")=0A-=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20= undo-in-region=20"=20in=20region"=20""))))=0A+=09=20=20(setq=20message=20= (concat=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(if=20(or=20undo-no-redo=20(not=20equiv))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "Undo"=20"Redo")=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(cond=20((and=20unconfined=20(>=20count=201))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20"=20in=20region=20(except=20first=20action)")=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20((and=20undo-in-region=20(not=20unconfined))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20"=20in=20region")))))=0A=20=20=20=20=20=20=20(when=20(and=20(consp=20= equiv)=20undo-no-redo)=0A=20=09;;=20The=20equiv=20entry=20might=20point=20= to=20another=20redo=20record=20if=20we=20have=20done=0A=20=09;;=20= undo-redo-undo-redo-...=20so=20skip=20to=20the=20very=20last=20equiv.=0A=20= =09(while=20(let=20((next=20(gethash=20equiv=20undo-equiv-table)))=0A=20=09= =09=20(if=20next=20(setq=20equiv=20next))))=0A=20=09(setq=20= pending-undo-list=20equiv)))=0A-=20=20=20=20(undo-more=0A-=20=20=20=20=20= (if=20(numberp=20arg)=0A-=09=20(prefix-numeric-value=20arg)=0A-=20=20=20=20= =20=20=201))=0A+=20=20=20=20(undo-more=20count)=0A=20=20=20=20=20;;=20= Record=20the=20fact=20that=20the=20just-generated=20undo=20records=20= come=20from=20an=0A=20=20=20=20=20;;=20undo=20operation--that=20is,=20= they=20are=20redo=20records.=0A=20=20=20=20=20;;=20In=20the=20ordinary=20= case=20(not=20within=20a=20region),=20map=20the=20redo=0A@@=20-2847,6=20= +2851,13=20@@=20undo-start=0A=20;;=20"ccaabad",=20as=20though=20the=20= first=20"d"=20became=20detached=20from=20the=0A=20;;=20original=20"ddd"=20= insertion.=20=20This=20quirk=20is=20a=20FIXME.=0A=20=0A+(defun=20= undo--first-record-unconfined=20(undo-list)=0A+=20=20"If=20the=20first=20= record=20of=20UNDO-LIST=20is=20marked=20unconfined,=20return=20the=20= argument=0A+without=20the=20leading=20`unconfined'=20directive;=20= otherwise=20nil."=0A+=20=20(pcase=20undo-list=0A+=20=20=20=20(`(nil=20= unconfined=20.=20,rest)=0A+=20=20=20=20=20rest)))=0A+=0A=20(defun=20= undo-make-selective-list=20(start=20end)=0A=20=20=20"Return=20a=20list=20= of=20undo=20elements=20for=20the=20region=20START=20to=20END.=0A=20The=20= elements=20come=20from=20`buffer-undo-list',=20but=20we=20keep=20only=20= the=0A@@=20-2861,10=20+2872,10=20@@=20undo-make-selective-list=0A=20=20=20= =20=20=20=20=20=20undo-deltas=0A=20=20=20=20=20=20=20=20=20undo-elt)=0A=20= =20=20=20=20;;=20The=20`unconfined'=20directive=20only=20applies=20to=20= the=20very=20first=20record.=0A-=20=20=20=20(pcase=20ulist=0A-=20=20=20=20= =20=20(`(nil=20unconfined=20.=20,rest)=0A-=20=20=20=20=20=20=20(setq=20= unconfined=20t)=0A-=20=20=20=20=20=20=20(setq=20ulist=20rest)))=0A+=20=20= =20=20(let=20((ul=20(undo--first-record-unconfined=20ulist)))=0A+=20=20=20= =20=20=20(when=20ul=0A+=20=20=20=20=20=20=20=20(setq=20ulist=20ul)=0A+=20= =20=20=20=20=20=20=20(setq=20unconfined=20t)))=0A=20=20=20=20=20(while=20= ulist=0A=20=20=20=20=20=20=20(when=20undo-no-redo=0A=20=20=20=20=20=20=20= =20=20(while=20(gethash=20ulist=20undo-equiv-table)=0A--=20=0A2.21.0=20= (Apple=20Git-122)=0A=0A= --Apple-Mail=_5FCBA9A8-24B8-4303-BF14-1383F574FFC1--