- determine the whitespace prefix of the current line
- insert the prefix on the next line
- if the current line ended in "{", indents one layer more
- and creates the matching "}" line after the insert point.
 proc e'indent {w {extra "    "}} {
    set lineno [expr {int([$w index insert])}]
    set line [$w get $lineno.0 $lineno.end]
    regexp {^(\s*)} $line -> prefix
    after 1 [list $w insert insert $prefix]
    if {[string index $line end] eq "\{"} {
        after 2 [list $w insert insert $extra]
        after 3 [list $w insert insert+1c $prefix\}\n]
    }
 }#-- Testing demo: pack [text .t]
 .t insert end \n ;#-- see below
 bind .t <Return> {e'indent %W}
 focus -force .t
 bind . <Escape> {exec wish $argv0 &; exit}
 bind . <F1> {console show}if 0 {Known problem: if the insert cursor is at the very end of the text, "insert+1c" delivers the same position as "insert", leading to wrong indentation on open-brace. I haven't found a good solution for that. But it rarely happens when editing existing text, and in an empty text widget, just type one newline and <Up> to avoid this problem.2006-03-20 HE I would use this version;-) proc e'indent {w {extra "    "}} {
        set lineno [expr {int([$w index insert])}]
        set line [$w get $lineno.0 $lineno.end]
        regexp {^(\s*)} $line -> prefix
        tk::TextInsert $w "\n$prefix"
        if {[string index $line end] eq "\{"} {
                tk::TextInsert $w "$extra"
        }
 }Or considering the close braces: proc e'indent {w {extra "    "}} {
        set lineno [expr {int([$w index insert])}]
        set line [$w get $lineno.0 $lineno.end]
        regexp {^(\s*)} $line -> prefix
        if {[string index $line end] eq "\{"} {
                tk::TextInsert $w "\n$prefix$extra"
        } elseif {[string index $line end] eq "\}"} {
                if {[regexp {^\s+\}} $line]} {
                        $w delete insert-[expr [string length $extra]+1]c insert-1c
                        tk::TextInsert $w "\n[string range $prefix 0 end-[string length $extra]]"
                } else {
                        tk::TextInsert $w "\n$prefix"
                }
        } else {
                tk::TextInsert $w "\n$prefix"
        }
 }The corresponding binding is: bind .t <Return> {e'indent %W;break}We don't need the row '.t insert end \n' anymore.See also Maintaining indentation in a text widget when go to a new line
}

