\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#449: [text] undo/redo to Return Range of Characters}
\date{June 07, 2016}
\author{François Vogel}
\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 \#449}&\textbf{[text] undo/redo to Return Range of Characters}\\\hline
Author&

François Vogel \tipmail{fvogelnew1}{free.fr}
\\
Created&Tuesday, \(\text{7}^{\text{th}}\) June 2016\\
Type&Project\\
Tcl Version&\(8.7\)\\
State&Final\\
Vote&Done\\
Version&\tipversion$Revision: 1.12 $\\
Keywords&Tk\\
Post History&\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

Tk features an undo/redo mechanism for the \textbf{text} widget. This TIP proposes that the \textbf{edit undo} and \textbf{edit redo} commands of the text widget return the ranges of characters impacted by the undo or redo operation.
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{Rationale}

In some applications using the \textbf{text} widget, say a text editor, modern practice is to show the text with highlighting, colorization, or any other ways of improving readablity for the human user. When undoing/redoing changes in the text, these applications need to know which characters were impacted by the undo or redo operation. This can be done by comparing the \textbf{text} widget contents before the change with its contents after the change, but this is very far from optimal especially with large texts.

Therefore a better way to get this information is proposed in the present TIP.

This feature was requested for the text widget in RFE 1217222 [\url{https://core.tcl.tk/tk/tktview/1217222}]

\section{Proposed Change}

Currently, \textbf{edit undo} and \textbf{edit redo} commands return the empty string.

It is proposed to change this return value and make these commands return the ranges of indices that were impacted by the undo or redo operation.

This return value is a list of indices, with an even number of elements. Indeed, there can be several edits (insertions and deletions) between two separators in the undo stack and all such edits have to report which range of text they changed.

The returned ranges are made of indices making sense at undo/redo return time, i.e. they refer to the text widget content at the time \textbf{edit undo} and \textbf{edit redo} return. Moreover, the returned list of indices is optimal, in the sense that the ranges contained in that list are all disjoint (overlapping ranges are merged, and ranges already contained in another range are not returned).

\section{Backwards Compatibility}

The proposed implementation makes use of temporary marks, that only exist \textit{during} an undo or redo operation (and never before or after these operations). This could be seen as a concern regarding backwards compatibility, however it is believed that the names of these marks has been chosen such that this should not be an issue. The chosen name is \textbf{tk::undoMark\tiplangle{}g\tiprangle{}\tiplangle{}ID\tiprangle{}}, where \textbf{\tiplangle{}g\tiprangle{}} is either \textbf{L} or \textbf{R}, and \textbf{\tiplangle{}ID\tiprangle{}} is an integer identifier. The risk of name collision is therefore deemed very low due to prefixing by \textbf{tk::}. This naming convention follows what is already existing in the text widget (internal anchors).

\section{Example}
\begingroup\small\begin{verbatim}
  package require Tk

  pack [text .t -undo true]
  .t insert end "Hello World.\n"
  .t edit separator
  .t insert end "Again hello.\n"

  .t edit undo  ; # will now return {2.0 3.0}
  .t edit redo  ; # will now return {2.0 3.0}

\end{verbatim}
\endgroup

More examples can be found by studying the new tests in the feature branch tip-449 hosting the development.

\section{Reference Implementation}

A reference implementation is available in branch tip-449 of the Tk fossil repository.

This new capability is implemented entirely in the code of the text widget. The undo/redo generic code (in \textit{generic/tkUndo.c}) is untouched.

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\end{document}
