From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Yuan Fu Newsgroups: gmane.emacs.devel Subject: Re: Distinguish between regional undo and undo to the beginning in undo-equiv-table Date: Thu, 4 Mar 2021 11:18:30 -0500 Message-ID: <06A32454-8DB2-492C-9A69-A825AD5B66A2@gmail.com> References: <195AF8D0-1BFD-419D-88A1-69EA1FEED4D6@gmail.com> <60DCC8C7-CCA4-4113-88BE-B81A395C494D@gmail.com> <4890CDDF-E0DD-464B-9268-AD404015129D@gmail.com> Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.60.0.2.21\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_2AF8650A-F322-4A32-89A5-69EDE3AD4301" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="10259"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Thu Mar 04 17:19:24 2021 Return-path: Envelope-to: ged-emacs-devel@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 1lHqhA-0002ZY-GG for ged-emacs-devel@m.gmane-mx.org; Thu, 04 Mar 2021 17:19:24 +0100 Original-Received: from localhost ([::1]:59354 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lHqh9-0001J3-Iz for ged-emacs-devel@m.gmane-mx.org; Thu, 04 Mar 2021 11:19:23 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:58926) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lHqgM-0000nB-IS for emacs-devel@gnu.org; Thu, 04 Mar 2021 11:18:34 -0500 Original-Received: from mail-qt1-x836.google.com ([2607:f8b0:4864:20::836]:46204) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lHqgL-0007bW-0K for emacs-devel@gnu.org; Thu, 04 Mar 2021 11:18:34 -0500 Original-Received: by mail-qt1-x836.google.com with SMTP id o1so16383042qta.13 for ; Thu, 04 Mar 2021 08:18:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:message-id:mime-version:subject:date:in-reply-to:cc:to :references; bh=hwHatG3714mXrxJcG6aC8VHHLqjsGUoPpN9qEeV8OJc=; b=CXrA45upbP0ThMhFK0oi0PAOmhN7y+TcXfkmk89YP+ernNX48O6yYEUXQC3wnorDkw ZiCitoAGhlp+jrREJycktnPaqDlqRZit5s1nWIiskb3hov9j893XZHVvW+7HqbeUUqpR ala7TlOHSdctDY7wMuIcU+0Jl/SC4ArVMLo/wJXIDFA7Wj6wYQnD/EuX/IsPjuz+IPnW 8pLdDrUlmKlp5gGCPOWpPovkFbcmDBGQGZypK0+ha49a5FYdWWapGPA54GyLr1pDaA7M C1GzlI1A/8DVW7y9QZi1pWmNX3kHYvPLPoev6ZecaAsnDi0LWUHIsDBhiDW7x17EKX2l YWZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:message-id:mime-version:subject:date :in-reply-to:cc:to:references; bh=hwHatG3714mXrxJcG6aC8VHHLqjsGUoPpN9qEeV8OJc=; b=eE47HMsiKiWBzjA6fptsc+db88bOVd9JG2REQX7omria353pqUzGxy6tkGZAP0QrGJ X4TLzG71jfAd6W2pYC9n2W+5xAIvRByw5uW7z4KGoIznDbyLDEHNat8HcKUVvcF28Hq8 IbNNnwMNMxQ35/hZqovLIKC7ot9Bx90qg2m/0Mj8wf4K9u+HvGtk3kqYeMniYcQfUYOu rqrbuwcXJHPTjVS8vyol9tbCXliYzPBT2pYIGJDBvmnv+V+90Ukc+Sl49b1B7wmaN3Fb VRkXnaS2ehk5yJS0ZVLFjyVsBy+I5QLyJlzTt2Yc7Axh1cUr9kopfebwspjSMhpJytfQ w9Qw== X-Gm-Message-State: AOAM532viA3pv2NSjXVPTHL7fVA0fREY04UlkQt4EMstqDTdQpUmNjgN /9PQaIJzZ+ZscfcYqiBF5ZPzB0w4M8I= X-Google-Smtp-Source: ABdhPJxBa8yEczDlD1BMppaOKruJ313gCPfjR6uGdz+EMwHv7AQ8u5VoEktXpsCu1eE3Jz3nydpZcQ== X-Received: by 2002:ac8:66ca:: with SMTP id m10mr4656968qtp.271.1614874711949; Thu, 04 Mar 2021 08:18:31 -0800 (PST) Original-Received: from ?IPv6:2601:98a:4200:9210:2139:b03b:5981:d056? ([2601:98a:4200:9210:2139:b03b:5981:d056]) by smtp.gmail.com with ESMTPSA id s52sm12657933qtb.66.2021.03.04.08.18.31 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 04 Mar 2021 08:18:31 -0800 (PST) In-Reply-To: X-Mailer: Apple Mail (2.3654.60.0.2.21) Received-SPF: pass client-ip=2607:f8b0:4864:20::836; envelope-from=casouri@gmail.com; helo=mail-qt1-x836.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:265971 Archived-At: --Apple-Mail=_2AF8650A-F322-4A32-89A5-69EDE3AD4301 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 >=20 >> Then should we add a mapping for the buffer-undo-list to t at that >> point? Or should we just do nothing? >=20 > Good question. I think you have a better understanding of how the = equiv > table should be filled than I do at this point, so I'd trust your = judgment. Ok, I looked into it in detail, undo-equiv-table is also used to check = if the previous command is really an undo, alongside with checking = last-command. So the undo record has to map to something, I decide to = map it to =E2=80=98empty unless there is already a mapping for the = record. Here is the (standalone) final draft. Please have a look. Yuan --Apple-Mail=_2AF8650A-F322-4A32-89A5-69EDE3AD4301 Content-Disposition: attachment; filename=undo-in-region-3.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="undo-in-region-3.patch" Content-Transfer-Encoding: quoted-printable =46rom=207e197d19f257816aaf12f474bdae2eca36fbbc21=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Yuan=20Fu=20=0ADate:=20Wed,=20= 3=20Mar=202021=2009:50:15=20-0500=0ASubject:=20[PATCH]=20Map=20redo=20= records=20for=20undo=20in=20region=20to=20'undo-in-region=0A=0A*=20= lisp/simple.el=20(undo-equiv-table):=20Add=20explaination=20for=0A= undo-in-region,=20undo=20to=20the=20beginning=20of=20undo=20list=20and=20= null=20undo.=0A(undo):=20If=20equiv=20is=20'undo-in-region,=20empty=20or=20= t,=20set=20pending-undo-list=0Ato=20t.=20=20If=20the=20redo=20is=20= undo-in-region,=20map=20buffer-undo-list=20to=0A'undo-in-region=20= instead=20of=20t,=20if=20it=20is=20an=20identity=20mapping,=20map=20to=0A= 'empty.=0A(undo-make-selective-list):=20Only=20continue=20when=20ulist=20= is=20a=20proper=20list.=0A*=20test/lisp/simple-tests.el=20= (simple-tests--undo):=20Add=20test=20for=0Aundo-only=20in=20region.=0A= (simple-tests--sans-leading-nil):=20New=20helper=20function.=0A= (simple-tests--undo-equiv-table):=20New=20test=20for=20= 'undo-equiv-table'.=0A---=0A=20lisp/simple.el=20=20=20=20=20=20=20=20=20=20= =20=20|=20=2055=20+++++++++++++++----=0A=20test/lisp/simple-tests.el=20|=20= 111=20+++++++++++++++++++++++++++++++++++++-=0A=202=20files=20changed,=20= 155=20insertions(+),=2011=20deletions(-)=0A=0Adiff=20--git=20= a/lisp/simple.el=20b/lisp/simple.el=0Aindex=20f8050091d5..98fccf4ff2=20= 100644=0A---=20a/lisp/simple.el=0A+++=20b/lisp/simple.el=0A@@=20-2824,8=20= +2824,35=20@@=20'advertised-undo=0A=20=0A=20(defconst=20undo-equiv-table=20= (make-hash-table=20:test=20'eq=20:weakness=20t)=0A=20=20=20"Table=20= mapping=20redo=20records=20to=20the=20corresponding=20undo=20one.=0A-A=20= redo=20record=20for=20undo-in-region=20maps=20to=20t.=0A-A=20redo=20= record=20for=20ordinary=20undo=20maps=20to=20the=20following=20(earlier)=20= undo.")=0A+A=20redo=20record=20for=20an=20undo=20in=20region=20maps=20to=20= 'undo-in-region.=0A+A=20redo=20record=20for=20ordinary=20undo=20maps=20= to=20the=20following=20(earlier)=20undo.=0A+A=20redo=20record=20that=20= undoes=20to=20the=20beginning=20of=20the=20undo=20list=20maps=20to=20t.=0A= +In=20the=20rare=20case=20where=20there=20are=20(erroneously)=20= consecutive=20nil's=20in=0A+`buffer-undo-list',=20`undo'=20maps=20the=20= previous=20valid=20undo=20record=20to=0A+'empty,=20if=20the=20previous=20= record=20is=20a=20redo=20record,=20`undo'=20doesn't=20change=0A+its=20= mapping.=0A+=0A+To=20be=20clear,=20a=20redo=20record=20is=20just=20an=20= undo=20record,=20the=20only=20difference=0A+is=20that=20it=20is=20= created=20by=20an=20undo=20command=20(instead=20of=20an=20ordinary=20= buffer=0A+edit).=20=20Since=20a=20record=20used=20to=20undo=20ordinary=20= change=20is=20called=20undo=0A+record,=20a=20record=20used=20to=20undo=20= an=20undo=20is=20called=20redo=20record.=0A+=0A+`undo'=20uses=20this=20= table=20to=20make=20sure=20the=20previous=20command=20is=20`undo'.=0A= +`undo-redo'=20uses=20this=20table=20to=20set=20the=20correct=20= `pending-undo-list'.=0A+=0A+When=20you=20undo,=20`pending-undo-list'=20= shrinks=20and=20`buffer-undo-list'=0A+grows,=20and=20Emacs=20maps=20the=20= tip=20of=20`buffer-undo-list'=20to=20the=20tip=20of=0A= +`pending-undo-list'=20in=20this=20table.=0A+=0A+For=20example,=20= consider=20this=20undo=20list=20where=20each=20node=20represents=20an=0A= +undo=20record:=20if=20we=20undo=20from=204,=20`pending-undo-list'=20= will=20be=20at=203,=0A+`buffer-undo-list'=20at=205,=20and=205=20will=20= map=20to=203.=0A+=0A+=20=20=20=20|=0A+=20=20=20=203=20=205=0A+=20=20=20=20= |=20/=0A+=20=20=20=20|/=0A+=20=20=20=204")=0A=20=0A=20(defvar=20= undo-in-region=20nil=0A=20=20=20"Non-nil=20if=20`pending-undo-list'=20is=20= not=20just=20a=20tail=20of=20`buffer-undo-list'.")=0A@@=20-2872,7=20= +2899,9=20@@=20undo=0A=20=20=20=20=20;;=20the=20next=20command=20should=20= not=20be=20a=20"consecutive=20undo".=0A=20=20=20=20=20;;=20So=20set=20= `this-command'=20to=20something=20other=20than=20`undo'.=0A=20=20=20=20=20= (setq=20this-command=20'undo-start)=0A-=0A+=20=20=20=20;;=20Here=20we=20= decide=20whether=20to=20break=20the=20undo=20chain.=20=20If=20the=0A+=20=20= =20=20;;=20previous=20command=20is=20`undo',=20we=20don't=20call=20= `undo-start',=20i.e.,=0A+=20=20=20=20;;=20don't=20break=20the=20undo=20= chain.=0A=20=20=20=20=20(unless=20(and=20(eq=20last-command=20'undo)=0A=20= =09=09=20(or=20(eq=20pending-undo-list=20t)=0A=20=09=09=20=20=20=20=20;;=20= If=20something=20(a=20timer=20or=20filter?)=20changed=20the=20buffer=0A= @@=20-2901,7=20+2930,7=20@@=20undo=0A=20=09;;=20undo-redo-undo-redo-...=20= so=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-=09(setq=20pending-undo-list=20equiv)))=0A+=09= (setq=20pending-undo-list=20(if=20(consp=20equiv)=20equiv=20t))))=0A=20=20= =20=20=20(undo-more=0A=20=20=20=20=20=20(if=20(numberp=20arg)=0A=20=09=20= (prefix-numeric-value=20arg)=0A@@=20-2917,11=20+2946,17=20@@=20undo=0A=20= =20=20=20=20=20=20(while=20(eq=20(car=20list)=20nil)=0A=20=09(setq=20= list=20(cdr=20list)))=0A=20=20=20=20=20=20=20(puthash=20list=0A-=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20;;=20Prevent=20identity=20mapping.=20= =20This=20can=20happen=20if=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20;;=20consecutive=20nils=20are=20erroneously=20in=20undo=20list.=0A-=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20(or=20undo-in-region=20= (eq=20list=20pending-undo-list))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20t=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= pending-undo-list)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cond=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(undo-in-region=20= 'undo-in-region)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20= Prevent=20identity=20mapping.=20=20This=20can=20happen=20if=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20;;=20consecutive=20nils=20are=20= erroneously=20in=20undo=20list.=20=20It=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20;;=20has=20to=20map=20to=20_something_=20so=20that=20= the=20next=20`undo'=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ;;=20command=20recognizes=20that=20the=20previous=20command=20is=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20`undo'=20and=20doesn't=20= break=20the=20undo=20chain.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20((eq=20list=20pending-undo-list)=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(or=20(gethash=20list=20undo-equiv-table)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'empty))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(t=20pending-undo-list))=0A=20=09=20=20= =20=20=20=20=20undo-equiv-table))=0A=20=20=20=20=20;;=20Don't=20specify=20= a=20position=20in=20the=20undo=20record=20for=20the=20undo=20command.=0A=20= =20=20=20=20;;=20Instead,=20undoing=20this=20should=20move=20point=20to=20= where=20the=20change=20is.=0A@@=20-3234,7=20+3269,7=20@@=20= undo-make-selective-list=0A=20=20=20=20=20=20=20=20=20undo-elt)=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(while=20(gethash=20ulist=20undo-equiv-table)=0A+=20=20= =20=20=20=20=20=20(while=20(consp=20(gethash=20ulist=20= undo-equiv-table))=0A=20=20=20=20=20=20=20=20=20=20=20(setq=20ulist=20= (gethash=20ulist=20undo-equiv-table))))=0A=20=20=20=20=20=20=20(setq=20= undo-elt=20(car=20ulist))=0A=20=20=20=20=20=20=20(cond=0Adiff=20--git=20= a/test/lisp/simple-tests.el=20b/test/lisp/simple-tests.el=0Aindex=20= f2ddc2e3fb..1819775bda=20100644=0A---=20a/test/lisp/simple-tests.el=0A= +++=20b/test/lisp/simple-tests.el=0A@@=20-465,8=20+465,117=20@@=20= simple-tests--undo=0A=20=20=20=20=20(simple-tests--exec=20= '(backward-char=20undo-redo=20undo-redo))=0A=20=20=20=20=20(should=20= (equal=20(buffer-string)=20"abc"))=0A=20=20=20=20=20(simple-tests--exec=20= '(backward-char=20undo-redo=20undo-redo))=0A+=20=20=20=20(should=20= (equal=20(buffer-string)=20"abcde")))=0A+=20=20;;=20Test=20undo/redo=20= in=20region.=0A+=20=20(with-temp-buffer=0A+=20=20=20=20= (buffer-enable-undo)=0A+=20=20=20=20(dolist=20(x=20'("a"=20"b"=20"c"=20= "d"=20"e"))=0A+=20=20=20=20=20=20(insert=20x)=0A+=20=20=20=20=20=20= (undo-boundary))=0A+=20=20=20=20(should=20(equal=20(buffer-string)=20= "abcde"))=0A+=20=20=20=20;;=20The=20test=20does=20this:=20activate=20= region,=20`undo',=20break=20the=20undo=0A+=20=20=20=20;;=20chain=20(by=20= deactivating=20and=20reactivating=20the=20region),=20then=0A+=20=20=20=20= ;;=20`undo-only'.=20=20There=20used=20to=20be=20a=20bug=20in=0A+=20=20=20= =20;;=20`undo-make-selective-list'=20that=20makes=20`undo-only'=20error=20= out=20in=0A+=20=20=20=20;;=20that=20case,=20which=20is=20fixed=20by=20in=20= the=20same=20commit=20as=20this=20change.=0A+=20=20=20=20= (simple-tests--exec=20'(move-beginning-of-line=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=20push-mark-command=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=20forward-char=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=20forward-char=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=20undo))=0A+=20=20=20=20= (should=20(equal=20(buffer-string)=20"acde"))=0A+=20=20=20=20= (simple-tests--exec=20'(move-beginning-of-line=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=20push-mark-command=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=20forward-char=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=20forward-char=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=20undo-only))=0A=20=20=20=20= =20(should=20(equal=20(buffer-string)=20"abcde"))=0A-=20=20=20=20))=0A+=20= =20=20=20;;=20Rest=20are=20simple=20redo=20in=20region=20tests.=0A+=20=20= =20=20(simple-tests--exec=20'(undo-redo))=0A+=20=20=20=20(should=20= (equal=20(buffer-string)=20"acde"))=0A+=20=20=20=20(simple-tests--exec=20= '(undo-redo))=0A+=20=20=20=20(should=20(equal=20(buffer-string)=20= "abcde"))))=0A+=0A+(defun=20simple-tests--sans-leading-nil=20(lst)=0A+=20= =20"Return=20LST=20sans=20the=20leading=20nils."=0A+=20=20(while=20(and=20= (consp=20lst)=20(null=20(car=20lst)))=0A+=20=20=20=20(setq=20lst=20(cdr=20= lst)))=0A+=20=20lst)=0A+=0A+(ert-deftest=20= simple-tests--undo-equiv-table=20()=0A+=20=20(with-temp-buffer=0A+=20=20=20= =20(buffer-enable-undo)=0A+=20=20=20=20(let=20((ul-hash-table=20= (make-hash-table=20:test=20#'equal)))=0A+=20=20=20=20=20=20(dolist=20(x=20= '("a"=20"b"=20"c"))=0A+=20=20=20=20=20=20=20=20(insert=20x)=0A+=20=20=20=20= =20=20=20=20(puthash=20x=20(simple-tests--sans-leading-nil=20= buffer-undo-list)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ul-hash-table)=0A+=20=20=20=20=20=20=20=20(undo-boundary))=0A+=20=20=20=20= =20=20(should=20(equal=20(buffer-string)=20"abc"))=0A+=20=20=20=20=20=20= ;;=20Tests=20mappings=20in=20`undo-equiv-table'.=0A+=20=20=20=20=20=20= (simple-tests--exec=20'(undo))=0A+=20=20=20=20=20=20(should=20(equal=20= (buffer-string)=20"ab"))=0A+=20=20=20=20=20=20(should=20(eq=20(gethash=20= (simple-tests--sans-leading-nil=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=20buffer-undo-list)=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= undo-equiv-table)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (gethash=20"b"=20ul-hash-table)))=0A+=20=20=20=20=20=20= (simple-tests--exec=20'(backward-char=20undo))=0A+=20=20=20=20=20=20= (should=20(equal=20(buffer-string)=20"abc"))=0A+=20=20=20=20=20=20= (should=20(eq=20(gethash=20(simple-tests--sans-leading-nil=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= buffer-undo-list)=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=20undo-equiv-table)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(gethash=20"c"=20ul-hash-table)))=0A+=20=20=20= =20=20=20;;=20Undo=20in=20region=20should=20map=20to=20'undo-in-region.=0A= +=20=20=20=20=20=20(simple-tests--exec=20'(backward-char=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= push-mark-command=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=20move-end-of-line=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=20undo))=0A+=20= =20=20=20=20=20(should=20(equal=20(buffer-string)=20"ab"))=0A+=20=20=20=20= =20=20(should=20(eq=20(gethash=20(simple-tests--sans-leading-nil=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= =20buffer-undo-list)=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=20undo-equiv-table)=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20'undo-in-region))=0A+=20=20=20=20=20=20;;=20= The=20undo=20that=20undoes=20to=20the=20beginning=20should=20map=20to=20= t.=0A+=20=20=20=20=20=20(deactivate-mark=20'force)=0A+=20=20=20=20=20=20= (simple-tests--exec=20'(backward-char=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=20undo=20undo=20undo=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=20undo=20undo=20undo))=0A+=20=20=20=20=20=20(should=20(equal=20= (buffer-string)=20""))=0A+=20=20=20=20=20=20(should=20(eq=20(gethash=20= (simple-tests--sans-leading-nil=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=20buffer-undo-list)=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= undo-equiv-table)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= t))=0A+=20=20=20=20=20=20;;=20Erroneous=20nil=20undo=20should=20map=20to=20= 'empty.=0A+=20=20=20=20=20=20(insert=20"a")=0A+=20=20=20=20=20=20= (undo-boundary)=0A+=20=20=20=20=20=20(push=20nil=20buffer-undo-list)=0A+=20= =20=20=20=20=20(simple-tests--exec=20'(backward-char=20undo))=0A+=20=20=20= =20=20=20(should=20(equal=20(buffer-string)=20"a"))=0A+=20=20=20=20=20=20= (should=20(eq=20(gethash=20(simple-tests--sans-leading-nil=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= buffer-undo-list)=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=20undo-equiv-table)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20'empty))=0A+=20=20=20=20=20=20;;=20But=20if=20= the=20previous=20record=20is=20a=20redo=20record,=20its=20mapping=0A+=20=20= =20=20=20=20;;=20shouldn't=20change.=0A+=20=20=20=20=20=20(insert=20"e")=0A= +=20=20=20=20=20=20(undo-boundary)=0A+=20=20=20=20=20=20(should=20(equal=20= (buffer-string)=20"ea"))=0A+=20=20=20=20=20=20(puthash=20"e"=20= (simple-tests--sans-leading-nil=20buffer-undo-list)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20ul-hash-table)=0A+=20=20=20=20=20=20(insert=20= "a")=0A+=20=20=20=20=20=20(undo-boundary)=0A+=20=20=20=20=20=20= (simple-tests--exec=20'(backward-char=20undo))=0A+=20=20=20=20=20=20= (should=20(equal=20(buffer-string)=20"ea"))=0A+=20=20=20=20=20=20(push=20= nil=20buffer-undo-list)=0A+=20=20=20=20=20=20(simple-tests--exec=20= '(forward-char=20undo))=0A+=20=20=20=20=20=20;;=20Buffer=20content=20= should=20change=20since=20we=20just=20undid=20a=20nil=0A+=20=20=20=20=20=20= ;;=20record.=0A+=20=20=20=20=20=20(should=20(equal=20(buffer-string)=20= "ea"))=0A+=20=20=20=20=20=20;;=20The=20previous=20redo=20record=20= shouldn't=20map=20to=20empty.=0A+=20=20=20=20=20=20(should=20(equal=20= (gethash=20(simple-tests--sans-leading-nil=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= buffer-undo-list)=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=20undo-equiv-table)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(gethash=20"e"=20= ul-hash-table))))))=0A=20=0A=20;;;=20undo=20auto-boundary=20tests=0A=20= (ert-deftest=20undo-auto-boundary-timer=20()=0A--=20=0A2.24.3=20(Apple=20= Git-128)=0A=0A= --Apple-Mail=_2AF8650A-F322-4A32-89A5-69EDE3AD4301--