Mercurial > hg > xemacs-beta
annotate lisp/undo-stack.el @ 5492:e82f5b7010fe
Merge some stuff in man, fix up Makefile
-------------------- ChangeLog entries follow: --------------------
man/ChangeLog addition:
2010-02-19 Ben Wing <ben@xemacs.org>
* widget.texi:
* widget.texi (Top):
* widget.texi (Introduction):
* widget.texi (User Interface):
* widget.texi (Programming Example):
* widget.texi (Setting Up the Buffer):
* widget.texi (Basic Types):
* widget.texi (link):
* widget.texi (url-link):
* widget.texi (info-link):
* widget.texi (push-button):
* widget.texi (editable-field):
* widget.texi (text):
* widget.texi (menu-choice):
* widget.texi (radio-button-choice):
* widget.texi (item):
* widget.texi (choice-item):
* widget.texi (toggle):
* widget.texi (checkbox):
* widget.texi (checklist):
* widget.texi (editable-list):
* widget.texi (group):
* widget.texi (Sexp Types):
* widget.texi (constants):
* widget.texi (generic):
* widget.texi (atoms):
* widget.texi (composite):
* widget.texi (Widget Properties):
* widget.texi (Defining New Widgets):
* widget.texi (Widget Browser):
* widget.texi (Widget Minor Mode):
* widget.texi (Utilities):
* widget.texi (Widget Wishlist):
* widget.texi (Widget Internals):
* widget.texi (GNU Free Documentation License):
* widget.texi (Index):
Sync with FSF 23.1.92.
2010-02-19 Ben Wing <ben@xemacs.org>
* texinfo/fdl.texi: New file.
* texinfo/texinfo.texi:
* texinfo/texinfo.texi (Top):
* texinfo/texinfo.texi (Copying Conditions):
* texinfo/texinfo.texi (Overview):
* texinfo/texinfo.texi (Reporting Bugs):
* texinfo/texinfo.texi (Using Texinfo):
* texinfo/texinfo.texi (Output Formats):
* texinfo/texinfo.texi (Info Files):
* texinfo/texinfo.texi (Printed Books):
* texinfo/texinfo.texi (Formatting Commands):
* texinfo/texinfo.texi (Conventions):
* texinfo/texinfo.texi (Comments):
* texinfo/texinfo.texi (Minimum):
* texinfo/texinfo.texi (Six Parts):
* texinfo/texinfo.texi (Short Sample):
* texinfo/texinfo.texi (History):
* texinfo/texinfo.texi (Texinfo Mode):
* texinfo/texinfo.texi (Texinfo Mode Overview):
* texinfo/texinfo.texi (XEmacs Editing):
* texinfo/texinfo.texi (Inserting):
* texinfo/texinfo.texi (Showing the Structure):
* texinfo/texinfo.texi (Updating Nodes and Menus):
* texinfo/texinfo.texi (Updating Commands):
* texinfo/texinfo.texi (Updating Requirements):
* texinfo/texinfo.texi (Other Updating Commands):
* texinfo/texinfo.texi (Info Formatting):
* texinfo/texinfo.texi (Printing):
* texinfo/texinfo.texi (Texinfo Mode Summary):
* texinfo/texinfo.texi (Beginning a File):
* texinfo/texinfo.texi (Sample Beginning):
* texinfo/texinfo.texi (Texinfo File Header):
* texinfo/texinfo.texi (First Line):
* texinfo/texinfo.texi (Start of Header):
* texinfo/texinfo.texi (setfilename):
* texinfo/texinfo.texi (settitle):
* texinfo/texinfo.texi (End of Header):
* texinfo/texinfo.texi (Document Permissions):
* texinfo/texinfo.texi (copying):
* texinfo/texinfo.texi (insertcopying):
* texinfo/texinfo.texi (Titlepage & Copyright Page):
* texinfo/texinfo.texi (titlepage):
* texinfo/texinfo.texi (titlefont center sp):
* texinfo/texinfo.texi (title subtitle author):
* texinfo/texinfo.texi (Copyright):
* texinfo/texinfo.texi (end titlepage):
* texinfo/texinfo.texi (headings on off):
* texinfo/texinfo.texi (Contents):
* texinfo/texinfo.texi (The Top Node):
* texinfo/texinfo.texi (Top Node Example):
* texinfo/texinfo.texi (Master Menu Parts):
* texinfo/texinfo.texi (Global Document Commands):
* texinfo/texinfo.texi (documentdescription):
* texinfo/texinfo.texi (setchapternewpage):
* texinfo/texinfo.texi (paragraphindent):
* texinfo/texinfo.texi (firstparagraphindent):
* texinfo/texinfo.texi (exampleindent):
* texinfo/texinfo.texi (Software Copying Permissions):
* texinfo/texinfo.texi (Ending a File):
* texinfo/texinfo.texi (Printing Indices & Menus):
* texinfo/texinfo.texi (File End):
* texinfo/texinfo.texi (Structuring):
* texinfo/texinfo.texi (Tree Structuring):
* texinfo/texinfo.texi (Structuring Command Types):
* texinfo/texinfo.texi (makeinfo top):
* texinfo/texinfo.texi (chapter):
* texinfo/texinfo.texi (unnumbered & appendix):
* texinfo/texinfo.texi (majorheading & chapheading):
* texinfo/texinfo.texi (section):
* texinfo/texinfo.texi (unnumberedsec appendixsec heading):
* texinfo/texinfo.texi (subsection):
* texinfo/texinfo.texi (unnumberedsubsec appendixsubsec subheading):
* texinfo/texinfo.texi (subsubsection):
* texinfo/texinfo.texi (Raise/lower sections):
* texinfo/texinfo.texi (Nodes):
* texinfo/texinfo.texi (Two Paths):
* texinfo/texinfo.texi (Node Menu Illustration):
* texinfo/texinfo.texi (node):
* texinfo/texinfo.texi (Node Names):
* texinfo/texinfo.texi (Writing a Node):
* texinfo/texinfo.texi (Node Line Tips):
* texinfo/texinfo.texi (Node Line Requirements):
* texinfo/texinfo.texi (First Node):
* texinfo/texinfo.texi (makeinfo top command):
* texinfo/texinfo.texi (makeinfo Pointer Creation):
* texinfo/texinfo.texi (anchor):
* texinfo/texinfo.texi (Menus):
* texinfo/texinfo.texi (Menu Location):
* texinfo/texinfo.texi (Writing a Menu):
* texinfo/texinfo.texi (Menu Parts):
* texinfo/texinfo.texi (Less Cluttered Menu Entry):
* texinfo/texinfo.texi (Menu Example):
* texinfo/texinfo.texi (Other Info Files):
* texinfo/texinfo.texi (Cross References):
* texinfo/texinfo.texi (References):
* texinfo/texinfo.texi (Cross Reference Commands):
* texinfo/texinfo.texi (Cross Reference Parts):
* texinfo/texinfo.texi (xref):
* texinfo/texinfo.texi (Reference Syntax):
* texinfo/texinfo.texi (One Argument):
* texinfo/texinfo.texi (Two Arguments):
* texinfo/texinfo.texi (Three Arguments):
* texinfo/texinfo.texi (Four and Five Arguments):
* texinfo/texinfo.texi (Top Node Naming):
* texinfo/texinfo.texi (ref):
* texinfo/texinfo.texi (pxref):
* texinfo/texinfo.texi (inforef):
* texinfo/texinfo.texi (uref):
* texinfo/texinfo.texi (cite):
* texinfo/texinfo.texi (Marking Text):
* texinfo/texinfo.texi (Indicating):
* texinfo/texinfo.texi (Useful Highlighting):
* texinfo/texinfo.texi (code):
* texinfo/texinfo.texi (kbd):
* texinfo/texinfo.texi (key):
* texinfo/texinfo.texi (samp):
* texinfo/texinfo.texi (verb):
* texinfo/texinfo.texi (var):
* texinfo/texinfo.texi (env):
* texinfo/texinfo.texi (file):
* texinfo/texinfo.texi (command):
* texinfo/texinfo.texi (option):
* texinfo/texinfo.texi (dfn):
* texinfo/texinfo.texi (abbr):
* texinfo/texinfo.texi (acronym):
* texinfo/texinfo.texi (indicateurl):
* texinfo/texinfo.texi (email):
* texinfo/texinfo.texi (Emphasis):
* texinfo/texinfo.texi (emph & strong):
* texinfo/texinfo.texi (Smallcaps):
* texinfo/texinfo.texi (Fonts):
* texinfo/texinfo.texi (Quotations and Examples):
* texinfo/texinfo.texi (Block Enclosing Commands):
* texinfo/texinfo.texi (quotation):
* texinfo/texinfo.texi (example):
* texinfo/texinfo.texi (verbatim):
* texinfo/texinfo.texi (verbatiminclude):
* texinfo/texinfo.texi (lisp):
* texinfo/texinfo.texi (small):
* texinfo/texinfo.texi (display):
* texinfo/texinfo.texi (format):
* texinfo/texinfo.texi (exdent):
* texinfo/texinfo.texi (flushleft & flushright):
* texinfo/texinfo.texi (noindent):
* texinfo/texinfo.texi (indent):
* texinfo/texinfo.texi (cartouche):
* texinfo/texinfo.texi (Lists and Tables):
* texinfo/texinfo.texi (Introducing Lists):
* texinfo/texinfo.texi (itemize):
* texinfo/texinfo.texi (enumerate):
* texinfo/texinfo.texi (Two-column Tables):
* texinfo/texinfo.texi (table):
* texinfo/texinfo.texi (ftable vtable):
* texinfo/texinfo.texi (itemx):
* texinfo/texinfo.texi (Multi-column Tables):
* texinfo/texinfo.texi (Multitable Column Widths):
* texinfo/texinfo.texi (Multitable Rows):
* texinfo/texinfo.texi (Special Displays):
* texinfo/texinfo.texi (Floats):
* texinfo/texinfo.texi (float):
* texinfo/texinfo.texi (caption shortcaption):
* texinfo/texinfo.texi (listoffloats):
* texinfo/texinfo.texi (Images):
* texinfo/texinfo.texi (Image Syntax):
* texinfo/texinfo.texi (Image Scaling):
* texinfo/texinfo.texi (Footnotes):
* texinfo/texinfo.texi (Footnote Commands):
* texinfo/texinfo.texi (Footnote Styles):
* texinfo/texinfo.texi (Indices):
* texinfo/texinfo.texi (Index Entries):
* texinfo/texinfo.texi (Predefined Indices):
* texinfo/texinfo.texi (Indexing Commands):
* texinfo/texinfo.texi (Combining Indices):
* texinfo/texinfo.texi (syncodeindex):
* texinfo/texinfo.texi (synindex):
* texinfo/texinfo.texi (New Indices):
* texinfo/texinfo.texi (Insertions):
* texinfo/texinfo.texi (Atsign Braces Comma):
* texinfo/texinfo.texi (Inserting an Atsign):
* texinfo/texinfo.texi (Inserting Braces):
* texinfo/texinfo.texi (Inserting a Comma):
* texinfo/texinfo.texi (Inserting Quote Characters):
* texinfo/texinfo.texi (Inserting Space):
* texinfo/texinfo.texi (Not Ending a Sentence):
* texinfo/texinfo.texi (Ending a Sentence):
* texinfo/texinfo.texi (Multiple Spaces):
* texinfo/texinfo.texi (frenchspacing):
* texinfo/texinfo.texi (dmn):
* texinfo/texinfo.texi (Inserting Accents):
* texinfo/texinfo.texi (Inserting Quotation Marks):
* texinfo/texinfo.texi (Dots Bullets):
* texinfo/texinfo.texi (dots):
* texinfo/texinfo.texi (bullet):
* texinfo/texinfo.texi (TeX and copyright):
* texinfo/texinfo.texi (tex):
* texinfo/texinfo.texi (copyright symbol):
* texinfo/texinfo.texi (registered symbol):
* texinfo/texinfo.texi (euro):
* texinfo/texinfo.texi (pounds):
* texinfo/texinfo.texi (textdegree):
* texinfo/texinfo.texi (minus):
* texinfo/texinfo.texi (geq leq):
* texinfo/texinfo.texi (math):
* texinfo/texinfo.texi (Click Sequences):
* texinfo/texinfo.texi (Glyphs):
* texinfo/texinfo.texi (Glyphs Summary):
* texinfo/texinfo.texi (result):
* texinfo/texinfo.texi (expansion):
* texinfo/texinfo.texi (Print Glyph):
* texinfo/texinfo.texi (Error Glyph):
* texinfo/texinfo.texi (Equivalence):
* texinfo/texinfo.texi (Point Glyph):
* texinfo/texinfo.texi (Breaks):
* texinfo/texinfo.texi (Break Commands):
* texinfo/texinfo.texi (Line Breaks):
* texinfo/texinfo.texi (- and hyphenation):
* texinfo/texinfo.texi (allowcodebreaks):
* texinfo/texinfo.texi (w):
* texinfo/texinfo.texi (tie):
* texinfo/texinfo.texi (sp):
* texinfo/texinfo.texi (page):
* texinfo/texinfo.texi (group):
* texinfo/texinfo.texi (need):
* texinfo/texinfo.texi (Definition Commands):
* texinfo/texinfo.texi (Def Cmd Template):
* texinfo/texinfo.texi (Def Cmd Continuation Lines):
* texinfo/texinfo.texi (Optional Arguments):
* texinfo/texinfo.texi (deffnx):
* texinfo/texinfo.texi (Def Cmds in Detail):
* texinfo/texinfo.texi (Functions Commands):
* texinfo/texinfo.texi (Variables Commands):
* texinfo/texinfo.texi (Typed Functions):
* texinfo/texinfo.texi (Typed Variables):
* texinfo/texinfo.texi (Data Types):
* texinfo/texinfo.texi (Abstract Objects):
* texinfo/texinfo.texi (Object-Oriented Variables):
* texinfo/texinfo.texi (Object-Oriented Methods):
* texinfo/texinfo.texi (Defining Macros):
* texinfo/texinfo.texi (Invoking Macros):
* texinfo/texinfo.texi (Macro Details):
* texinfo/texinfo.texi (alias):
* texinfo/texinfo.texi (definfoenclose):
* texinfo/texinfo.texi (Hardcopy):
* texinfo/texinfo.texi (Use TeX):
* texinfo/texinfo.texi (Format with tex/texindex):
* texinfo/texinfo.texi (Format with texi2dvi):
* texinfo/texinfo.texi (Print with lpr):
* texinfo/texinfo.texi (Within XEmacs):
* texinfo/texinfo.texi (Texinfo Mode Printing):
* texinfo/texinfo.texi (Compile-Command):
* texinfo/texinfo.texi (Requirements Summary):
* texinfo/texinfo.texi (Preparing for TeX):
* texinfo/texinfo.texi (Overfull hboxes):
* texinfo/texinfo.texi (smallbook):
* texinfo/texinfo.texi (A4 Paper):
* texinfo/texinfo.texi (pagesizes):
* texinfo/texinfo.texi (Cropmarks and Magnification):
* texinfo/texinfo.texi (PDF Output):
* texinfo/texinfo.texi (Obtaining TeX):
* texinfo/texinfo.texi (Creating and Installing Info Files):
* texinfo/texinfo.texi (Creating an Info File):
* texinfo/texinfo.texi (makeinfo advantages):
* texinfo/texinfo.texi (Invoking makeinfo):
* texinfo/texinfo.texi (makeinfo options):
* texinfo/texinfo.texi (Pointer Validation):
* texinfo/texinfo.texi (makeinfo in XEmacs):
* texinfo/texinfo.texi (texinfo-format commands):
* texinfo/texinfo.texi (Batch Formatting):
* texinfo/texinfo.texi (Tag and Split Files):
* texinfo/texinfo.texi (Installing an Info File):
* texinfo/texinfo.texi (Directory File):
* texinfo/texinfo.texi (New Info File):
* texinfo/texinfo.texi (Other Info Directories):
* texinfo/texinfo.texi (Installing Dir Entries):
* texinfo/texinfo.texi (Invoking install-info):
* texinfo/texinfo.texi (Generating HTML):
* texinfo/texinfo.texi (HTML Translation):
* texinfo/texinfo.texi (HTML Splitting):
* texinfo/texinfo.texi (HTML CSS):
* texinfo/texinfo.texi (HTML Xref):
* texinfo/texinfo.texi (HTML Xref Link Basics):
* texinfo/texinfo.texi (HTML Xref Node Name Expansion):
* texinfo/texinfo.texi (HTML Xref Command Expansion):
* texinfo/texinfo.texi (HTML Xref 8-bit Character Expansion):
* texinfo/texinfo.texi (HTML Xref Mismatch):
* texinfo/texinfo.texi (Command List):
* texinfo/texinfo.texi (Command Syntax):
* texinfo/texinfo.texi (Tips):
* texinfo/texinfo.texi (Sample Texinfo Files):
* texinfo/texinfo.texi (Short Sample Texinfo File):
* texinfo/texinfo.texi (GNU Sample Texts):
* texinfo/texinfo.texi (Invoking sample):
* texinfo/texinfo.texi (GNU Free Documentation License):
* texinfo/texinfo.texi (Index):
* texinfo/texinfo.texi (Verbatim Copying License):
* texinfo/texinfo.texi (All-permissive Copying License):
* texinfo/texinfo.texi (Include Files):
* texinfo/texinfo.texi (Using Include Files):
* texinfo/texinfo.texi (texinfo-multiple-files-update):
* texinfo/texinfo.texi (Include Files Requirements):
* texinfo/texinfo.texi (Sample Include File):
* texinfo/texinfo.texi (Include Files Evolution):
* texinfo/texinfo.texi (Headings):
* texinfo/texinfo.texi (Headings Introduced):
* texinfo/texinfo.texi (Heading Format):
* texinfo/texinfo.texi (Heading Choice):
* texinfo/texinfo.texi (Custom Headings):
* texinfo/texinfo.texi (Catching Mistakes):
* texinfo/texinfo.texi (makeinfo Preferred):
* texinfo/texinfo.texi (Debugging with Info):
* texinfo/texinfo.texi (Debugging with TeX):
* texinfo/texinfo.texi (Using texinfo-show-structure):
* texinfo/texinfo.texi (Using occur):
* texinfo/texinfo.texi (Running Info-Validate):
* texinfo/texinfo.texi (Using Info-validate):
* texinfo/texinfo.texi (Unsplit):
* texinfo/texinfo.texi (Tagifying):
* texinfo/texinfo.texi (Splitting):
* texinfo/texinfo.texi (Refilling Paragraphs):
* texinfo/texinfo.texi (Command and Variable Index):
* texinfo/texinfo.texi (General Index):
* texinfo/version.texi: New file.
Sync with FSF 23.1.92. Make new directory to hold the files needed
to generate texinfo.info, since there are three such files now.
2010-02-19 Ben Wing <ben@xemacs.org>
* Makefile:
* Makefile (src_files1):
* Makefile (DIR):
* Makefile (texinfo-srcs):
* Makefile ($(INFODIR)/widget.info):
* Makefile ($(INFODIR)/texinfo.info):
* Makefile (.PHONY):
* Makefile (texinfo.dvi):
* Makefile (texinfo.pdf):
* Makefile ($(HTMLDIR)/widget.html):
* Makefile ($(HTMLDIR)/texinfo.html):
Incorporate texinfo.texi moving to a subdirectory texinfo/.
Do some tricks to reduce the amount of duplication while still
maintaining compatible with non-GNU make (at least, with
Solaris make).
* doclicense.texi: New file.
* info.texi:
* info.texi (Top):
* info.texi (Getting Started):
* info.texi (Help-Small-Screen):
* info.texi (Help):
* info.texi (Help-P):
* info.texi (Help-^L):
* info.texi (Help-Inv):
* info.texi (Help-]):
* info.texi (Help-M):
* info.texi (Help-FOO):
* info.texi (Help-Xref):
* info.texi (Help-Int):
* info.texi (Help-Q):
* info.texi (Advanced):
* info.texi (Search Text):
* info.texi (Search Index):
* info.texi (Go to node):
* info.texi (Choose menu subtopic):
* info.texi (Create Info buffer):
* info.texi (XEmacs Info Variables):
* info.texi (Expert Info):
* info.texi (Add):
* info.texi (Menus):
* info.texi (Cross-refs):
* info.texi (Help-Cross):
* info.texi (Tags):
* info.texi (Checking):
* info.texi (Index):
* texinfo.tex:
* texinfo.tex (paragraphindent{%):
* texinfo.tex (sectionheading will have):
* texinfo.tex (chapterzzz{#3}%):
* texinfo.tex (subsubsection = \numberedsubsubsec):
* texinfo.tex (subsubsection = \appendixsubsubsec):
* texinfo.tex (subsubsection = \unnumberedsubsubsec):
* texinfo.tex (sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%):
* texinfo.tex (sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%):
* texinfo.tex (sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%):
* texinfo.tex (sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%):
* texinfo.tex (sectionheading{#1}{subsec}{Yappendix}%):
* texinfo.tex (sectionheading{#1}{subsec}{Ynothing}%):
* texinfo.tex (sectionheading{#1}{subsubsec}{Ynumbered}%):
* texinfo.tex (sectionheading{#1}{subsubsec}{Yappendix}%):
* texinfo.tex (sectionheading{#1}{subsubsec}{Ynothing}%):
* texinfo.tex (sectionheading{#1}{subsubsec}{Yomitfromtoc}{}):
* texinfo.tex (sectionheading to do the printing.):
* texinfo.tex (sectionlevel}{#1}{#4}%):
* texinfo.tex (sectionheading, q.v.):
Sync with FSF 23.1.92.
| author | Ben Wing <ben@xemacs.org> |
|---|---|
| date | Fri, 19 Feb 2010 22:39:19 -0600 |
| parents | 3ecd8885ac67 |
| children | 308d34e9f07d |
| rev | line source |
|---|---|
| 428 | 1 ;;; undo-stack.el --- An "undoable stack" object. |
| 2 | |
| 3 ;; Copyright (C) 1997 Free Software Foundation, Inc. | |
| 4 ;; Copyright (C) 1996 Ben Wing. | |
| 5 | |
| 6 ;; Maintainer: XEmacs Development Team | |
| 7 ;; Keywords: extensions, dumped | |
| 8 | |
| 9 ;; This file is part of XEmacs. | |
| 10 | |
| 11 ;; XEmacs is free software; you can redistribute it and/or modify it | |
| 12 ;; under the terms of the GNU General Public License as published by | |
| 13 ;; the Free Software Foundation; either version 2, or (at your option) | |
| 14 ;; any later version. | |
| 15 | |
| 16 ;; XEmacs is distributed in the hope that it will be useful, but | |
| 17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 19 ;; General Public License for more details. | |
| 20 | |
| 21 ;; You should have received a copy of the GNU General Public License | |
| 22 ;; along with XEmacs; see the file COPYING. If not, write to the | |
| 23 ;; Free Software Foundation, 59 Temple Place - Suite 330, | |
| 24 ;; Boston, MA 02111-1307, USA. | |
| 25 | |
| 26 ;;; Synched up with: Not in FSF. | |
| 27 | |
| 28 ;;; Commentary: | |
| 29 | |
| 30 ;; This file is dumped with XEmacs. | |
| 31 | |
| 32 ;; An "undoable stack" is an object that can be used to implement | |
| 33 ;; a history of positions, with undo and redo. Conceptually, it | |
| 34 ;; is the kind of data structure used to keep track of (e.g.) | |
| 35 ;; visited Web pages, so that the "Back" and "Forward" operations | |
| 36 ;; in the browser work. Basically, I can successively visit a | |
| 37 ;; number of Web pages through links, and then hit "Back" a | |
| 38 ;; few times to go to previous positions, and then "Forward" a | |
| 39 ;; few times to reverse this process. This is similar to an | |
| 40 ;; "undo" and "redo" mechanism. | |
| 41 | |
| 42 ;; Note that Emacs does not standardly contain structures like | |
| 43 ;; this. Instead, it implements history using either a ring | |
| 44 ;; (the kill ring, the mark ring), or something like the undo | |
| 45 ;; stack, where successive "undo" operations get recorded as | |
| 46 ;; normal modifications, so that if you do a bunch of successive | |
| 47 ;; undo's, then something else, then start undoing, you will | |
| 48 ;; be redoing all your undo's back to the point before you did | |
| 49 ;; the undo's, and then further undo's will act like the previous | |
| 50 ;; round of undo's. I think that both of these paradigms are | |
| 51 ;; inferior to the "undoable-stack" paradigm because they're | |
| 52 ;; confusing and difficult to keep track of. | |
| 53 | |
| 54 ;; Conceptually, imagine a position history like this: | |
| 55 | |
| 56 ;; 1 -> 2 -> 3 -> 4 -> 5 -> 6 | |
| 57 ;; ^^ | |
| 58 | |
| 59 ;; where the arrow indicates where you currently are. "Going back" | |
| 60 ;; and "going forward" just amount to moving the arrow. However, | |
| 61 ;; what happens if the history state is this: | |
| 62 | |
| 63 ;; 1 -> 2 -> 3 -> 4 -> 5 -> 6 | |
| 64 ;; ^^ | |
| 65 | |
| 66 ;; and then I visit new positions (7) and (8)? In the most general | |
| 67 ;; implementation, you've just caused a new branch like this: | |
| 68 | |
| 69 ;; 1 -> 2 -> 3 -> 4 -> 5 -> 6 | |
| 70 ;; | | |
| 71 ;; | | |
| 72 ;; 7 -> 8 | |
| 73 ;; ^^ | |
| 74 | |
| 75 ;; But then you can end up with a whole big tree, and you need | |
| 76 ;; more sophisticated ways of navigating ("Forward" might involve | |
| 77 ;; a choice of paths to follow) and managing its size (if you don't | |
| 78 ;; want to keep unlimited history, you have to truncate at some point, | |
| 79 ;; and how do you truncate a tree?) | |
| 80 | |
| 81 ;; My solution to this is just to insert the new positions like | |
| 82 ;; this: | |
| 83 | |
| 84 ;; 1 -> 2 -> 3 -> 4 -> 7 -> 8 -> 5 -> 6 | |
| 85 ;; ^^ | |
| 86 | |
| 87 ;; (Netscape, I think, would just truncate 5 and 6 completely, | |
| 88 ;; but that seems a bit drastic. In the Emacs-standard "ring" | |
| 89 ;; structure, this problem is avoided by simply moving 5 and 6 | |
| 90 ;; to the beginning of the ring. However, it doesn't seem | |
| 91 ;; logical to me to have "going back past 1" get you to 6.) | |
| 92 | |
| 93 ;; Now what if we have a "maximum" size of (say) 7 elements? | |
| 94 ;; When we add 8, we could truncate either 1 or 6. Since 5 and | |
| 95 ;; 6 are "undone" positions, we should presumably truncate | |
| 96 ;; them before 1. So, adding 8 truncates 6, adding 9 truncates | |
| 97 ;; 5, and adding 10 truncates 1 because there is nothing more | |
| 98 ;; that is forward of the insertion point. | |
| 99 | |
| 100 ;; Interestingly, this method of truncation is almost like | |
| 101 ;; how a ring would truncate. A ring would move 5 and 6 | |
| 102 ;; around to the back, like this: | |
| 103 | |
| 104 ;; 5 -> 6 -> 1 -> 2 -> 3 -> 4 -> 7 -> 8 | |
| 105 ;; ^^ | |
| 106 | |
| 107 ;; However, when 8 is added, the ring truncates 5 instead of | |
| 108 ;; 6, which is less than optimal. | |
| 109 | |
| 110 ;; Conceptually, we can implement the "undoable stack" using | |
| 111 ;; two stacks of a sort called "truncatable stack", which are | |
| 112 ;; just simple stacks, but where you can truncate elements | |
| 113 ;; off of the bottom of the stack. Then, the undoable stack | |
| 114 | |
| 115 ;; 1 -> 2 -> 3 -> 4 -> 5 -> 6 | |
| 116 ;; ^^ | |
| 117 | |
| 118 ;; is equivalent to two truncatable stacks: | |
| 119 | |
| 120 ;; 4 <- 3 <- 2 <- 1 | |
| 121 ;; 5 <- 6 | |
| 122 | |
| 123 ;; where I reversed the direction to accord with the probable | |
| 124 ;; implementation of a standard list. To do another undo, | |
| 125 ;; I pop 4 off of the first stack and move it to the top of | |
| 126 ;; the second stack. A redo operation does the opposite. | |
| 127 ;; To truncate to the proper size, first chop off 6, then 5, | |
| 128 ;; then 1 -- in all cases, truncating off the bottom. | |
| 129 | |
| 130 ;;; Code: | |
| 131 | |
| 132 (define-error 'trunc-stack-bottom "Bottom of stack reached") | |
| 133 | |
| 134 (defsubst trunc-stack-stack (stack) | |
| 135 ;; return the list representing the trunc-stack's elements. | |
| 136 ;; the head of the list is the most recent element. | |
| 137 (aref stack 1)) | |
| 138 | |
| 139 (defsubst trunc-stack-length (stack) | |
| 140 ;; return the number of elements in the trunc-stack. | |
| 141 (aref stack 2)) | |
| 142 | |
| 143 (defsubst set-trunc-stack-stack (stack new) | |
| 144 ;; set the list representing the trunc-stack's elements. | |
| 145 (aset stack 1 new)) | |
| 146 | |
| 147 (defsubst set-trunc-stack-length (stack new) | |
| 148 ;; set the length of the trunc-stack. | |
| 149 (aset stack 2 new)) | |
| 150 | |
| 151 ;; public functions: | |
| 152 | |
| 153 (defun make-trunc-stack () | |
| 154 ;; make an empty trunc-stack. | |
| 155 (vector 'trunc-stack nil 0)) | |
| 156 | |
| 157 (defun trunc-stack-push (stack el) | |
| 158 ;; push a new element onto the head of the trunc-stack. | |
| 159 (set-trunc-stack-stack stack (cons el (trunc-stack-stack stack))) | |
| 160 (set-trunc-stack-length stack (1+ (trunc-stack-length stack)))) | |
| 161 | |
| 162 (defun trunc-stack-top (stack &optional n) | |
| 163 ;; return the nth topmost element from the trunc-stack. | |
| 164 ;; signal an error if the stack doesn't have that many elements. | |
| 165 (or n (setq n 0)) | |
| 166 (if (>= n (trunc-stack-length stack)) | |
| 167 (signal-error 'trunc-stack-bottom (list stack)) | |
| 168 (nth n (trunc-stack-stack stack)))) | |
| 169 | |
| 170 (defun trunc-stack-pop (stack) | |
| 171 ;; pop and return the topmost element from the stack. | |
| 172 (prog1 (trunc-stack-top stack) | |
| 173 (set-trunc-stack-stack stack (cdr (trunc-stack-stack stack))) | |
| 174 (set-trunc-stack-length stack (1- (trunc-stack-length stack))))) | |
| 175 | |
| 176 (defun trunc-stack-truncate (stack &optional n) | |
| 177 ;; truncate N items off the bottom of the stack. If the stack is | |
| 178 ;; not that big, it just becomes empty. | |
| 179 (or n (setq n 1)) | |
| 180 (if (> n 0) | |
| 181 (let ((len (trunc-stack-length stack))) | |
| 182 (if (>= n len) | |
| 183 (progn | |
| 184 (set-trunc-stack-length stack 0) | |
| 185 (set-trunc-stack-stack stack nil)) | |
| 186 (setcdr (nthcdr (1- (- len n)) (trunc-stack-stack stack)) nil) | |
| 187 (set-trunc-stack-length stack (- len n)))))) | |
| 188 | |
| 189 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| 190 | |
| 191 ;;; FMH! FMH! FMH! This object-oriented stuff doesn't really work | |
| 192 ;;; properly without built-in structures (vectors suck) and without | |
| 193 ;;; public and private functions and fields. | |
| 194 | |
| 195 (defsubst undoable-stack-max (stack) | |
| 196 (aref stack 1)) | |
| 197 | |
| 198 (defsubst undoable-stack-a (stack) | |
| 199 (aref stack 2)) | |
| 200 | |
| 201 (defsubst undoable-stack-b (stack) | |
| 202 (aref stack 3)) | |
| 203 | |
| 204 ;; public functions: | |
| 205 | |
| 206 (defun make-undoable-stack (max) | |
| 207 ;; make an empty undoable stack of max size MAX. | |
| 208 (vector 'undoable-stack max (make-trunc-stack) (make-trunc-stack))) | |
| 209 | |
| 210 (defsubst set-undoable-stack-max (stack new) | |
| 211 ;; change the max size of an undoable stack. | |
| 212 (aset stack 1 new)) | |
| 213 | |
| 214 (defun undoable-stack-a-top (stack) | |
| 215 ;; return the topmost element off the "A" stack of an undoable stack. | |
| 216 ;; this is the most recent position pushed on the undoable stack. | |
| 217 (trunc-stack-top (undoable-stack-a stack))) | |
| 218 | |
| 219 (defun undoable-stack-a-length (stack) | |
| 220 (trunc-stack-length (undoable-stack-a stack))) | |
| 221 | |
| 222 (defun undoable-stack-b-top (stack) | |
| 223 ;; return the topmost element off the "B" stack of an undoable stack. | |
| 224 ;; this is the position that will become the most recent position, | |
| 225 ;; after a redo operation. | |
| 226 (trunc-stack-top (undoable-stack-b stack))) | |
| 227 | |
| 228 (defun undoable-stack-b-length (stack) | |
| 229 (trunc-stack-length (undoable-stack-b stack))) | |
| 230 | |
| 231 (defun undoable-stack-push (stack el) | |
| 232 ;; push an element onto the stack. | |
| 233 (let* | |
| 234 ((lena (trunc-stack-length (undoable-stack-a stack))) | |
| 235 (lenb (trunc-stack-length (undoable-stack-b stack))) | |
| 236 (max (undoable-stack-max stack)) | |
| 237 (len (+ lena lenb))) | |
| 238 ;; maybe truncate some elements. We have to deal with the | |
| 239 ;; possibility that we have more elements than our max | |
| 240 ;; (someone might have reduced the max). | |
| 241 (if (>= len max) | |
| 242 (let ((must-nuke (1+ (- len max)))) | |
| 243 ;; chop off must-nuke elements from the B stack. | |
| 244 (trunc-stack-truncate (undoable-stack-b stack) must-nuke) | |
| 245 ;; but if there weren't that many elements to chop, | |
| 246 ;; take the rest off the A stack. | |
| 247 (if (< lenb must-nuke) | |
| 248 (trunc-stack-truncate (undoable-stack-a stack) | |
| 249 (- must-nuke lenb))))) | |
| 250 (trunc-stack-push (undoable-stack-a stack) el))) | |
| 251 | |
| 252 (defun undoable-stack-pop (stack) | |
| 253 ;; pop an element off the stack. | |
| 254 (trunc-stack-pop (undoable-stack-a stack))) | |
| 255 | |
| 256 (defun undoable-stack-undo (stack) | |
| 257 ;; transfer an element from the top of A to the top of B. | |
| 258 ;; return value is undefined. | |
| 259 (trunc-stack-push (undoable-stack-b stack) | |
| 260 (trunc-stack-pop (undoable-stack-a stack)))) | |
| 261 | |
| 262 (defun undoable-stack-redo (stack) | |
| 263 ;; transfer an element from the top of B to the top of A. | |
| 264 ;; return value is undefined. | |
| 265 (trunc-stack-push (undoable-stack-a stack) | |
| 266 (trunc-stack-pop (undoable-stack-b stack)))) | |
| 267 | |
| 268 | |
| 269 ;;; undo-stack.el ends here |
