TIP #449: [text] undo/redo to Return Range of Characters
_____________________________________________________________________________
TIP:	449
Title:	[text] undo/redo to Return Range of Characters
Version:	$Revision: 1.12 $
Authors:	François Vogel <fvogelnew1@free.fr>
State:	Final
Type:	Project
Tcl-Version:	8.7
Vote:	Done
Created:	Tue Jun 07 00:00:00 UTC 2016
Keywords:	Tk
Abstract
Tk features an undo/redo mechanism for the text widget. This TIP proposes that the edit undo and edit redo commands of the text widget return the ranges of characters impacted by the undo or redo operation.
Rationale
In some applications using the 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 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 [https://core.tcl.tk/tk/tktview/1217222]
Proposed Change
Currently, edit undo and 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 edit undo and 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).
Backwards Compatibility
The proposed implementation makes use of temporary marks, that only exist 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 tk::undoMark<g><ID>, where <g> is either L or R, and <ID> is an integer identifier. The risk of name collision is therefore deemed very low due to prefixing by tk::. This naming convention follows what is already existing in the text widget (internal anchors).
Example
  package require Tk

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

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

More examples can be found by studying the new tests in the feature branch tip-449 hosting the development.
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 generic/tkUndo.c) is untouched.
Copyright
This document has been placed in the public domain.
_____________________________________________________________________________
Colophon
TIP AutoGenerator - written by Donal K. Fellows