- 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
}

