diff options
-rw-r--r-- | library/text.tcl | 40 | ||||
-rw-r--r-- | tests/text.test | 89 |
2 files changed, 129 insertions, 0 deletions
diff --git a/library/text.tcl b/library/text.tcl index 18fed2c..2bf1b2b 100644 --- a/library/text.tcl +++ b/library/text.tcl @@ -85,7 +85,16 @@ bind Text <ButtonRelease-1> { } bind Text <Control-1> { %W mark set insert @%x,%y + # An operation that moves the insert mark without making it + # one end of the selection must insert an autoseparator + if {[%W cget -autoseparators]} { + %W edit separator + } } +# stop an accidental double click triggering <Double-Button-1> +bind Text <Double-Control-1> { # nothing } +# stop an accidental movement triggering <B1-Motion> +bind Text <Control-B1-Motion> { # nothing } bind Text <<PrevChar>> { tk::TextSetCursor %W insert-1displayindices } @@ -245,6 +254,11 @@ bind Text <<SelectAll>> { } bind Text <<SelectNone>> { %W tag remove sel 1.0 end + # An operation that clears the selection must insert an autoseparator, + # because the selection operation may have moved the insert mark + if {[%W cget -autoseparators]} { + %W edit separator + } } bind Text <<Cut>> { tk_textCut %W @@ -256,7 +270,15 @@ bind Text <<Paste>> { tk_textPaste %W } bind Text <<Clear>> { + # Make <<Clear>> an atomic operation on the Undo stack, + # i.e. separate it from other delete operations on either side + if {[%W cget -autoseparators]} { + %W edit separator + } catch {%W delete sel.first sel.last} + if {[%W cget -autoseparators]} { + %W edit separator + } } bind Text <<PasteSelection>> { if {$tk_strictMotif || ![info exists tk::Priv(mouseMoved)] @@ -314,7 +336,16 @@ bind Text <Control-t> { } bind Text <<Undo>> { + # An Undo operation may remove the separator at the top of the Undo stack. + # Then the item at the top of the stack gets merged with the subsequent changes. + # Place separators before and after Undo to prevent this. + if {[%W cget -autoseparators]} { + %W edit separator + } catch { %W edit undo } + if {[%W cget -autoseparators]} { + %W edit separator + } } bind Text <<Redo>> { @@ -1021,9 +1052,18 @@ proc ::tk_textCopy w { proc ::tk_textCut w { if {![catch {set data [$w get sel.first sel.last]}]} { + # make <<Cut>> an atomic operation on the Undo stack, + # i.e. separate it from other delete operations on either side + set oldSeparator [$w cget -autoseparators] + if {$oldSeparator} { + $w edit separator + } clipboard clear -displayof $w clipboard append -displayof $w $data $w delete sel.first sel.last + if {$oldSeparator} { + $w edit separator + } } } diff --git a/tests/text.test b/tests/text.test index 5b85b4f..2112aad 100644 --- a/tests/text.test +++ b/tests/text.test @@ -6172,6 +6172,95 @@ test text-27.18 {patch 1469210 - inserting after undo} -setup { } -cleanup { destroy .t } -result 1 +test text-25.19 {patch 1669632 (i) - undo after <Control-1>} -setup { + destroy .t +} -body { + text .t -undo 1 + .t insert end foo\nbar + .t edit reset + .t insert 2.2 WORLD + event generate .t <Control-1> -x 1 -y 1 + .t insert insert HELLO + .t edit undo + .t get 2.2 2.7 +} -cleanup { + destroy .t +} -result WORLD +test text-25.20 {patch 1669632 (iv) - undo after <<SelectNone>>} -setup { + destroy .top .top.t +} -body { + toplevel .top + pack [text .top.t -undo 1] + .top.t insert end "This is an example text" + .top.t edit reset + .top.t mark set insert 1.5 + .top.t insert 1.5 HELLO + .top.t tag add sel 1.10 1.12 + update + focus -force .top.t + event generate .top.t <<SelectNone>> + .top.t insert insert " WORLD " + .top.t edit undo + .top.t get 1.5 1.10 +} -cleanup { + destroy .top.t .top +} -result HELLO +test text-25.21 {patch 1669632 (vii) - <<Undo>> shall not remove separators} -setup { + destroy .t +} -body { + text .t -undo 1 + .t insert end "This is an example text" + .t edit reset + .t insert 1.5 "WORLD " + event generate .t <Control-1> -x 1 -y 1 + .t insert insert HELLO + event generate .t <<Undo>> + .t insert insert E + event generate .t <<Undo>> + .t get 1.0 "1.0 lineend" +} -cleanup { + destroy .t +} -result "This WORLD is an example text" +test text-25.22 {patch 1669632 (v) - <<Clear>> is atomic} -setup { + destroy .t +} -body { + toplevel .top + pack [text .top.t -undo 1] + .top.t insert end "This is an example text" + .top.t edit reset + .top.t mark set insert 1.5 + .top.t insert 1.5 "A" + update + focus -force .top.t + event generate .top.t <Delete> + event generate .top.t <<SelectNextChar>> + event generate .top.t <<Clear>> + event generate .top.t <Delete> + event generate .top.t <<Undo>> + .top.t get 1.0 "1.0 lineend" +} -cleanup { + destroy .top.t .top +} -result "This A an example text" + test text-25.23 {patch 1669632 (v) - <<Cut>> is atomic} -setup { + destroy .t +} -body { + toplevel .top + pack [text .top.t -undo 1] + .top.t insert end "This is an example text" + .top.t edit reset + .top.t mark set insert 1.5 + .top.t insert 1.5 "A" + update + focus -force .top.t + event generate .top.t <Delete> + event generate .top.t <<SelectNextChar>> + event generate .top.t <<Cut>> + event generate .top.t <Delete> + event generate .top.t <<Undo>> + .top.t get 1.0 "1.0 lineend" +} -cleanup { + destroy .top.t .top +} -result "This A an example text" test text-28.1 {bug fix - 624372, ControlUtfProc long lines} -body { pack [text .t -wrap none] |