TIP #122: USE TCL_{NON,}WORDCHARS THROUGHOUT TCL/TK ===================================================== Version: $Revision: 1.9 $ Author: Martin Weber Vince Darley State: Rejected Type: Project Tcl-Version: 8.6 Vote: Done Created: Thursday, 12 December 2002 URL: https://tip.tcl-lang.org122.html Post-History: ------------------------------------------------------------------------- ABSTRACT ========== This TIP shall bring flexible management of word and non-word chars to Tcl, to be used throughout the Tcl realm in e.g. [regexp]'s \w \W, Tk's [textwidget], [string] wordstart/wordend etc. SPECIFICATION =============== Assignment to /tcl_{non,}wordchars/ shall influence any place in Tcl which decides whether something is a word character or not, including detection of word boundaries in e.g. regular expressions, Tk's text widget and so on. For this there shall be no hard-coding of lists of values which are word and non-word characters, and neither shall the language rely on the language of implementation (i.e. C's /is*()/ functions), as this disallows dynamic changing of /tcl_{non,}wordchars/. Rather shall the value(s) of /tcl_{non,}wordchars/ be used to determine whether a given character is part of a word or not. RATIONALE =========== Currently in Tcl there are different hard-coded ways to decide whether a certain character is a word character or a non word character. Different hard-coded ways also imply that changes on one side might not get over to the other side, so there soon are different hard-coded ways which yield different hard-coded results. As a inference of it being hard-coded, this also means that there is no way to change or fix that potentially broken behavior. Having Tcl lookup the values of those variables at runtime allows for the needed flexibility, both when dealing with nonstandard demands and nonstandard character sets. As an example of the breakage, you can assign a regular expression to tcl_{,non}wordchars, and the double click binding in the textwidget will regard that pattern when marking a "whole word". When you try to ask the text widget to deliver the data under a certain coordinate with the indices 'wortstart' and 'wordend', the value of tcl_{non,}wordchars is not used though. There may be a problem with the performance of the lookup, but on the other hand are C's /is*()/ functions also implemented via a table lookup. An installation of a caching static character table could guarantee the needed performance. EXAMPLE OF CURRENT WORD CONFUSION =================================== Tk's text widget uses "word" in several ways: 1. selection by word (double-click + drag), 2. movement by word ('insert wordstart'), 3. regexp searching with \m\M wordmatching. 4. line breaks when wrapping (-wrap word) It is not at all clear from reading Tcl or Tk's documentation what the behaviour of the above options will be. It turns out that: 1. after a convoluted call-chain, ends up calling tcl_wordBreakAfter/Before which use tcl_wordchars and tcl_nonwordchars (which actually are defined differently on Windows vs Unix/MacOS!!). 2. uses 'isalnum(char)' or '_' to define a word (hard-coded in Tk's tkTextIndex.c) (in Tk8.5a0 this has been fixed to use /Tcl_UniCharIsWordChar/) 3. uses Tcl's regexp engine's definition of a word (this ought to be the same as that used in (2)). 4. Anything separated by white-space from something else, used with '-wrap word' to define line-wrapping in text widgets (and canvases). It is quite likely that most of the above are different under some circumstances or some platforms/locales, and certainly if the user/developer wants to create a text widget with a different word definition, they basically can't in any consistent way. IMPLEMENTATION ================ None yet. COPYRIGHT =========== This document is placed in the public domain. ------------------------------------------------------------------------- TIP AutoGenerator - written by Donal K. Fellows