Version 0 of Modern Bindings for the Text Widget

Updated 2005-10-31 15:33:31

KJN: This page defines a binding tag, modernText, as an alternative to the text widget's default binding tag, Text.

The purpose of modernText is to make the text widget behave more like a "modern" (Year 2005 CE) text editor. It makes the text widget more useful for implementing a text editor, and makes it behave in a way that is more familiar to many users.

modernText is implemented as a binding tag, and apart from these bindings its code is contained entirely in the ::modernText namespace, with no exports to the global or other namespaces, and no new widget commands. It uses modified copies of the Tk code, leaving the original code, and the Text binding tag, unchanged.

Vices of the default bindings:

  • clicking near the end of a line moves the cursor to the start of the next line. Double-clicking or dragging may highlight and select the space at the end of the line (notably the region where there are no characters). It may select the first word of the next line. It may make a nonsense selection.
  • the Home and End keys could be improved - these have been changed in recent versions of Tcl/Tk to move to the beginning or end of a display line, rather than of a logical line; further improvement is possible - successive keypresses can implement "Smart Home" and "Smart End".
  • When a selection exists, a <<Paste>> operation (e.g. <Control-v>) deletes the selection (as modern editors do) - unless you are using X11 (the windowing system for Linux etc).
  • The <Escape> key does not clear the selection.
  • Selecting with <Shift-Button1> may select from the position of the previous mouse click, not the previous position of the insertion cursor.
  • <Shift-Button1> operations can move the selection anchor.

The last two 'vices' are often useful features, so modernText gives you the option of retaining them, by setting variables defined in the ::modernText namespace to 1 (instead of their default 0). Explaining these vices/features in more detail:

  • If the mouse is clicked at position A, then the keyboard is used to move the cursor to B, then shift is held down, and the mouse is clicked at C: the Text binding tag gives a selection from A to C; the modernText gives a selection from B to C. If you want modernText to behave like Text in this respect, set ::modernText::mouseSelectIgnoresKbd to 1.
  • The Text binding tag allows successive Shift-Button-1 events to change both ends of the selection, by moving the selection anchor to the end of the selection furthest from the mouse click. Instead, the modernText binding tag fixes the anchor, and multiple Shift-Button-1 events can only move the non-anchored end of the selection. If you want modernText to behave like Text in this respect, set ::modernText::variableAnchor to 1. In both Text and modernText, keyboard navigation with the Shift key held down alters the selection and keeps the selection anchor fixed.

I have worked on the bindings that I personally use a lot, but there are many others that I do not use - so I would appreciate feedback (on this Wiki page) on any features in modernText, particularly bindings or other features that may have been broken by these changes.

modernText is mainly intended for text widgets whose -wrap mode is "none" or "word". For a text widget that is wrapped in "char" mode, display line ends are much less meaningful, and so, for "-wrap char", modernText's rules on crossing line ends are relaxed for display lines (but not for logical lines).

Requirements

The code requires Tk 8.5; the latest development version (ActiveTcl 8.5 beta 4, 8.5a4) has a bug [L1 ] in the text widget. So I am using an earlier version, ActiveTcl 8.5 beta 3 (8.5a2). I recommend using this version for text widget work until a bugfixed version of 8.5 is released.

To use modernText, source the code in the first box below, and then use the bindtags command to specify the modernText binding tag (instead of the default Text) for your text widget, e.g.

    bindtags .t {.t modernText . all}

The second box below has a simple demo program.

To Do

  • improvement of word selection functions in lib/tcl8.5/word.tcl
  • indentation of wrapped lines using tags and -lmargin2