summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--library/text.tcl40
-rw-r--r--tests/text.test89
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]