entry .e -textvar cmd bind .e <Key-Return> {go %W} text .t -wrap word proc go {w} { global cmd .t insert end "% $cmd\n" catch {eval $cmd} res .t insert end $res\n set cmd "" } eval pack [winfo children .] -fill both -expand 1 focus .ewhich allows you to source any file and call any Tcl command you might want. Of course, this can be expanded with colors to distinguish stdin/out/err, an entry with a history, menus (see Menus made easy), whatever.
Nov-4-2006 GWM however if you enter into this console's entry:
set b 1 set c 2 expr $b+$cyou do not get 3 as the result but "can't read "b": no such variable", as the commands were all executed internal to proc go, and were destroyed on exit. Change the "eval $cmd" line to:
catch {uplevel #0 eval $cmd} resand the expr works (as does puts "B is $b" and so on).
Nov-3-2006 JM Richard, it is probably very simple, but, how can I distinguish between stdin/stdout/stderr? ...or, just give me a hint. Thanks.Nov-6-2006 HE This version differs between stdin/stdout/stderr (or better it differs between the emulation of stdin/stdout/stderr).
entry .e -textvar cmd bind .e <Key-Return> {go %W} text .t -wrap word .t tag configure stdout -foreground blue .t tag configure stdin -foreground black .t tag configure stderr -foreground red proc go {w} { global cmd .t insert end "% $cmd\n" stdin if {[catch {uplevel #0 eval $cmd} res] == 1} { .t insert end "$res\n" stderr } else { .t insert end "$res\n" stdout } set cmd "" } eval pack [winfo children .] -fill both -expand 1 focus .e
But, in all simplicity, this requires the user to know what he's doing. Nothing prevents this code from evaluating "exec format c:"...Eh? Why would you care if somebody did that? Does the widget make that do something other than this:
pehrens@marfik ~:>>tclsh % exec format c: No permission (or no disks found)! %%-)
See console for Unix for Donald Porter's more elaborated console. Tk for Windows has a built-in console that you can have come up just with the command
console showSee Windows wish console for hints how to extend that.
Jeffrey Hobbs -- On the subject of consoles, if you don't need lightweight, you might want to check out http://tkcon.sourceforge.net/ for a cross-platform console environment with lots of features. There is a megawidget version at http://www.purl.org/net/hobbs/tcl/.See the wiki page for Tkcon for more details.
As an alternative how about
proc execute_command {} { set selection [.main tag nextrange sel 0.0] if {[llength $selection] > 0} { set command [.main get [lindex $selection 0] [lindex $selection 1]] .main insert insert [uplevel #0 $command] .main see insert } } text .main pack .main -side top -fill both -expand true # Bind f12 to execute the current selection # bind .main <KeyPress-F12> execute_commandSince this uses the selection multiple lines can be evaluated making it easy to edit/redefine procedures e.g., unknown can be redefined to allow Unix commands to be used - simplest way is to edit the results of info body unknown.
This one is almost as short as the examples above, but more intuitive to use:
package require Tk destroy .console toplevel .console pack [text .console.cmd -wrap word] -expand yes -fill both bind .console.cmd <Return> evalConsoleCmd bind .console.cmd <Return> +break .console.cmd tag configure success -foreground \#008800 .console.cmd tag configure failure -foreground red proc evalConsoleCmd {} { set c .console.cmd if {[$c compare {insert + 1 lines} < end]} then { set l [$c get {insert linestart} {insert lineend}] $c insert {end - 1 chars} \n[string trimright $l] $c mark set insert end $c see insert } else { if {[catch { set result [uplevel 1 [$c get end-1lines end-1chars]] } err]} then { $c insert end \n {} $err failure \n } else { $c insert end \n {} $result success \n } } }