Search code examples
widgettcltk-toolkittext-widget

Unusual behavior with the Text widget indexing? (Tcl/Tk)


I am trying to create bindings for the Tk Text widget to limit the User so s/he can't delete the first character in the line (the character serves as a sort of prompt like in a terminal.)

Here's how I'm almost accomplishing this:

bind .text <BackSpace> {
    if{[.text index insert] == [.text index {insert linestart+1c}]} {
        break;
    }
}

It works in terms of not letting the user delete the first character in the line, but for whatever reason, it also stops the user from deleting the ninth character in the line as well! For example:

>hello world!

Pressing backspace now from the end of that line will delete until

hello wor

and then stop! I can press the left-arrow to move to the next character after 'r' and keep deleting, and then as it should, it doesn't delete the carrot. I see no reason why this should be happening. If someone could either point out my mistake or let me know of a better way to achieve what I'd like that would be great.


Solution

  • At the point where it stops, [.text index insert] gives an index of 1.10 and [.text index {insert linestart+1c}] gives an index of 1.1.

    These are numerically equal, and == likes to use numeric equality if at all possible.

    The fix is to use the compare method of the text widget, perhaps like this:

    bind .text <BackSpace> {
        if {[.text compare insert == {insert linestart+1c}]} {
            break
        }
    }
    

    (I think you might actually be better off doing your overall goal a different way, perhaps by setting a tag on the text you want to preserve and checking before deletion whether any of the text to be deleted has the tag. But that's a very different approach.)