if 0 {[Richard Suchenwirth] 2003-08-12 - In contrast to [a basic editor] which has quite some features, here's an utterly simple one which just allows to load and save files, and of course edit, and cut and paste, and whatever is built-in into the [text] widget anyway. And it has a bit "online help"... ;-) This is yet another study in [literate programming]. For the bare source code (26 lines), see [A minimal editor]. It is always a good idea to start a source file with some explanations on the name, purpose, author, and date. I have recently picked up the habit to put this information into a string variable (which in Tcl can easily span multiple lines), so the same info is presented to the reader of the source code, and can be displayed as online help: } set about "minEd - a minimal editor Richard Suchenwirth 2003 F1: help F2: load F3: save " if 0 {The visible part of a Graphical User Interface (GUI) consists of [widget]s. For this editor, I of course need a [text] widget, and a vertical [scrollbar]. With the option "-wrap word" for the text widget, another horizontal scrollbar is not needed - lines longer than the window just wrap at word boundaries. Tk widgets come on the screen in two steps: first, they are created with an initial configuration; then, handed to a "geometry manager" for display. As widget creation commands return the pathname, they can be nested into the manager command ([pack] in this case), to keep all settings for a widget in one place. This may lead to over-long lines, though. Although the scrollbar comes to the right of the text, I create and [pack] it first. The reason is that when a window is made smaller by the user, the widgets last packed first lose visibility. These two lines also illustrate the coupling between a scrollbar and the widget it controls: * the scrollbar sends a ''yview'' message to it when moved * the widget sends a ''set'' message to the scrollbar when the view changed, for instance from cursor keys And these two lines already give us an editor for arbitrarily long text, with built-in capabilities of cut, copy, and paste - see the [text] man page. Only file I/O has to be added by us to make it really usable. } pack [scrollbar .y -command ".t yview"] -side right -fill y pack [text .t -wrap word -yscrollc ".y set"] -side right -fill both -expand 1 if 0 {The other important part of a GUI are the bindings - what event shall trigger what action. For simplicity, I've limited the bindings here to a few of the function keys on top of typical keyboards:} bind . {tk_messageBox -message $about} if 0 {Online help is done with a no-frills [tk_messageBox] with the "about" text defined at start of file. - The other bindings call custom commands, which get a filename argument from Tk's file selector dialogs:} bind . {loadText .t [tk_getOpenFile]} bind . {saveText .t [tk_getSaveFile]} if 0 {These dialogs can also be configured in a number of ways, but even in this simple form they are quite powerful - allow navigation around the file system, etc. On [Windows] they call the native file selectors, which have a history of previously opened files, detail view (size/date etc.) When this editor is called with a filename on the command line, that file is loaded on startup (simple as it is, it can only handle one file at a time):} if {$argv != ""} {loadText .t [lindex $argv 0]} if 0 {The procedures for loading and saving text both start with a sanity check of the filename argument - if it's an empty string, as produced by file selector dialogs when the user cancels, they return immediately. Otherwise, they transfer file content to text widget or vice-versa. ''loadText'' adds the "luxury" that the name of the current file is also put into the window title. Then it opens the file, clears the text widget, reads all file contents in one go, and puts them into the text widget.} proc loadText {w fn} { if {$fn==""} return wm title . [file tail $fn] set fp [open $fn] $w delete 1.0 end $w insert end [read $fp] close $fp } if 0 {''saveText'' takes care not to save the extra newline that [text] widgets append at end, by limiting the range to "end - 1 c"(haracter).} proc saveText {w fn} { if {$fn==""} return set fp [open $fn w] puts -nonewline $fp [$w get 1.0 "end - 1 c"] close $fp } if 0 { [DKF]: Are you targetting 8.4 or later? If so, add ''-undo 1'' to the options to [text] and get full undo/redo support. Easy!} ---- [Arts and crafts of Tcl-Tk programming] [Category Editor utility]