<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Sun May 26 02:49:01 GMT 2013 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='155'>
<header><title>Fix Some of the Text Widget&apos;s Limitations</title><author address="mailto:vince@santafe.edu">Vince Darley</author><status type='project' state='final' tclversion="8.5" vote='after'>$Revision: 1.23 $</status><history></history><created day='8' month='sep' year='2003' /></header>
<abstract>Tk&apos;s text widget is very powerful, but has a number of known limitations. In particular the entire handling of wrapped lines and &apos;display/visual entities&apos; versus &apos;logical entities&apos; is quite limited. The most obvious side-effect of these inadequacies is the &apos;scrollbar problem&apos; (in which, particularly when there are long wrapped lines in the widget, the vertical scrollbar slider changes in size depending on the number of logical lines currently displayed, see <url ref="http://mini.net/tcl/896"/> for example). This TIP overhauls the widget to provide consistent, complete support for &apos;display lines&apos;, &apos;display indices&apos; and as a consequence smooth, pixel-based scrolling. A few other small bugs/issues have also been resolved.</abstract>
<body><section title="Proposal">
<para>The text widget has a number of limitations:</para>
<enumerate><item.e index='1'><para>The aforementioned scrollbar interaction is flawed</para></item.e><item.e index='2'><para>To count the number of characters between index positions $idx1 and $idx2, one can only really do <emph style="italic">string length [.text get $idx1 $idx2]</emph>. There is no easy way to determine the number of visible (non-elided) characters between these two index positions, nor the number of valid index positions between them (remember that embedded windows or images always take up one unit of index position, but don&apos;t correspond to any characters). A similar difficulty exists in counting the number of display lines between two index positions, and in counting the number of pixels between two index positions (or in the entire widget).</para></item.e><item.e index='3'><para>Performing a correct text &quot;replace&quot; operation (as used by a text editor, for example) is difficult, because combinations of insert/delete tend to make the window scroll and/or leave the insertion cursor in an unnatural place.</para></item.e><item.e index='4'><para>There is no way to configure the widget to get an acceptable block-cursor.</para></item.e><item.e index='5'><para>When long lines are wrapped there is no easy way to get the beginning or end of a possible display line, or move up or down by display lines, unless the line is actually currently displayed (and even then the code is rather complex).</para></item.e><item.e index='6'><para>Even though &apos;search&apos; can operate optionally on all text or just non-elided text, there is no easy way to retrieve the actual string which matched in the latter case, if the match spans characters on either side of an elided range.</para></item.e><item.e index='7'><para><emph style="italic">.text search -backwards -all</emph> returns subsets of indices in forwards rather than backwards order; with simple multi-line greedy searches (like <emph style="italic">-nolinestop -- .*</emph>) it fails to match multiple lines; it can return backwards matches which fully enclose each other, etc.</para></item.e></enumerate>
<para>This TIP is, therefore, to fix these limitations, as follows:</para>
<enumerate><item.e index='1'><para>Make internal changes to the text widget so it keeps track of the number of vertical display pixels in each logical line, and uses that information to calculate scrollbar interactions, to provide a better user experience, including smooth scrolling. This requires an extension to the text widget&apos;s yview command to do smooth scrolling: <emph style="italic">.text yview scroll N pixels</emph></para></item.e><item.e index='2'><para>Add a <emph style="italic">count</emph> widget subcommand, which calculates the number of characters or index positions or non-elided characters/index positions or lines or displaylines or x/y-pixels between two given indices. Similar extend <emph style="italic">+N chars</emph> to allow index calculations by chars, indices and elided or not.</para></item.e><item.e index='3'><para>Add a <emph style="italic">replace</emph> widget subcommand, which performs a combined delete/insert operation while ensuring that the insertion position, vertical display position, and undo/redo information is correctly set.</para></item.e><item.e index='4'><para>Add a <emph style="italic">-blockcursor</emph> configuration option which makes the widget use a rectangular flashing &quot;block&quot; rather than a thin beam for the insertion point.</para></item.e><item.e index='5'><para>Add <emph style="italic">displaylinestart</emph> and <emph style="italic">displaylineend</emph> and <emph style="italic">+/- N displaylines</emph> index offsets which work like <emph style="italic">linestart</emph>, <emph style="italic">lineend</emph>, <emph style="italic">+/- N lines</emph> but with display lines, and which work whether the relevant indices are currently displayed or not. And make <emph style="italic">tk::TextUpDownLine</emph> operate in terms of display lines.</para></item.e><item.e index='6'><para>Add an option <emph style="italic">-displaychars</emph> to <emph style="italic">get</emph> which, if given, restricts the returned characters to be just those which are not elided.</para></item.e><item.e index='7'><para>Fix &apos;search -all -backwards&apos; so that it returns the matches in the correct backwards sequence, even within each individual line. Also add the options &apos;-overlap&apos; (to allow matches which overlap each other to be returned) and &apos;-strictlimits&apos; to prevent matches which would extend beyond the strict [pos,limit] range. Fix code for correct greedy forwards and backwards searches using correct non-overlapping matching unless explicitly requested.</para></item.e></enumerate>
<para>Each of these proposals is discussed and presented in full detail below.</para>
<para>In addition, the current implementation provides for a bit more text widget objectification and fixes the &quot;very slow deletion of lots of text with lots of tags&quot; bug (there was a non-linear slowdown which has been removed). One crashing bug in the text widget has also been fixed, and a bug in searches with &apos;-all&apos;.</para>
</section>
<section title="Scrollbar Interaction">
<para>This is the most complex of the proposed changes, even though solving it results in very limited changes to the actual text-widget&apos;s public Tcl or C interfaces. The following example illustrates the problem:</para>
<verbatim><vline encoding='base64'>IHBhY2sgW3Njcm9sbGJhciAucyAtY29tbWFuZCB7LnQgeXZpZXd9XSAtc2lkZSByaWdodCAtZmlsbCB5</vline><vline encoding='base64'>IHBhY2sgW3RleHQgLnQgLXlzY3JvbGxjb21tYW5kIHsucyBzZXR9XSAtc2lkZSBsZWZ0</vline><vline encoding='base64'></vline><vline encoding='base64'>IGZvciB7c2V0IGkgMH0geyRpIDwgMzAwfSB7aW5jciBpfSB7</vline><vline encoding='base64'>ICAgLnQgaW5zZXJ0IGluc2VydCAkaQ==</vline><vline encoding='base64'>IH0=</vline><vline encoding='base64'></vline><vline encoding='base64'>IGZvciB7c2V0IGkgMH0geyRpIDwgMjB9IHtpbmNyIGl9IHs=</vline><vline encoding='base64'>ICAgLnQgaW5zZXJ0IGluc2VydCAiJGlcbiI=</vline><vline encoding='base64'>IH0=</vline><vline encoding='base64'></vline><vline encoding='base64'>IGZvciB7c2V0IGkgMH0geyRpIDwgMzAwfSB7aW5jciBpfSB7</vline><vline encoding='base64'>ICAgLnQgaW5zZXJ0IGluc2VydCAkaQ==</vline><vline encoding='base64'>IH0=</vline></verbatim>
<para>Solving this problem perfectly must require the text widget to know exactly how many vertical pixels each line contains. However, for a widget which contains a great deal (megabytes) of text, images, embedded windows and numerous tags (and on which certain tags could have their font configuration changed on the fly), it is clearly impractical to have the widget calculate every line&apos;s pixel-height requirements whenever anything changes (for bad cases the response-time would be unacceptable).</para>
<para>The solution proposed is an asynchronous update mechanism where the structure representing each logical line caches the last known pixel height and an epoch counter. As changes (global or local) are made, individual logical lines recalculate their height either immediately (for small, local changes such as inserting a few characters) or are scheduled for recalculation (for larger changes such as resizing the window or changing size-influencing tag settings). When blocks of lines (or, indeed, all lines) are scheduled for recalculation, each asynchronous callback should only recalculate the pixel heights of a relatively small number of lines, so that user-responsiveness is maintained.</para>
<para>As line pixel-height calculations are updated, a second asynchronous mechanism is triggered, this one to update any scrollbar attached to the text widget (i.e. call the <emph style="italic">-yscrollcommand</emph> callback). Again it is undesirable to call this every single time a single line&apos;s height is updated, so this is called with a timer mechanism so it is updated every 200ms.</para>
<para>Both of these asynchronous mechanisms should be designed so they do not need to be run if nothing relevant has changed in the widget.</para>
<para>It may require some experimentation to determine the most appropriate usage patterns of these asynchronous callbacks. In particular, the current implementation uses timer callbacks (idle callbacks cannot be used because idle callbacks are not allowed to reschedule themselves). A thread-based implementation may have some advantages (although it certainly has disadvantages too).</para>
<para>Given the pixel calculations are available, they have been used to provide for smooth scrolling of the text widget. This means even with large images (possibly even larger than the height of the widget itself), smooth scrolling off top and bottom of the widget are automatic. In order for smooth scrolling to be used by Tk&apos;s Tcl library, the <emph style="italic">pixels</emph> unit has been added to the <emph style="italic">.text yview scroll</emph> command. This is used to ensure mouse-wheel and scan-drag scrolling are smooth. It is important that the existing <emph style="italic">pages</emph> and <emph style="italic">units</emph> (the latter being display lines) do not change in meaning so that, for example, clicking on a scrollbar&apos;s arrow still scrolls the widget by 1 display line.</para>
</section>
<section title="Count Subcommand">
<para>A new subcommand <emph style="italic">.text count ?options? startIndex endIndex</emph> is added for all text widgets. Valid options (any combination of which can be specified) are <emph style="italic">-chars</emph>, <emph style="italic">-indices</emph>, <emph style="italic">-displaychars</emph>, <emph style="italic">-displayindices</emph>, <emph style="italic">-lines</emph>, <emph style="italic">-displaylines</emph>, <emph style="italic">-xpixels</emph>, <emph style="italic">-ypixels</emph>. The default value, if no option is specified, is <emph style="italic">-indices</emph>. In addition <emph style="italic">-update</emph> can be specified. If given this option ensures all subsequent options operate on a range of indices for which all metric calculations (e.g. line pixel heights) are up to date. This option is of particular importance to the <emph style="italic">-ypixels</emph> option.</para>
<para>The subcommand counts the number of relevant things between the two indices. If startIndex is after endIndex, the result will be a negative number. The actual items which are counted depend on the option given, as follows:</para>
<describe><item.d name='-indices'><para>count all characters and embedded windows or images (i.e. everything which counts in text-widget index space), whether they are elided or not.</para></item.d><item.d name='-chars'><para>count all characters, whether elided or not. Do not count embedded windows or images.</para></item.d><item.d name='-displaychars'><para>count all non-elided characters.</para></item.d><item.d name='-displayindices'><para>count all non-elided characters, windows and images.</para></item.d><item.d name='-lines'><para>count all logical lines (this option is only included for completeness since it can be achieved pretty easily in Tk already)</para></item.d><item.d name='-displaylines'><para>count all displaylines.</para></item.d><item.d name='-xpixels'><para>count the number of horizontal pixels between the two indices.</para></item.d><item.d name='-ypixels'><para>count the number of vertical pixels between the two indices. </para></item.d></describe>
<para>If more than one of these counting options is given, the result is a list with one entry for each such option given (<emph style="italic">-update</emph> does not contribute to this result, of course).</para>
<para>Similar, the index modifiers are extended so the following are now valid: &quot;+N display chars&quot;, &quot;+N indices&quot;, &quot;+N display indices&quot;, &quot;+N any indices&quot;, &quot;+N any chars&quot;. The &quot;display&quot; and &quot;any&quot; can be abbreviated if they are followed by whitespace.</para>
<para>In particular, this means that:</para>
<verbatim><vline encoding='base64'>IHN0cmluZyBsZW5ndGggWy50ZXh0IGdldCAkaTEgJGkyXSA9PSBbLnRleHQgY291bnQgLWNoYXJzICRpMSAkaTJd</vline></verbatim>
<para>provided $i1 is not after $i2 in the widget. It also means that</para>
<verbatim><vline encoding='base64'>IC50ZXh0IGNvbXBhcmUgIiRpMSArIFsudGV4dCBjb3VudCAtaW5kaWNlcyAkaTEgJGkyXWluZGljZXMiID09ICRpMg==</vline></verbatim>
<para>and</para>
<verbatim><vline encoding='base64'>IC50ZXh0IGNvbXBhcmUgIiRpMSArIFsudGV4dCBjb3VudCAtZGlzcGxheWluZGljZXMgJGkxICRpMl0gZGlzcGxheSBpbmRpY2VzIiA9PSAkaTI=</vline></verbatim>
<para>is true under all circumstances.</para>
<para>Lastly, for those who wish to know the required number of vertical pixels a text widget needs, <emph style="italic">.text count -update -ypixels 1.0 end</emph> will give this (once any borderwidth, highlightthickness and ypad have been added on). For example, the following procedure will give the smallest possible size in pixels which a given text widget would desire to have no scrollbars:</para>
<verbatim><vline encoding='base64'>cHJvYyB0ZXh0RGV0ZXJtaW5lRGltZW5zaW9ucyB7dGV4dH0gew==</vline><vline encoding='base64'>ICAgIHNldCBib3JkZXIgWyR0ZXh0IGNnZXQgLWhpZ2hsaWdodHRoaWNrbmVzc10=</vline><vline encoding='base64'>ICAgIGluY3IgYm9yZGVyIFskdGV4dCBjZ2V0IC1ib3JkZXJ3aWR0aF0=</vline><vline encoding='base64'>ICAgIHNldCB5IFtleHByIHsyKiAoJGJvcmRlciArIFskdGV4dCBjZ2V0IC1wYWR5XSl9XQ==</vline><vline encoding='base64'>ICAgIHNldCB4IFtleHByIHsyKiAoJGJvcmRlciArIFskdGV4dCBjZ2V0IC1wYWR4XSl9XQ==</vline><vline encoding='base64'>ICAgIA==</vline><vline encoding='base64'>ICAgIGluY3IgeSBbJHRleHQgY291bnQgLXVwZGF0ZSAteXBpeGVscyAxLjAgZW5kXQ==</vline><vline encoding='base64'>ICAgIGlmIHtbJHRleHQgY2dldCAtd3JhcF0gZXEgIm5vbmUifSB7</vline><vline encoding='base64'>CXNldCBtYXhfeCAw</vline><vline encoding='base64'>CWZvciB7c2V0IGkgMH0geyRpIDwgaW50KFskdGV4dCBpbmRleCBlbmRdKX0ge2luY3IgaX0gew==</vline><vline encoding='base64'>CSAgICBzZXQgeHBpeCBbJHRleHQgY291bnQgLXhwaXhlbHMgJHtpfS4wICIke2l9LjAgbGluZW5kIl0=</vline><vline encoding='base64'>CSAgICBpZiB7JHhwaXggPiAkbWF4X3h9IHs=</vline><vline encoding='base64'>CQlzZXQgbWF4X3ggJHhwaXg=</vline><vline encoding='base64'>CSAgICB9</vline><vline encoding='base64'>CX0=</vline><vline encoding='base64'>CWluY3IgbWF4X3ggJHg=</vline><vline encoding='base64'>CXJldHVybiBbbGlzdCAkeCAkeV0=</vline><vline encoding='base64'>ICAgIH0gZWxzZSB7</vline><vline encoding='base64'>CXJldHVybiBbbGlzdCBbd2luZm8gcmVxd2lkdGggJHRleHRdICR5XQ==</vline><vline encoding='base64'>ICAgIH0=</vline><vline encoding='base64'>fQ==</vline></verbatim>
</section>
<section title="Replace Subcommand">
<para>A new subcommand</para>
<verbatim><vline encoding='base64'>IC50ZXh0IHJlcGxhY2UgaW5kZXgxIGluZGV4MiBjaGFycyA/dGFnTGlzdCBjaGFycyB0YWdMaXN0IC4uLj8=</vline></verbatim>
<para>is added for all text widgets. This subcommand is approximately equivalent to a combined:</para>
<verbatim><vline encoding='base64'>IC50ZXh0IGRlbGV0ZSBpbmRleDEgaW5kZXgy</vline><vline encoding='base64'>IC50ZXh0IGluc2VydCBpbmRleDEgY2hhcnMgP3RhZ0xpc3QgY2hhcnMgdGFnTGlzdCAuLi4/</vline></verbatim>
<para>but also ensures that the current window display position (e.g. what line is currently displayed at the top left corner of the text widget), the current insertion position and the undo/redo stack are all correctly set up. This subcommand could be implemented in pure Tcl, but is quite complex to get right. The C-level implementation shares most of the code with insert/delete/count and can also be made more efficient in its handling of window-scrolling issues.</para>
</section>
<section title="Block Cursor">
<para>A new text widget configuration option <emph style="italic">-blockcursor &lt;boolean&gt;</emph> is added. If set to any true value, instead of a thin flashing vertical bar being used for the insertion cursor, a full rectangular block is used instead.</para>
</section>
<section title="Display-Line Handling">
<para>Currently one can discover the beginning or end of a given logical line and move between logical lines with:</para>
<verbatim><vline encoding='base64'>IC50ZXh0IGluZGV4ICIkaWR4IGxpbmVzdGFydCI=</vline><vline encoding='base64'>IC50ZXh0IGluZGV4ICIkaWR4IGxpbmVlbmQi</vline><vline encoding='base64'>IC50ZXh0IGluZGV4ICIkaWR4ICsxbGluZXMi</vline><vline encoding='base64'>IC50ZXh0IGluZGV4ICIkaWR4IC01bGluZXMi</vline></verbatim>
<para>However, when a given logical line may be wrapped over numerous display lines it is not so simple to find the beginning or end of a display line, or move up or down by display lines. (In fact is is currently possible with the <emph style="italic">@</emph> syntax if the logical line and the $idx are both currently displayed on screen, but is not possible(*) if the logical line is not currently displayed). Therefore a new index manipulation set are added:</para>
<verbatim><vline encoding='base64'>IC50ZXh0IGluZGV4ICIkaWR4IGRpc3BsYXkgbGluZXN0YXJ0Ig==</vline><vline encoding='base64'>IC50ZXh0IGluZGV4ICIkaWR4IGRpc3BsYXkgbGluZWVuZCI=</vline><vline encoding='base64'>IC50ZXh0IGluZGV4ICIkaWR4ICsxZGlzcGxheSBsaW5lcyI=</vline><vline encoding='base64'>IC50ZXh0IGluZGV4ICIkaWR4IC01ZGlzcGxheSBsaW5lcyI=</vline></verbatim>
<para>These work whether or not $idx is currently displayed (when it is not displayed, the index is calculated by laying out the geometry of the line behind the scenes so this operation is certainly more time-consuming than determining the logical line start or end). The &quot;display&quot; in these items can be abbreviated if it is followed by whitespace (if it is not abbreviated then the whitespace is optional).</para>
<para>In addition the single Tcl proc <emph style="italic">tk::TextUpDownLine</emph> (in text.tcl) has been updated to operate in terms of display lines and thereby to retain the current x position as accurately as possible across multiple up/down arrow keypresses.</para>
<para>(*) Perhaps it would be possible, if horribly cumbersome, by copying the relevant contents into another text widget which is unmapped and making sure the desired lines are visible in that widget, and finally performing the desired operations on the copy before deleting it all!</para>
</section>
<section title="Get -displaychars">
<para>This is a simple new option to the <emph style="italic">get</emph> subcommand, which now has the syntax <emph style="italic">.text get ?-displaychars? ?--? index1 ?index2....?</emph>. This means the following code now makes sense:</para>
<verbatim><vline encoding='base64'>IHNldCBmb3VuZCBbLnRleHQgc2VhcmNoIC1lbGlkZSAtY291bnQgbnVtICRwYXR0ZXJuICRwb3Nd</vline><vline encoding='base64'>IHNldCBtYXRjaCBbLnRleHQgZ2V0IC1kaXNwbGF5Y2hhcnMgJGZvdW5kICIkZm91bmQgKyAkbnVtIGNoYXJzIl0=</vline></verbatim>
<para>Previously, achieving something like the second line was quite complex.</para>
</section>
<section title="Search subcommand">
<para>In Tk8.5a0 at present <emph style="italic">search -all -backwards ...</emph> returns the list of indices backwards from line to line, but forwards within each line (a side-effect of backwards matching being implemented as repeated forward searches). Large backwards or forwards regexp searches for, say, <emph style="italic">-nolinestop -- .*</emph> would only match a single line. Various other overlap vs non-overlap problems too. All of these glitches (my own code ;-) have been fixed and the test suite for <emph style="italic">search</emph> hugely extended.</para>
</section>
<section title="Backward Compatibility">
<para>All of the above changes simply extend the functionality of the text widget in new ways, and therefore have no significant backward compatibility problems. It is possible that some existing Tk code may notice some minor behavioural differences:</para>
<para>Since the interaction between text widget and vertical scrollbar is now slightly different, any code which assumed that a particular scrollbar position (e.g. 0.5) corresponds to a particular line of text will find that that line of text may now be different (and will of course depend on the actual line heights). This change is considered a bug fix, not an incompatibility! In particular, however, any code which performs a calculation like:</para>
<verbatim><vline encoding='base64'>IHNldCBudW1fbGluZXMgW2xpbmRleCBbc3BsaXQgWy50ZXh0IGluZGV4IGVuZF0gLl0gMF0=</vline><vline encoding='base64'>IHNldCBsYXN0X3Zpc2libGUgW2V4cHIge2ludCgkbnVtX2xpbmVzICpbbGluZGV4IFsudGV4dCB5dmlld10gMV0pfV0=</vline></verbatim>
<para>(under the assumption that the scrollbar&apos;s units are effectively measured in logical lines) will now get a different answer (since the scrollbar operates with pixels), and that different answer will not correspond to the last visible line. Of course the code should always have used:</para>
<verbatim><vline encoding='base64'>IHNldCBsYXN0X3Zpc2libGU=</vline><vline encoding='base64'>ICAgW2V4cHIge2ludChbLnRleHQgaW5kZXggIkBbd2luZm8gd2lkdGggLnRleHRdLFt3aW5mbyBoZWlnaHQgLnRleHRdIl0pfV0=</vline></verbatim>
<para>which works correctly no matter how the scrollbar operates.</para>
<para>In addition, with the new <emph style="italic">pixels</emph> unit for the scrollbar, the command <emph style="italic">.text yview scroll 1 p</emph> is now ambiguous and will throw an error. This incompatibility is similar to those which have previously been introduced in, e.g., Tk 8.4 (with -padx, -pady).</para>
<para>Lastly, &quot;+N chars&quot; is a synonym for &quot;+N indices&quot; for backwards compatibility reasons. This may be different to &quot;+N any chars&quot;.</para>
</section>
<section title="Implementation">
<para>A complete implementation is available at:</para>
<para><url ref="http://sf.net/tracker/?func=detail&amp;aid=791292&amp;group_id=12997&amp;atid=312997"/></para>
<para>This passes all Tk text widget tests (on Windows XP, at least), including a significant number of new tests. The memory requirements of the text widget have increased marginally to support the correct vertical scrolling behaviour: two new integers must be stored for each logical line of text.</para>
</section>
<section title="Out of Scope">
<para>A number of other text widget enhancements might be nice. Some of these are listed here for completeness:</para>
<itemize><item.i><para>Printing support (at least to postscript like the canvas widget -- in fact I&apos;m sure 95% of the canvas printing code could be re-used for this, with the only new stuff being handling of multiple pages. It might be preferable to support pdf instead, however)</para></item.i><item.i><para>Cloning (e.g. reading in the result of <emph style="italic">.text -dump</emph>, although handling of tag definitions and tag-bindings would also be nice)</para></item.i><item.i><para>Synchronizing/backing the widget contents with a Tcl variable (actually not too hard to implement quite efficiently now, given the <emph style="italic">count</emph> functionality). This can be done without too much trouble with pure Tcl.</para></item.i><item.i><para>Loading data into the widget asynchronously from a channel (easy to implement with Tcl procedures, although core support might make for better scrollbar handling and thereby make such a feature almost invisible to the user).</para></item.i><item.i><para>Modifications to the horizontal scrollbar. The horizontal scrollbar&apos;s position/status depends only on the <emph style="italic">currently-displayed contents</emph> of the text widget. This means as one scrolls the widget vertically, the horizontal scrollbar changes. No attempt has been made to fix this problem in this TIP.</para></item.i><item.i><para>A shorthand (<emph style="italic">display start</emph>, <emph style="italic">display end</emph>?) for the rather less obvious <emph style="italic">.text index &quot;@0,0&quot;</emph> and <emph style="italic">.text index &quot;@[winfo width .text],[winfo height .text]&quot;</emph></para></item.i><item.i><para>The attachment of user-defined data to each logical line in the widget (e.g. a code parser&apos;s current internal state), which might make true parsing for syntax colouring significantly easier.</para></item.i><item.i><para>The pre-existing behaviour of <emph style="italic">+/- N lines</emph> uses byte-indices instead of x-pixel calculations (thereby having the cursor bobbling around when there are multi-byte characters or even worse when there are images, proportional fonts, tabs, etc). Further, the behaviour is quite strange when wrapping is enabled in the widget. This TIP does not propose any changes in this area other than to suggest that Tcl coders make use of &apos;displaylines&apos; instead, for more consistent behaviour (as has been done to text.tcl).</para></item.i><item.i><para>To do word-matching with <emph style="italic">search</emph> requires the use of a regexp pattern and something like <emph style="italic">.text search -regexp -- &quot;\\m[quote::Regfind $string]\\M&quot; $pos</emph>. It might be nice to add a flag to control word-matching without the need for such manipulations.</para></item.i></itemize>
<para>None of these is included in the current TIP or current implementation. If interested members of the community wish to extend this TIP or submit further TIPs to handle any of these enhancements, they are very welcome (and the author is happy to help coordinate where possible).</para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>
