Changes for version 2.06 - 2026-11-11
- Ragged trees: the leaves of a block's tree may be at different depths (the manual's new section "Ragged trees"). The widget keeps the stored tree uniform, a shallower leaf hanging from its parent through padding nodes (a flag in the node), which no command names; every command that names nodes follows the real tree: block at and block of (a node is a list of its children, leaves and nodes side by side), block nodedata (levels count real ancestors from the leaf; negative levels from the root), the addresses of values in undo steps and in -valuecommand's $where (where the node's first leaf starts, the level counted from that leaf), block trim, and the layout callback's arguments (with -layoutdepth, a shallower leaf is presented inside lists of one element down to that depth). The uniform tree shows only in block list and in the levels of block split. New command "block sprout index1 ?index2?": with two indices the leaf holding the range becomes three children of its parent, the text before the range, a new node holding the range as its only leaf, and the text after it (a range that starts on the delimiter before the leaf, or ends just after the one after it, makes no start or end piece); with one index (decision O8) the leaf the index names gets a new node above it, the only leaf of a block included. Returns the number of separators put in. New command "block flatten index level": the node "level" real levels above the leaf of index becomes one leaf; at the root the block becomes a single leaf (block at gives one number, block list the depth -1, the layout callback gets the leaf alone, nodedata 0 and -1 name it; a newline, a split or block sprout give it a root again). Returns the number of separators deleted. Deletions that join two leaves of different depths first give the shallower one new nodes (WRAPs) until both are equally deep, then join them as before; a newline typed in a leaf, and block split at level 0, make a sibling at the leaf's depth. Format change of block list (decision L1): the separator before a leaf with padding is a pair [depth, defect] (a blessed array of class Tk::Text::BlockSeparator, the defect being the number of padding nodes above the leaf), and a padded first leaf gets [undef, defect] in front of it; the list of a tree whose leaves are equally deep is as before. A single-leaf block has the depth -1. The undo and the redo of every structural edit are exact for ragged trees: the tree, the padding and the values come back (the undo is the inverse sequence of the edit's steps; its lists carry the padding). block sprout and block flatten are recorded for undo, each a kind of edit of its own for -autoseparators. -valuecommand: the steps of block sprout, block flatten and of deletions across depths are told one by one (a WRAP or a PULL OUT changes the level in the address of the nodes above: "move" with the place after the step); new event "copy" for the value block sprout shares between the pieces; new event "new" (decision O5, option A), told before a change for each node or leaf it creates without a value, with its place after the change and the value undef (newlines in blocks, block split, block insert, block sprout, the WRAPs of a deletion, the leaves a dissolved block leaves in the block around it, a single-leaf block's new root); not told for what an undo or a redo re-creates. block split now tells "move" for the root's value when it adds levels: it inserts the new nodes between the root and its children, so the root's address grows. The error of block nodedata for a level beyond the root says "... has N levels above this leaf" (it said "above its leaves"). PROVISIONAL (BUGS 28): which sequence of steps an edit uses (block flatten's recipe, a deletion's WRAPs of the shallower leaf), the value rules of the steps (a join keeps the start side's value; a pull out the node's; block sprout shares the former leaf's value), and the -valuecommand events of these commands ("copy", "new", the steps told one by one). Fixed (BUGS 29, since 2.01): the undo of a deletion inside a block re-created the separators of level above 0 with the tags of the place, also those the deleted range had off there. Fixed (BUGS 30, since 2.05): -getflags was ORed into the widget's own text extractions, so reserved bits changed what block list and the undo's records contained (0x200 left the node values out). The widget now uses only the documented bits and ignores the others. Fixed (BUGS 31, since 2.05): a value set, after a deletion that dissolved a nested block, on a leaf the dissolution made in the enclosing block went, with the undo, to the leaf of the re-created block at the same place, and the redo, which dissolves that block again, took it into the undo step with the block's values: the leaf came back without it. Such a value now waits in the undo step (told "stash"), as one whose place does not exist after the undo does (BUGS 26), and the redo gives it back to the leaf of the enclosing block (told "restore"). The random -valuecommand test no longer lets an undo or a redo leave a node without a value. Tests: t/ragged.t, t/flatten.t, t/getflags.t; t/stress.t and t/valuecommand-random.t edit ragged trees at random, undo and redo at once and compare the block list with values and the shape of every block; the random -valuecommand test checks in half of its widgets, where every node has a value before each command, that every node a command creates is told "new".
Modules
a Tk text widget with nestable "blocks" (editable formulas)