The characters in a text widget are addressed by their line number and the character position within the line. Lines are numbered starting at one, while characters are numbered starting at zero. The numbering for lines was chosen to be compatible with other programs that number lines starting at one, like compilers that generate line-oriented error messages. Here are some examples of text indices:
|1.0||The first character.|
|1.1||The second character on the first line.|
|2.end||The newline character on the second line.|
There are also symbolic indices. The insert index is the position at which new characters are normally inserted when the user types in characters. You can define new indices called marks, too, as described later. Table 33-1 summarizes the various forms for a text index.
Table 33-1. Text indices.
|line.char||Lines count from 1. Characters count from 0.|
|@x,y||The character under the specified screen position.|
|current||The character currently under the mouse.|
|end||Just after the very last character.|
|image||The position of the embedded image.|
|insert||The position right after the insert cursor.|
|mark||Just after the named mark.|
|tag.first||The first character in the range tagged with tag.|
|tag.last||Just after the last character tagged with tag.|
|window||The position of the embedded window.|
Inserting and Deleting Text
You add text with the insert operation ($t is a text widget):
$t insert index string ?tagList? ?string tagList? ...
The index can be any of the forms listed in the table, or it can be an index expression as described in a moment. The tags, if any, are added to the newly inserted text. Otherwise, string picks up any tags present on both sides of index. Tags are described on page 457. Multiple strings with different tags can be inserted with one command.
The most common index at which to insert text is the insert index, which is where the insert cursor is displayed. The default bindings insert text at insert when you type. You must include a newline character explicitly to force a line break:
$t insert insert "Hello, World\n"
The delete operation takes one or two indices. If only one index is given, the character at that position is deleted. If there are two indices, all the characters up to the second index are deleted. The character at the second index is not deleted. For example, you can delete the first line with this command:
$t delete 1.0 2.0
The text widget supports a simple sort of arithmetic on indices. You can specify "the end of the line with this index" and "three characters before this index," and so on. This is done by grouping a modifying expression with the index. For example, the insert index can be modified like this:
"insert -3 chars"
The interpretation of indices and their modifiers is designed to operate well with the delete and tag add operations of the text widget. These operations apply to a range of text defined by two indices. The second index refers to the character just after the end of the range. For example, the following command deletes the word containing the insert cursor:
$t delete "insert wordstart" "insert wordend"
If you want to delete a whole line, including the trailing newline, you need to use a "lineend +1 char" modifier. Otherwise, the newline remains and you are left with a blank line. If you supply several modifiers to an index, they are applied in left to right order:
$t delete "insert linestart" "insert lineend +1 char"
Table 33-2 summarizes the set of index modifiers.
Table 33-2. Index modifiers for text widgets.
|+ count chars||count characters past the index.|
|- count chars||count characters before the index.|
|+ count lines||count lines past the index, retaining character position.|
|- count lines||count lines before the index, retaining character position.|
|linestart||The beginning of the line.|
|lineend||The end of the line (i.e., the newline character).|
|wordstart||The first character of a word.|
|wordend||Just after the last character of a word.|
The compare operation compares two text indices and index expressions. You must use compare for reliable comparisons because, for example, index 1.3 is less than index 1.13. If you try to compare indices as numbers, you get the wrong answer. The general form of the compare operation is:
$t compare ix1 op ix2
The comparison operator can be one of <, <=, ==, =>, >, or !=. The indices can be simple indices in the forms listed in Table 33-1, and they can be index expressions. Example 33-6 on page 467 uses the compare operation.