- The editor starts automatically on an empty page (controlled by the autostart index in the global array).
- The name of the main window is "obfuscated" to avoid obvious name conflicts.
- The save procedure uses now a reference to the global array. I think that the previous code was broken since it did not modified dynamically the menu when serially editing several files.
 package require Tk
 namespace eval ::pocketeditor {
     variable g
     if {![info exists g]} {
 	array set g {
 	    autostart   on
 	    mainwin     ".__pe"
 	}
     }
     namespace export e
 }
 proc ::pocketeditor::e {{name ""}} {
     variable g
     if ![winfo exists $g(mainwin)] {
 	toplevel $g(mainwin)
 	text $g(mainwin).t -wrap word -yscr "$g(mainwin).y set" \
 	    -width 37 -bd 2 -undo 1
 	scrollbar $g(mainwin).y -com "$g(mainwin).t yview"
 	pack $g(mainwin).t $g(mainwin).y -side left -fill y
 	set m [menu $g(mainwin).m]
 	$g(mainwin) config -menu $m
 	m+ $m File Open.. ::pocketeditor::open
 	m+ $m File Save {::pocketeditor::save ::pocketeditor::g(filename)}
 	m+ $m File "Save as.." ::pocketeditor::save
 	m+ $m File ---
 	m+ $m File Eval {eval [$::pocketeditor::g(mainwin).t get 1.0 end]}
 	m+ $m File Clear {$::pocketeditor::g(mainwin).t delete 1.0 end}
 	m+ $m File ok {console eval {raise .; focus -force .console}}
 	foreach i {Cut Copy Paste} {
 	    m+ $m Edit $i [list event gen $g(mainwin).t <<$i>>]
 	}
 	m+ $m Edit ---
 	m+ $m Edit Undo {$g(mainwin).t edit undo}
 	m+ $m Edit Redo {$g(mainwin).t edit redo}
 	m+ $m Goto Top    {$g(mainwin).t see 1.0}
 	m+ $m Goto Cursor {$g(mainwin).t see insert}
 	m+ $m Goto Bottom {$g(mainwin).t see end}
 	$m add casc -label @ -menu [menu $m.dummy]
 	bind $g(mainwin).t <ButtonRelease-1> {$::pocketeditor::g(mainwin).m entryconf @* -label @[$::pocketeditor::g(mainwin).t index current]; ::pocketeditor::xx}
 	wm geo $g(mainwin) 240x189+0+25
 	set ::g(dir) [pwd]
     }
     if {$name ne ""} {
 	$g(mainwin).t delete 1.0 end
 	$g(mainwin).t insert end [::pocketeditor::get $name]
	 wm title $g(mainwin) [file tail $name]
     }
     raise $g(mainwin)
     focus -force $g(mainwin).t
 }
 proc ::pocketeditor::get name {
     variable g
     if [file exists $name] {
 	set f [::open $name]
 	set g(filename) $name
 	::pocketeditor::K [read $f] [close $f]
     } else {::pocketeditor::corp $name}
 }
 proc ::pocketeditor::K {a b} {set a}
 proc ::pocketeditor::corp name {
     set argl {}
     foreach a [info args $name] {
 	if [info default $name $a def] {
 	    lappend a $def
 	}
 	lappend argl $a
     }
     list proc $name $argl [info body $name]
 }
 proc ::pocketeditor::open {} {
     variable g
     e [tk_getOpenFile -initialdir $::g(dir)]
 }
 proc ::pocketeditor::save {{file_p ""}} {
     variable g
     if {$file_p eq ""} {
 	set file [tk_getSaveFile -initialdir $::g(dir)]
     } else {
 	puts "$file_p"
 	upvar \#0 $file_p file
 	puts "Saving into $file"
     }
     if {$file ne ""} {
 	set ::g(dir) [file dir [file join [pwd] $file]]
 	set f [::open $file w]
 	puts $f [$g(mainwin).t get 1.0 "end - 1c"]
 	close $f
     }
 }
 proc ::pocketeditor::m+ {m head label {cmd ""}} {
     if ![winfo ex $m.m$head] {
 	$m add casc -label $head -menu [menu $m.m$head -tearoff 0]
     }
     if {$label ne "---"} {
 	$m.m$head add command -label $label -command $cmd
     } else {$m.m$head add separator}
 }
 proc ::pocketeditor::xx {} {
     variable g
     $g(mainwin) config -menu ""
     $g(mainwin) config -menu $g(mainwin).m
 }
 package provide pocketeditor 0.1
 if { [string is true $::pocketeditor::g(autostart)] } {
     ::pocketeditor::e
 }JHJL 27/01/06: Can you give me a hint how to install this!
RS: Thanks for your interest, first of all. But consider that I tapped the e code on my cellphone, and still prefer to type
einstead of
package require pocketeditor namespace export pocketeditor::* eto finally get the editor up :^) You're right that namespaces are a good way of packaging software, and sort-of hiding internal details away, and avoiding name conflicts between different modules. But always spelling out fully-qualified names is a bit of an overkill - one design feature of namespaces is that "at home you don't need to say your family name":
 namespace eval foo {...}
 proc foo::bar {...} {
   grill ...
 }
 proc foo::grill {...} {
   bar
 }will resolve grill and bar to the version in the own namespace as first choice.And, also consider the usage scope: while pocketeditor::get and pocketeditor::save are specific to this little thing, and hence deserve to live in the same namespace, other functions are not:- m+ is generic for adding items to owned menus
- xx is just a workaround as long as eTcl can't update menu titles well
- corp is a very generic inverse of proc, can also be used e.g. to transfer procedures between interpreters
- and K finally is the most generic combinator - to draw that into the ::pocketeditor namespace would just lead to code duplication...
- packages are good for comprehensive, engineered libraries of general usability. The ones I use most often are BWidget, Img, tdom
- namespaces are, apart from being used in packages, good for wrapping smaller units not for general use (internal functions and variables), down to single objects in OO
- auto_index provides a gentler way of getting library functions. If you engineeringly start an app with a series of package requires, that code will be sourced even though it may not be used at all. With auto_index, source occurs on demand, and startup is faster.
MB: After RS and EF work, I extended the possibilities of the editor and released it as an open-source sourceforge project :http://tclrep.wiki.sourceforge.net/PocketEditor


