Tk Source Code

Changes On Branch tip-686
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch tip-686 Excluding Merge-Ins

This is equivalent to a diff from f25026c5 to 5961ea7d

2024-02-19
12:48
TIP #686: Make NextWord/SelectNextWord behavior platform-independant check-in: 24551291 user: jan.nijtmans tags: core-8-branch
12:36
Merge 8.7 check-in: 1aeab0c8 user: jan.nijtmans tags: trunk, main
08:40
Rebase to latest trunk Closed-Leaf check-in: 5961ea7d user: jan.nijtmans tags: tip-686
2024-02-16
15:46
Merge 9.0 check-in: 056bd45b user: jan.nijtmans tags: revised_text, tip-466
15:29
Merge 8.7 check-in: f25026c5 user: jan.nijtmans tags: trunk, main
15:22
Merge 8.6 check-in: 81c381e8 user: jan.nijtmans tags: core-8-branch
09:03
Merge 8.7 check-in: dac08ee2 user: jan.nijtmans tags: trunk, main
2024-02-14
22:15
variable "State" no longer necessary check-in: b057d795 user: jan.nijtmans tags: tip-686

Changes to library/entry.tcl.

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    tk::EntrySetCursor %W [tk::EntryNextWord %W insert]
}
bind Entry <<SelectPrevWord>> {
    tk::EntryKeySelect %W [tk::EntryPreviousWord %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <<SelectNextWord>> {
    tk::EntryKeySelect %W [tk::EntryNextWord %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <<LineStart>> {
    tk::EntrySetCursor %W 0
}
bind Entry <<SelectLineStart>> {
    tk::EntryKeySelect %W 0







|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    tk::EntrySetCursor %W [tk::EntryNextWord %W insert]
}
bind Entry <<SelectPrevWord>> {
    tk::EntryKeySelect %W [tk::EntryPreviousWord %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <<SelectNextWord>> {
    tk::EntryKeySelect %W [tk::EntrySelectNextWord %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <<LineStart>> {
    tk::EntrySetCursor %W 0
}
bind Entry <<SelectLineStart>> {
    tk::EntryKeySelect %W 0
584
585
586
587
588
589
590

591




592
















593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
    set new [string index $data $i-1][string index $data $first]
    $w delete $first $i
    $w insert insert $new
    EntrySeeInsert $w
}

# ::tk::EntryNextWord --

# Returns the index of the next word position after a given position in the




# entry.  The next word is platform dependent and may be either the next
















# end-of-word position or the next start-of-word position after the next
# end-of-word position.
#
# Arguments:
# w -		The entry window in which the cursor is to move.
# start -	Position at which to start search.

if {[tk windowingsystem] eq "win32"}  {
    proc ::tk::EntryNextWord {w start} {
        # the check on [winfo class] is because the spinbox also uses this proc
        if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
	    return end
	}
	set pos [tk::endOfWord [$w get] [$w index $start]]
	if {$pos >= 0} {
	    set pos [tk::startOfNextWord [$w get] $pos]
	}
	if {$pos < 0} {
	    return end
	}
	return $pos
    }
} else {
    proc ::tk::EntryNextWord {w start} {
        # the check on [winfo class] is because the spinbox also uses this proc
        if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
	    return end
	}
	set pos [tk::endOfWord [$w get] [$w index $start]]
	if {$pos < 0} {
	    return end
	}
	return $pos
    }
}

# ::tk::EntryPreviousWord --
#
# Returns the index of the previous word position before a given
# position in the entry.
#







>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|





<
|
|
|
|
|
|
<
<
<
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<







584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620

621
622
623
624
625
626



627
628
629
630













631
632
633
634
635
636
637
    set new [string index $data $i-1][string index $data $first]
    $w delete $first $i
    $w insert insert $new
    EntrySeeInsert $w
}

# ::tk::EntryNextWord --
# Returns the index of the next start-of-word position after the next
# end-of-word position after a given position in the text.
#
# Arguments:
# w -		The entry window in which the cursor is to move.
# start -	Position at which to start search.

proc ::tk::EntryNextWord {w start} {
    # the check on [winfo class] is because the spinbox also uses this proc
    if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
	return end
    }
    set pos [tk::endOfWord [$w get] [$w index $start]]
    if {$pos >= 0} {
	set pos [tk::startOfNextWord [$w get] $pos]
    }
    if {$pos < 0} {
	return end
    }
    return $pos
}

# ::tk::EntrySelectNextWord --
# Returns the index of the next end-of-word position after a given
# position in the text.
#
# Arguments:
# w -		The entry window in which the cursor is to move.
# start -	Position at which to start search.


proc ::tk::EntrySelectNextWord {w start} {
    # the check on [winfo class] is because the spinbox also uses this proc
    if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
	return end
    }
    set pos [tk::endOfWord [$w get] [$w index $start]]



    if {$pos < 0} {
	return end
    }
    return $pos













}

# ::tk::EntryPreviousWord --
#
# Returns the index of the previous word position before a given
# position in the entry.
#

Changes to library/spinbox.tcl.

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
    ::tk::EntrySetCursor %W [::tk::EntryNextWord %W insert]
}
bind Spinbox <<SelectPrevWord>> {
    ::tk::EntryKeySelect %W [::tk::EntryPreviousWord %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<SelectNextWord>> {
    ::tk::EntryKeySelect %W [::tk::EntryNextWord %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<LineStart>> {
    ::tk::EntrySetCursor %W 0
}
bind Spinbox <<SelectLineStart>> {
    ::tk::EntryKeySelect %W 0







|







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
    ::tk::EntrySetCursor %W [::tk::EntryNextWord %W insert]
}
bind Spinbox <<SelectPrevWord>> {
    ::tk::EntryKeySelect %W [::tk::EntryPreviousWord %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<SelectNextWord>> {
    ::tk::EntryKeySelect %W [::tk::EntrySelectNextWord %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<LineStart>> {
    ::tk::EntrySetCursor %W 0
}
bind Spinbox <<SelectLineStart>> {
    ::tk::EntryKeySelect %W 0

Changes to library/text.tcl.

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
bind Text <<NextPara>> {
    tk::TextSetCursor %W [tk::TextNextPara %W insert]
}
bind Text <<SelectPrevWord>> {
    tk::TextKeySelect %W [tk::TextPrevPos %W insert tk::startOfPreviousWord]
}
bind Text <<SelectNextWord>> {
    tk::TextKeySelect %W [tk::TextNextWord %W insert]
}
bind Text <<SelectPrevPara>> {
    tk::TextKeySelect %W [tk::TextPrevPara %W insert]
}
bind Text <<SelectNextPara>> {
    tk::TextKeySelect %W [tk::TextNextPara %W insert]
}







|







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
bind Text <<NextPara>> {
    tk::TextSetCursor %W [tk::TextNextPara %W insert]
}
bind Text <<SelectPrevWord>> {
    tk::TextKeySelect %W [tk::TextPrevPos %W insert tk::startOfPreviousWord]
}
bind Text <<SelectNextWord>> {
    tk::TextKeySelect %W [tk::TextSelectNextWord %W insert]
}
bind Text <<SelectPrevPara>> {
    tk::TextKeySelect %W [tk::TextPrevPara %W insert]
}
bind Text <<SelectNextPara>> {
    tk::TextKeySelect %W [tk::TextNextPara %W insert]
}
1082
1083
1084
1085
1086
1087
1088

1089




1090






1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
	    $w edit separator
	    $w configure -autoseparators 1
	}
    }
}

# ::tk::TextNextWord --

# Returns the index of the next word position after a given position in the




# text.  The next word is platform dependent and may be either the next






# end-of-word position or the next start-of-word position after the next
# end-of-word position.
#
# Arguments:
# w -		The text window in which the cursor is to move.
# start -	Position at which to start search.

if {[tk windowingsystem] eq "win32"}  {
    proc ::tk::TextNextWord {w start} {
	TextNextPos $w [TextNextPos $w $start tk::endOfWord] \
		tk::startOfNextWord
    }
} else {
    proc ::tk::TextNextWord {w start} {
	TextNextPos $w $start tk::endOfWord
    }
}

# ::tk::TextNextPos --
# Returns the index of the next position after the given starting
# position in the text as computed by a specified function.
#
# Arguments:
# w -		The text window in which the cursor is to move.







>
|
>
>
>
>
|
>
>
>
>
>
>
|
|





<
|
<
<
<
<
<
|
|
|







1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108

1109





1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
	    $w edit separator
	    $w configure -autoseparators 1
	}
    }
}

# ::tk::TextNextWord --
# Returns the index of the next start-of-word position after the next
# end-of-word position after a given position in the text.
#
# Arguments:
# w -		The text window in which the cursor is to move.
# start -	Position at which to start search.

proc ::tk::TextNextWord {w start} {
    TextNextPos $w [TextNextPos $w $start tk::endOfWord] \
	    tk::startOfNextWord
}

# ::tk::TextSelectNextWord --
# Returns the index of the next end-of-word position after a given
# position in the text.
#
# Arguments:
# w -		The text window in which the cursor is to move.
# start -	Position at which to start search.


proc ::tk::TextSelectNextWord {w start} {





    TextNextPos $w $start tk::endOfWord
}


# ::tk::TextNextPos --
# Returns the index of the next position after the given starting
# position in the text as computed by a specified function.
#
# Arguments:
# w -		The text window in which the cursor is to move.

Changes to library/ttk/entry.tcl.

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
bind TEntry <<NextWord>>		{ ttk::entry::Move %W nextword }
bind TEntry <<LineStart>>		{ ttk::entry::Move %W home }
bind TEntry <<LineEnd>>			{ ttk::entry::Move %W end }

bind TEntry <<SelectPrevChar>> 		{ ttk::entry::Extend %W prevchar }
bind TEntry <<SelectNextChar>>		{ ttk::entry::Extend %W nextchar }
bind TEntry <<SelectPrevWord>>		{ ttk::entry::Extend %W prevword }
bind TEntry <<SelectNextWord>>		{ ttk::entry::Extend %W nextword }
bind TEntry <<SelectLineStart>>		{ ttk::entry::Extend %W home }
bind TEntry <<SelectLineEnd>>		{ ttk::entry::Extend %W end }

bind TEntry <<SelectAll>> 		{ %W selection range 0 end }
bind TEntry <<SelectNone>> 		{ %W selection clear }

bind TEntry <<TraverseIn>> 	{ %W selection range 0 end; %W icursor end }







|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
bind TEntry <<NextWord>>		{ ttk::entry::Move %W nextword }
bind TEntry <<LineStart>>		{ ttk::entry::Move %W home }
bind TEntry <<LineEnd>>			{ ttk::entry::Move %W end }

bind TEntry <<SelectPrevChar>> 		{ ttk::entry::Extend %W prevchar }
bind TEntry <<SelectNextChar>>		{ ttk::entry::Extend %W nextchar }
bind TEntry <<SelectPrevWord>>		{ ttk::entry::Extend %W prevword }
bind TEntry <<SelectNextWord>>		{ ttk::entry::Extend %W selectnextword }
bind TEntry <<SelectLineStart>>		{ ttk::entry::Extend %W home }
bind TEntry <<SelectLineEnd>>		{ ttk::entry::Extend %W end }

bind TEntry <<SelectAll>> 		{ %W selection range 0 end }
bind TEntry <<SelectNone>> 		{ %W selection clear }

bind TEntry <<TraverseIn>> 	{ %W selection range 0 end; %W icursor end }
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
















271
272
273
274
275
276
277
    set c [$w index $index]
    # @@@ OR: check [$w index left] / [$w index right]
    if {$c < [$w index @0] || $c >= [$w index @[winfo width $w]]} {
	$w xview $c
    }
}

## NextWord -- Find the next word position.
#	Note: The "next word position" follows platform conventions:
#	either the next end-of-word position, or the start-of-word
#	position following the next end-of-word position.
#
set ::ttk::entry::State(startNext) \
	[string equal [tk windowingsystem] "win32"]

proc ttk::entry::NextWord {w start} {
    # the check on [winfo class] is because the spinbox and combobox also use this proc
    if {[winfo class $w] eq "TEntry" && [$w cget -show] ne ""} {
	return end
    }
    variable State
    set pos [tk::endOfWord [$w get] [$w index $start]]
    if {$pos >= 0 && $State(startNext)} {
	set pos [tk::startOfNextWord [$w get] $pos]
    }
    if {$pos < 0} {
	return end
















    }
    return $pos
}

## PrevWord -- Find the previous word position.
#
proc ttk::entry::PrevWord {w start} {







|
<
|
|

<
<
<





<

|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







244
245
246
247
248
249
250
251

252
253
254



255
256
257
258
259

260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
    set c [$w index $index]
    # @@@ OR: check [$w index left] / [$w index right]
    if {$c < [$w index @0] || $c >= [$w index @[winfo width $w]]} {
	$w xview $c
    }
}

## NextWord --

# Returns the index of the next start-of-word position after the next
# end-of-word position after a given position in the text.
#



proc ttk::entry::NextWord {w start} {
    # the check on [winfo class] is because the spinbox and combobox also use this proc
    if {[winfo class $w] eq "TEntry" && [$w cget -show] ne ""} {
	return end
    }

    set pos [tk::endOfWord [$w get] [$w index $start]]
    if {$pos >= 0} {
	set pos [tk::startOfNextWord [$w get] $pos]
    }
    if {$pos < 0} {
	return end
    }
    return $pos
}

## SelectNextWord --
# Returns the index of the next end-of-word position after a given
# position in the text.
#
proc ttk::entry::SelectNextWord {w start} {
    # the check on [winfo class] is because the spinbox and combobox also use this proc
    if {[winfo class $w] eq "TEntry" && [$w cget -show] ne ""} {
	return end
    }
    set pos [tk::endOfWord [$w get] [$w index $start]]
    if {$pos < 0} {
	return end
    }
    return $pos
}

## PrevWord -- Find the previous word position.
#
proc ttk::entry::PrevWord {w start} {
311
312
313
314
315
316
317

318
319
320
321
322
323
324
#
proc ttk::entry::RelIndex {w where {index insert}} {
    switch -- $where {
	prevchar	{ PrevChar $w $index }
    	nextchar	{ NextChar $w $index }
	prevword	{ PrevWord $w $index }
	nextword	{ NextWord $w $index }

	home		{ return 0 }
	end		{ $w index end }
	default		{ error "Bad relative index $index" }
    }
}

## Move -- Move insert cursor to relative location.







>







322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#
proc ttk::entry::RelIndex {w where {index insert}} {
    switch -- $where {
	prevchar	{ PrevChar $w $index }
    	nextchar	{ NextChar $w $index }
	prevword	{ PrevWord $w $index }
	nextword	{ NextWord $w $index }
	selectnextword	{ SelectNextWord $w $index }
	home		{ return 0 }
	end		{ $w index end }
	default		{ error "Bad relative index $index" }
    }
}

## Move -- Move insert cursor to relative location.

Changes to tests/spinbox.test.

3888
3889
3890
3891
3892
3893
3894

3895
3896
3897
3898
3899
3900






3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
} -cleanup {
    destroy .s
} -result {can't trace "thisnsdoesntexist::myvar": parent namespace doesn't exist}
test spinbox-25.3 {Bugs [2a32225cd1] and [9fa3e08243]} -setup {
    destroy .s
    pack [spinbox .s]
    update

} -body {
    .s insert end "A sample text"
    .s icursor end
    event generate .s <<PrevWord>>  ; # shall move insert to index 9
    .s delete insert end
    .s get






} -cleanup {
    destroy .s
} -result {A sample }

# Collected comments about lacks from the test
# XXX Still need to write tests for SpinboxBlinkProc, SpinboxFocusProc,
# and SpinboxTextVarProc.
# No tests for DisplaySpinbox.
# XXX Still need to write tests for SpinboxScanTo and SpinboxSelectTo.
# No tests for EventuallyRedraw







>





|
>
>
>
>
>
>


|







3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
} -cleanup {
    destroy .s
} -result {can't trace "thisnsdoesntexist::myvar": parent namespace doesn't exist}
test spinbox-25.3 {Bugs [2a32225cd1] and [9fa3e08243]} -setup {
    destroy .s
    pack [spinbox .s]
    update
    set res {}
} -body {
    .s insert end "A sample text"
    .s icursor end
    event generate .s <<PrevWord>>  ; # shall move insert to index 9
    .s delete insert end
    lappend res [.s get]
    .s delete 0 end
    .s insert end "A sample text"
    .s icursor 2
    event generate .s <<NextWord>>  ; # shall move insert to index 9
    .s delete 0 insert
    lappend res [.s get]
} -cleanup {
    destroy .s
} -result {{A sample } text}

# Collected comments about lacks from the test
# XXX Still need to write tests for SpinboxBlinkProc, SpinboxFocusProc,
# and SpinboxTextVarProc.
# No tests for DisplaySpinbox.
# XXX Still need to write tests for SpinboxScanTo and SpinboxSelectTo.
# No tests for EventuallyRedraw

Changes to tests/ttk/spinbox.test.

287
288
289
290
291
292
293

294
295
296
297
298
299






300
301
302
303
304
305
306
307
308
309
    unset -nocomplain ::spinbox_test max
} -result {one two three 4 5 two six six six two 5 4 three two one one one one}

test spinbox-11.2 {Bugs [2a32225cd1] and [9fa3e08243]} -setup {
    destroy .s
    pack [ttk::spinbox .s]
    update

} -body {
    .s insert end "A sample text"
    .s icursor end
    event generate .s <<PrevWord>>  ; # shall move insert to index 9
    .s delete insert end
    .s get






} -cleanup {
    destroy .s
} -result {A sample }


# nostomp: NB intentional difference between ttk::spinbox and tk::spinbox;
# see also #1439266
#
test spinbox-nostomp-1 "don't stomp on -variable (init; -from/to)" -body {
    set SBV 55







>





|
>
>
>
>
>
>


|







287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
    unset -nocomplain ::spinbox_test max
} -result {one two three 4 5 two six six six two 5 4 three two one one one one}

test spinbox-11.2 {Bugs [2a32225cd1] and [9fa3e08243]} -setup {
    destroy .s
    pack [ttk::spinbox .s]
    update
    set res {}
} -body {
    .s insert end "A sample text"
    .s icursor end
    event generate .s <<PrevWord>>  ; # shall move insert to index 9
    .s delete insert end
    lappend res [.s get]
    .s delete 0 end
    .s insert end "A sample text"
    .s icursor 2
    event generate .s <<NextWord>>  ; # shall move insert to index 9
    .s delete 0 insert
    lappend res [.s get]
} -cleanup {
    destroy .s
} -result {{A sample } text}


# nostomp: NB intentional difference between ttk::spinbox and tk::spinbox;
# see also #1439266
#
test spinbox-nostomp-1 "don't stomp on -variable (init; -from/to)" -body {
    set SBV 55