'''text''' ''pathName ?options?'' '''[tk_textCopy]''' ''pathName'' '''[tk_textCut]''' ''pathName'' '''[tk_textPaste]''' ''pathName'' The man page http://purl.org/tcl/home/man/tcl8.4/TkCmd/text.htm documents '''text''', as well as '''[tk_textCopy]''', '''[tk_textCut]''', and '''[tk_textPaste]''' functions. First announced 1992-08-07 with Tk 2.2 ([http://groups.google.com/groups?q=group:comp.lang.tcl+author:ousterhout&start=900&hl=de&lr=&newwindow=1&scoring=d&selm=15ue4cINNq9u%40agate.berkeley.edu&rnum=990]) ---- The '''text''' command creates a text widget. '''text''' is one of Tk's two "Swiss Army" widgets that create powerful semi-custom components ('''[canvas]''' is the other). A text widget can be anything from a multi-line entry to a fully functional Web browser. [Derek Fountain]'s article, "The Tk Text Widget" [http://www.linuxjournal.com/article.php?sid=7357&mode=thread&order=0], nicely introduces text to [Tcl] newcomers. ---- [Bruce Hartweg] writes on comp.lang.tcl: [[To move the text widget cursor to an index,]] there is a special mark named ''insert'' that is used that monitors/controls where the insertion cursor is .txtarea mark set insert 1.0 [[how do I get the selection? I.E. a start and end index from a dragged selection..]] there is a special tag called sel that is the current selection .txtarea tag ranges sel [Bryan Oakley] follows up with these examples: set start [.textarea index sel.first] set end [.textarea index sel.last] # or... set range [.textarea tag ranges sel] ---- Interesting pages on the '''text''' widget include: * [Read-only text widget] * [Text Widget Newline Wrapping] * [Text Widget Syntax Highlighting] * [Text widget undo/redo] * [Text widget example] * [A change-sensitive text widget] * [A little Unicode editor] * [Multi-column display in text widget] * [Text variable for text widget] * [ANSI color control] * [Super and Subscripts in a text widget] * [A simple slideshow] * [htext] * [a way to 'pipe' from an external process into a text widget] * [a simple file-viewing text widget] * [Move cursor by display line in a text widget] * [Auto extending text widget tags] * When working with text tag bindings its useful to know the [Behavior of break for text tag bindings]. The break command in this case does not affect the normal chain of bindtags execution. * [Serializing a text widget] * [URL behaviour in a text widget] * [text::sync] * [Show me all!] (how to show all the lines) * [LabelText -A Multi Line Entry Widget] * [Multiline expanding entry widget] * [Multi-Line Text Entry Widget - With Entry Widget Like Field To Field Tabbing] ---- [LV] March 26, 2003 - Anyone have an example of how to set a minimize size on a text widget - so that it cannot be resized any smaller? ---- [Nicolas Desoter] asks on comp.lang.tcl: "Does anyone know how to print the content of a text widget in a postscript file? I need to have main layouts of the contents like character size and eventually fonts and colors. The widget contains some image too." Later he goes on to mention that the application is not available to modify, so he cannot change this into a canvas widget. [Bryan Oakley] suggests checking the widget to see if the widget in question has some sort of introspective capability (like text's dump subcommand) which could be used to get the contents in a parsable format, which then could be used to crecreate the widget in a hidden canvas. [Vince] says he doesn't think it would be much more work just to add a 'print' subcommand to the text widget, coded in C, which makes use of the canvas widget's postscript creation C functions to do this. Is there a way that a general solution for this sort of thing could be developed? ulis, 2003-06-17: This seems related to [Serializing a widget] where you can see how to save and restore a text widget. [LV], June 17, 2003: yes, that seems like a good start towards the goal. ---- One of the ''gotchas'' of text was recently discussed in the wiki's chatroom [[add wikit reference later]]. The topic was setting a variable to the contents of a text widget. [RS] (== [suchenwi]) mentioned: [suchenwi]: I think the trailing newline is obligatory in text widgets. (For saving, one often writes [[$text get 1.0 end-1c]] (where both 1.0 and 0.0 refer to the first character of the first line - 2.0 is the first of the second!) [lvirden]: Richard, so there's always an additional newline (because I sure wouldn't want to save the data without a final newline - I've been seeing data loss here because someone's application fails to write out the last line of data if it isn't terminated. [suchenwi]: Right - the bullet-proof way is to check whether the last char is a \n, and if not, append one. [lvirden]: the gotcha is that the current implementation makes it difficult to determine whether the last newline was input by the user, or is being generated by the code. [suchenwi]: Yes - hence test the presence. But if a user types three or five newlines after the text, the "correct" number may not be preserved. Just avoid that a text file gets longer by one \n on every save... ---- There doesn't seem to be much information on [tags] in this wiki. A short tutorial on their usage might be nice. ---- Dave Duxbury described in [the comp.lang.tcl newsgroup] how the Tab key can be bypassed for text widgets, so it changes widget focus instead of inserting a TAB character: bind Text {continue} bind Text {continue} bind Text {} bind Text {} [Ro] This changes the bindings for all the text widgets. If you only want to change it for a few of the widgets, say a [Read-only text widget], then use this on your widget ".t": bind .t { focus [tk_focusNext %W] break } bind .t { focus [tk_focusPrev %W] break } ---- [GPS] In Tcl/Tk 8.3.4 I've discovered that deleting large amounts of text is very slow (> 30 seconds). When dealing with > 3k lines with many tags it can take quite a while. A solution that I came upon was to delete text in 40 line increments, followed by a final delete 1.0 end. I haven't been able to discover what in the Text widget's code is causing this problem, but I wanted to point this out just in case anyone else runs into it. ---- [RS] just discovered that the Tk text widget has a surprising use on Windows(NT): Copying text from IE to an Outlook message will remove linefeeds. Pasting it first into a Tk text widget, then copying it from there, and pasting it into Outlook Just Works... so Tk can even fix some Windows bugs, albeit with manual effort involved... ---- Moved from [Ask, and it shall be given.] Question: I have a text widget and a vertical scrollbar linked to it and new text is inserted e.g. .a.scroll insert end "new line\n" When lines are inserted the scrollbar will change (slider becomes shorter) but it will still show the first line. However I want the scrollbar to scroll to the bottom of the text so you could always read the last line. - [RS]: Easy one - after inserting text at end, add the command .a.scroll see end ---- [MAK] The text widget's ''search'' command directly provides most of the functionality that you'd need to implement common search dialogs - regexp support, case sensitivity, direction, etc. The one common thing it doesn't provide directly is matching on word boundaries. You can overcome this limitation fairly easily by putting your search into a loop and using the ''-count'' option, which returns the length of the matched range, and the widget's ''compare'' command with indexes using the ''wordstart'' and ''wordend'' index modifiers. Of course, you'll want to save a list of your partial matches so you know when to stop looping, since the search function automatically wraps. Pseudocode: set partialMatches [list] set start "insert" set matchRange {} while {1} { if {$direction == "backwards"} { set index "$start -1 chars" } else { set index "$start +1 chars" } # Perform search set start [eval $w search $switches -count length -- [list $pattern $index]] if {($start == "") || ([lsearch -exact $partialMatches $start] != -1)} { # No partial match or already saw this one break } # Compare matched range to word range set wordstart "$start wordstart" set wordend "$start wordend" if {[$w compare $wordstart == $start] && \ [$w compare $wordend == "$start +$length chars"]} { # Matched whole word - store range for later use and stop. set matchRange [list $start $wordend] break } # Didn't match whole word - store start point for loop # checking and continue searching from there. lappend partialMatches $start } [Vince] comments that it does provide for searching on word-boundaries. Just use '\m' and '\M' in a regexp search pattern. [MAK] But then you have to deal with quoting hell to make sure your search pattern doesn't contain things regexp will parse as a regexp pattern if you're doing a non-regexp search. If the user wants to search for, say, [[foo]] (literal, not regexp), then you have to deal with quoting the brackets. (On the other hand, the above might not work, since wordstart and wordend will probably both be considered to be the first bracket, rather than the first and second, respectively). The search command could certainly use an extra switch for this. :) [Vince] I wouldn't exactly call it quoting hell in this case. A straightforward regsub does the trick: regsub -all {[][\$?^|*+()\.\{\}\\]} $pat {\\&} pat ''You call that straightforward?'' [Vince] -- yes, I do, ''when'' the above regsub is wrapped into a proc (''quote::Regfind'' is what I use). It seems a lot more straightforward and less error-prone than the 20 lines of pseudo-code above (which, according to the above text, might not work)! .text search -regexp -- "\\m[quote::Regfind $word]\\M" $pos [MAK] Well, by "might not work" I meant "might not work as a user intended." To clarify: if you do a search in, say, DevStudio (and probably other MS apps) for "Foo()" and check off the "match whole word only" option, then it will not match "Foo()" even if it is in the file you're searching and it's surrounded by whitespace. Whether you'd consider that behavior wrong or a bug in DevStudio/etc. is a separate issue, but the behavior of the above pseudocode is consistent with that behavior. However, the RE method behaves that way too: % set x "Foo()" Foo() % regexp {\mFoo\(\)\M} $x 0 ...so the "might not work" bit applies to the RE method as well, and in the same way. It's certainly simpler number-of-lines-wise than the loop if that substitution indeed catches all of the RE syntax. Though I'm inclined to agree with the above that that pattern isn't all that straightforward. :P I find myself wondering if you've got extra backslashes in there. I do think your quoting is wrong on your .text search, though: % regexp "\mFoo\M" "Foo" 0 % regexp {\mFoo\M} "Foo" 1 (fixed the quoting above, thanks!) ---- The following questions were moved from "Ask, and it shall be given." in hopes that someone who knows might see them. Are there any attempts out there to get a text widget to display the contents of a very large (e.g. 1 gigabyte) file in a clever incremental way (so we only show what we currently need to show, and obviously only load from disk a few pieces of the file at a time!). How about being able to edit such a huge file yet only commit the changes in one go on a 'save' operation? [ulis], 2004-01-23: If you only need to display parts of a huge file, the obvious solution is [Virtuallist] that virtualizes the display and can 'forget' what is no more needed. ---- Question and answer moved from [Ask, and it shall be given.]. Question (05/02/2003)Hi all, I have a problem in displaying a text in Tk text widget. Actually I am getting a string "fd6" from c function using Tcl_SetVar(pInterp,"testfield",fd6,0); If i print the variable fd6,I am able to get the contents of string.I want to set the contents of fd6 string to a text widget (I am able to set fd6 contents to label&entry because they have -textvariable option) I want to set contents of fd6 string to text widge(text widget dosent have -text variable option). Please help me in this with a sample code. My mail id : amarnr@tataelxsi.co.in [sudhi] - Say .text is ur text widget, then '.text insert end $fd6' will put your variable in the text widget. hope this helps !! ---- Q) I am trying to prepare a notepad editor in which I am not able to create an Undo command. I was told that Ver. 8.4 has an inbuilt command. how do I use that? A) [DKF]: Look at the ''edit'' subcommand of the text widget. Note that you need to turn it on to use it; it is turned off by default because many uses of thetext widget don't need this sort of thing. You could also look through the Tk demos; 8.4 includes a demonstration of how to use the undo/redo feature. ---- When using Tk text widgets, I've run into a weird issue with bindings: if I bind to a particular tag on the widget ($text tag bind hyperlink "do something"), then this all works fine, ''unless'' the "do something" actually creates a new toplevel window. What happens then is the new toplevel is created (on top of everything), but then the default text widget binding for is activated (from the original click), and now the text widget gets the focus and is moved to the front (this is on Windows). Anyone have a good suggestion for how to stop the second binding from firing, but only under these circumstances? (I already have a 'break' in the tag binding, but that doesn't seem to affect the binding on the widget itself). '''This is only an issue if you've added a binding to the text widget which causes it to be raised. On Windows, the Tk B1 binding gives the text widget the focus, and so it's that second binding which will trigger to then raise the window''' ---- Why doesn't the [text] widget have a "-readonly" option like [entry]? -[FW] [KBK] - Primarily for historical reasons. But it isn't at all difficult to do a [Read-only text widget]. ---- The following was moved from the second ask questions page: Hello, I have created a text widget which contains some lines of text entry boxes in a line (see example below). Now it is possible (and how) to move the cursor between this text entry boxes, when the Up-/Down arrows keys are pressed ? +-----------------------------------------------------+ | .-----------. .----------. .-----------. | | Track 1: |Chris Rea | | Title 1 | | | | | `-----------' `----------' `-----------' | | .-----------. .----------. .-----------. | | Track 2: |Chris Rea | | Title 2 | | | | | `-----------' `----------' `-----------' | : : : : : : e.g: If the cursor stay in the box contains "Title 1" and I press the down-key then it should be set in the text box below which contains "Title 2".. I have no idea which Tk function can move the cursor (and input focus) between text entry's. Thanks for tips Werner [Peter Lewerin]: see the [focus] command. Also, have you considered using the TkTable widget instead? Werner: Thanks for your hint. focus exactly does what I want. TkTable widget ? I don't know this (function ?). I use functions only from Tcl8.4/Tk8.4 Manual, BWidget and BLT extentions. Many Thanks, Werner MSH Try the tablelist widget its a text widget based metawidget which allows direct entry into the table (PURE Tcl) excelent. PL: see [Tktable] for the TkTable widget. It's contained in the ActiveTcl distribution, and as it's written by [Jeffrey Hobbs], the '''Tcl guy''', it could be considered "informally standard", if there is such a phrase. ---- Note that [Derek Fountain] is another author of one of the [Tcl articles] published, this one published in Linux Journal, about the text widget. ---- [NEM] ''24Jan2004'': Has anyone ever tried to separate the text widget internal representation (a B-Tree IIRC) from the rest of the code? This is about the only major thing I would like to see change in the text widget. For instance, I am currently writing a widget (in [snit]) to view/edit [XML] files in a simple word-processor--like view. Currently, all information is stored twice - once in the text widget, and once in a [tDOM] data structure. It would be really nice to be able to just tell the text widget to use the DOM tree instead of its own internal representation, i.e., having a clean separation of data and view. I looked at the code that implements the Tk text widget a while ago, but I got lost quite quickly. Anyone more knowledgeable have any good pointers as to how this might be done, or know anyone who's tried it in the past? [Vince] points out that with tip#169 this has actually been done to a large extent in Tk 8.5a2. It's still not as separate as you describe, but it is closer. The basic need would be to have a pluggable interface to ''all'' the TkBTree* functions in tkTextBTree.c. I think the bigger work would be providing an implementation of all of those functions for your tDOM data structure, rather than the modifications to the text widget (which would just require using a function lookup table for all access). By the way, I think it would be a great idea, because it would also allow things like a text widget which just showed a portion of a large (gigabyte, say) file to be written relatively easily in Tcl (assuming this interface was exposed to Tcl). ---- See also [File watch] for how to alert if a file being edited in a [text] has changed outside the editor. ---- [FW]: Is it possible to make a tag encompass the literal beginning of the text? For instance, if I do .t tag add main 0.0 end .t tag config main -background red on an empty text widget, the red background starts after the cursor. Is there any way to make it so the user starts typing directly into the tag? This is very useful if, say, you want to set the margin before someone starts typing. ---- [Tk syntax help] - [Arts and Crafts of Tcl-Tk Programming] - [Category Command] - [Category Widget] - [Category GUI]