The Tk text widget, in 8.4 or newer, has a nice '.text configure -undo 1' support for an unlimited undo/redo stack for textual insertions/deletions. This is particularly useful for text editors that make use of the Tk text widget. The mechanism is at the same time robust to being renamed and fragile to it: Renaming with overloading: text .t -undo 1 .t insert end "hello there" rename .t my.t proc .t {args} { puts "captured: $args" ; uplevel 1 my.t $args } .t undo edit The above will work and the overloading proc ''.t'' will intercept the undo operation. This allows ''.t'' to perform actions like colouring any new text that has appeared (either because a delete operation has been undone, or because the widget has scrolled as a result of the action). But, if you rename and do not overload: text .t -undo 1 .t insert end "hello there" rename .t my.t #proc .t {args} { puts "captured: $args" ; uplevel 1 my.t $args } .t undo edit Then this will throw an error ''invalid command name ".t"''. While it would be easy to make the undo mechanism always use the current ''widgetCmd'' data structure (and hence fix this second example), it would break the first example. And the first example is important -- an undo/redo action can trigger scrolling, changing of the 'insert' position, text appearing or disappearing, etc. The programmer needs to have the capability to notice exactly what has happened and take appropriate action! Finally, this is further complicated with TIP#169, in which ''peer text widgets'' were introduced, which may show all or part of the underlying textual data. With these peer widgets, it could be that an undo operation may or may not apply to what is currently shown (at least in the current peer): text .t -undo 0 for {set i 0} {$i < 20} {incr i} { .t insert end "hello there $i" } text .t -undo 1 .t insert end "add one more line" # Only show the middle 10 lines .t configure -startline 5 -endline 15 # This should undo the action that isn't visible? .t undo edit So, we need a more flexible solution to these problems. One such solution would be to provide the text widget with a callback or event mechanism. For example, we could envisage new virtual events: <>, <> (and <> ?) whose ''user_data'' field contains further relevant information: [list $start_idx $end_idx $characters] so that any client can easily capture whatever information it needs about the action that just took place. This would certainly work well if we ignore the complications of peer text widgets. Perhaps ''<>'' would be a better virtual event. Perhaps a minor modification to it might also resolve the situation there as well? ---- [EB]: I have found a workaround for having the undo mecanism calling the overloaded command instead of the widget command. In fact, to perform undo (or redo), ''[[$path edit undo]]'' recalls all necessary insert/delete on $path '''in the global namespace''', so renaming the widget with the same name inside a namespace and invoking ''[[$path edit undo]]'' inside that namespace will invoke the wrapper when calling the insert/delete: namespace eval editor {} proc editor::editor {path args} { set path [eval [list text $path] $args] rename $path ::editor::$path interp alias {} $path {} ::editor::TextWrapper $path return $path } proc editor::TextWrapper {path cmd args} { switch $cmd { ... default { # [$path edit undo] will recall $path the global namespace, our wrapper. return [eval [list $path $cmd] $args] } } [Vince] -- interesting!