Version 3 of Text widget elision

Updated 2004-07-25 20:26:46

if 0 {Richard Suchenwirth 2004-07-24 - Tk's text widget has since version 8.3 received an -elide feature which I hadn't tried yet. So in this weekend fun project, I experimented how to implement "folding" parts of a text content.

The command elidify adds buttons in a text widget wherever an open brace appears at end of line (the typical pattern for proc bodies). If such a button displays "-", clicking it will elide (hide) the braces and its contents; clicking a "+" button will make the braces and its contents reappear. This way one can "close" details one is not interested in, and see more of the grand picture instead.

Buttons have the advantage that they don't show up when you retrieve the text content, say for saving to a file. }

 proc elidify w {
    set from 1.0
    set id 0
    #-- remove previous elidify buttons (if you have no other embedded widgets)
    foreach i [winfo children $w] {
       destroy $i
       $w tag delete $i
    }
    while 1 {
        set here [$w search -regexp {\{$} $from end]
        if {$here eq ""} break
        set n 1
        while {![info complete [$w get $here "$here + $n chars"]]} {
            if {[incr n]>65536} break ;#-- avoid runanway loops on unbalanced braces
        }
        set there [$w index "$here + $n chars"]
        set b $w.[incr id]
        button $b -text - -command "eliToggle $b" -pady 0
        $w window create $here -window $b
        $w tag config $b -elide 0
        $w tag add    $b "$here + 1 char" "$there + 1 char"
        set from [$w index "$there + 2 chars"]
    }
    set id ;# returns the number of elidable sections
 }

# This procedure is called whenever a "folding" button is clicked

 proc eliToggle w {
    if {[$w cget -text] eq "-"} {
        $w config -text +
        [winfo parent $w] tag config $w -elide 1
    } else {
        $w config -text -
        [winfo parent $w] tag config $w -elide 0
    }
 }

if 0 {Let's now test the whole thing on its own source code:}

 pack [text .t -wrap word] -fill both -expand 1
 set fp [open [info script]]
 .t insert end [read $fp]
 close $fp
 elidify .t

Arts and crafts of Tcl-Tk programming