\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#104: Generalization of the Tk Undo Subsystem}
\date{June 19, 2002}
\author{Ludwig Callewaert, Larry W. Virden.}
\urlstyle{sf}
\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}
\def\tipversion$#1${\texttt{\$#1\$}}
\def\tiplangle#1{\ensuremath{<}}
\def\tiprangle#1{\ensuremath{>}}
\def\tipbar#1{\ensuremath{|}}
\def\tipmail#1#2{\(\langle\){\small\expandafter\url{#1@#2}}\(\rangle\)}
\ifx\pdfoutput\undefined
\newcommand{\tipimage}[2]{\typeout{Make sure you download #1.eps}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.eps}}{\includegraphics[width=0.8\textwidth]{#1.eps}}}
\newcommand{\tipxref}[1]{}
\newcommand{\tipxrefend}{}
\else
\newcommand{\tipimage}[2]{\typeout{Make sure you create #1.pdf}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.pdf}}{\includegraphics[width=0.8\textwidth]{#1.pdf}}}
\pdfcatalog{/PageMode /UseOutlines}
\newcommand{\tipxref}[1]{\pdfannotlink attr {/C [0.5 0.5 1.0] /Border [0 0 1]} goto name {#1}}
\newcommand{\tipxrefend}{\pdfendlink}
\fi
\newenvironment{tipabstract}{\begin{abstract}}{\end{abstract}}
\begin{document}\maketitle
\begin{center}\begin{tabularx}{\linewidth}{|r@{: }X|}\hline
\textbf{TIP \#104}&\textbf{Generalization of the Tk Undo Subsystem}\\\hline
Author&

Ludwig Callewaert \tipmail{ludwig.callewaert}{belgacom.net}
\par
Larry W. Virden. \tipmail{lvirden}{yahoo.com}
\\
Created&Wednesday, \(\text{19}^{\text{th}}\) June 2002\\
Type&Project\\
Tcl Version&\(8.4\)\\
State&Final\\
Vote&Done\\
Version&\tipversion$Revision: 1.6 $\\
Post History&\\
Discussions To&news:comp.lang.tcl\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

This TIP proposes a reimplementation of the Tk Text widget undo feature. The text widget interface is not affected. No functional changes are made at the Tcl level. The purpose of the reimplementation is to move the undo feature from a text only implementation to a general implementation also usable by other widgets. This opens the door to undoing also tag, mark and other operations, and allows for an exposure of the undo stack at the Tcl level. These new features are however not part of this TIP.
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{Rationale}

As stated in the abstract, the current implementation of the text widget undo feature only allows for text changes to be undone. The usefulness of the undo feature would increase tremendously if other operations could be undone (tags, marks, embedded windows, ...). This was already part of the \cite{tip26} discussions. This TIP deals with the generalization of the undo stack to cope with these requirements.

\section{Specification}

As the undo functionality is no longer text widget specific, it has been put in a separate file \textit{generic/tkUndo.c} along with its header file \textit{generic/tkUndo.h}. The \textit{TkUndoRedoStack} is a structure containing the undo and redo stacks. These undo and redo stacks are linked lists of \textit{TkUndoAtom} structures. There are two types of these atoms: the separator (similar to the previous implementation) and the command. When the type is command, both an \textit{apply} and a \textit{revert} action need to be provided. The apply action is for the redo. The revert action is for the undo. Both are pointers to a \textit{Tcl\_Obj}, so they can (and should) contain a Tcl script.

The following functions all operating on a \textit{TkUndoRedoStack} stack are provided to implement the undo/redo functionality.
\begin{description}
\item[1. ''TkUndoInitStack(interp)'']
returns a pointer to an initialized TkUndoRedoStack and stores \textit{interp} in that stack for script evaluation.
\item[2. ''TkUndoClearStacks(stack)'']
clears both the undo and the redo stacks.
\item[3. ''TkUndoFreeStack(stack)'']
clears both undo and redo stacks and frees any memory allocated to \textit{stack}.
\item[4. ''TkUndoInsertUndoSeparator(stack)'']
inserts a separator on the undo stack. Note that there is currently no need for a \textit{TkUndoInsertRedoSeparator} function, as the redo stack is managed by the internals of \textit{TkUndo}.
\item[5. ''TkUndoPushAction(stack, actionScript, revertScript)'']
pushes an action of the undo stack (an atom of type command). \textit{actionScript} and \textit{revertScript} are \textit{Tcl\_DString} pointers that provide the script to redo and undo the action respectively. The redo stack is cleared.
\item[6. ''TkUndoRevert(stack)'']
undo a compound action. Compound means all revert script of action between two separators on the undo stack are evaluated in the stack's interpreter and the actions are moved to the redo stack. Returns TCL\_ERROR when unsuccessful (stack empty for instance), and TCL\_OK otherwise.
\item[7. ''TkUndoApply(stack)'']
redo a compound action. The apply script of all actions between two separators on the redo stack is evaluated in the stack's interpreter. The actions are moved to the undo stack. Returns TCL\_ERROR when unsuccessful (stack empty for instance), and TCL\_OK otherwise.
\item[8. ''TkUndoSetDepth(stack, maxDepth)'']
sets the maximum number of compound actions stored on the stack to \textit{maxDepth}. By default, stacks are unlimited, and a value of \textit{maxDepth} \tiplangle{}= 0 resets the stack to be unlimited.
\end{description}
\begin{enumerate}
\setcounter{enumi}{8}
\item{}
The option \textit{-maxundo} is added to the text widget to access the stack limit feature of the text widget's undo stack from the script level.
\end{enumerate}

These functions are sufficient to implement the current undo functionality of the text widget, and they have been used for this purpose.

\section{Reference Implementation}

See patch \#554763 on SourceForge: \textit{ \url{https://sourceforge.net/tracker/?func=detail&atid=312997&aid=554763&group_id=12997} }

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\begin{thebibliography}{TIP \#1}
\addcontentsline{toc}{section}{References}
\bibitem[TIP \#26]{tip26}
Ludwig Callewaert,
Ludwig Callewaert,
\emph{Enhancements for the Tk Text Widget},
on-line at \url{http://purl.org/tcl/tip/26.html}
\end{thebibliography}
\end{document}
