Tk Source Code

View Ticket
Login
Ticket UUID: cc736f86926f5be825fa3914b51b94bc461ad5a7
Title: Ctrl+Left in text skips a one-character word before the cursor
Type: Bug Version: 8.6.18, 9.0.5, 9.1.0
Submitter: serhiy.storchaka Created on: 2026-10-25 10:13:56
Subsystem: 18. [text] Assigned To: nobody
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2026-10-31 15:22:53
Resolution: Fixed Closed By: nemethi
    Closed on: 2026-10-31 15:22:53
Description:

In a text widget, Ctrl+Left (<<PrevWord>>) skips a one-character word just before the cursor. The same happens with Shift+Ctrl+Left, Meta-b and Meta-BackSpace.

pack [text .t]
.t insert end "a b c\nxy z"
.t mark set insert end-1c
focus .t
# Ctrl+Left goes to 2.0 (before "xy") instead of 2.3 (before "z")

From 2.0 the following stops are right (1.4, 1.2, 1.0). Entry and spinbox are not affected with ICU.

::tk::TextPrevPos calls tk::startOfPreviousWord with index end, the index of the last character, which is one before the cursor. The word starting at that index is therefore not found.

Fixed on branch text-prev-word-one-char [edb46a2731]: new ::tk::TextPrevWord appends a space to the text, so that end is the cursor position. New tests text-42.1 and text-42.2 (with -locale tcl8). Tested on Linux and Windows; not tested on macOS.

User Comments: nemethi (claiming to be Csaba Nemethi) added on 2026-10-31 15:22:53:

Merged by Jan into main, core-9-0-branch, and core-8-6-branch by commits [11d88f8a], [4c024a3a], and [f7d98b9f]. Closing the ticket.


marc_culler (claiming to be Marc Culler) added on 2026-10-28 12:52:39:
Thank you Serhiy.  That was it.  With Tcl updated I consistently see
no Tk test failures with the tip_695 branch, which includes this fix
and the new tests.

---- text-42.1 start
++++ text-42.1 PASSED
---- text-42.2 start
++++ text-42.2 PASSED

serhiy.storchaka added on 2026-10-28 09:55:54:

Jan, text-42.2 fails on the Windows CI of main, because win-build.yml builds against the Tcl branch manifest-in-rc-only (last changed in July), which does not have the fix for Tcl ticket 3e7c4a039d. Could it use Tcl main, or could main be merged into that branch?


serhiy.storchaka added on 2026-10-28 03:48:02:

Marc, did you update Tcl? Without ICU, as on macOS, the fix needs Tcl ticket 3e7c4a039d, fixed in Tcl main on 2026-10-26. Your results are what an older Tcl gives.


marc_culler (claiming to be Marc Culler) added on 2026-10-27 22:49:40:
I don't think this fix works on macOS. although it has already been merged into
main.  As far as I can tell, on macOS 27 it still jumps to 2.0.

The failures are:

==== text-42.1 <<PrevWord>> stops at a one-character word before the cursor FAILED
==== Contents of test case:

    .t insert end "a b c\nxy z"
    .t mark set insert end-1c
    for {set i 0} {$i < 5} {incr i} {
        event generate .t <<PrevWord>>
        lappend res [.t index insert]
    }
    .t mark set insert 2.4
    event generate .t <<SelectPrevWord>>
    lappend res [.t tag ranges sel]

---- Result was:
2.0 1.4 1.2 1.0 1.0 {2.0 2.4}
---- Result should have been (exact matching):
2.3 2.0 1.4 1.2 1.0 {2.3 2.4}
==== text-42.1 FAILED


==== text-42.2 <<PrevWord>> stops at a one-character word before the cursor, -locale tcl8 FAILED
==== Contents of test case:

    .t insert end "a b c\nxy z"
    .t mark set insert end-1c
    for {set i 0} {$i < 5} {incr i} {
        event generate .t <<PrevWord>>
        lappend res [.t index insert]
    }
    set res

---- Result was:
2.0 1.4 1.2 1.0 1.0
---- Result should have been (exact matching):
2.3 2.0 1.4 1.2 1.0
==== text-42.2 FAILED

serhiy.storchaka added on 2026-10-26 15:05:48:

The fix is now simpler [2bcf1dec75], since tcl_startOfPreviousWord was fixed in Tcl (Tcl ticket 3e7c4a039d): ::tk::TextPrevWord passes end+1, the cursor position, to tk::startOfPreviousWord. This needed a fix of the ICU version too, which returned the position of a space when only spaces preceded the start (0 for "\n" 1, 1 for "a \n" 3). It now gives the same results as tcl_startOfPreviousWord (checked on 80485 random strings of letters, spaces and newlines). New tests cluster-4.10 to 4.14. text-42.2 (-locale tcl8) needs the fixed Tcl. Tested on Linux and Windows; not tested on macOS.