Version 5 of Windows wish console

Updated 2004-04-28 14:32:26

Richard Suchenwirth - While on Unixes, the standard channels stdin, stdout, and stderr are the same as the terminal you started wish from, a Windows wish doesn't typically have these standard channels (and is mostly started with double-click anyway). To help this, Scriptics has added a console that takes over the standard channels (stderr even coming in red, stdin in blue). The console is normally hidden, but can be brought up with the command

  console show

somewhere near the beginning of your wish script. In the 8.2.2 Winhelp, the console command is not contained, but from playing with it, you can find out

 % console help
 bad option "help": should be hide, show, or title

And there's even more to it, as Frederic Bonnet tells us:

You can use the undocumented "console" command. "console eval <script>" evals the given script in the Tcl interpreter that manages the console. The console's text area is actually a text widget created in this interpreter. For example:

        console eval {.console config -font fixed}

will change the font of the console to "fixed". Since the console is a Tk text widget, you can use all text widget commands and options on it (for example, changing colors, bindings...). (comp.lang.tcl on Jan 13, 2000) NB -- on Unixes, fixed is a nice little fixed-pitch font. On my NT, fixed brings something like Arial 14. For fixed pitch, -font {Courier 9} comes out better.


Bryan Oakley adds... the "console" command isn't really an "undocumented command", so much as an artifact of how the console is implemented. "console" is merely the name of the slave interpreter that the console runs in.

RS: By "undocumented" I meant I don't see it in the Tcl 8.2.2 Winhelp index. The analogy with a slave interpreter is evident with eval, but "console hide" is quite different from slave hide, and slave show or slave title are not possible (or undocumented ;-) with slave interpreters.


 console eval {winfo children .}

tells you more about the console widget: it is a toplevel with children .menu, .console (text), and .sb (scrollbar). You can resize the whole thing with

 console eval {wm geometry . $Wx$H+$X+$Y}

where $W and $H are dimensions in character cells (default 80x24), but $X and $Y are in pixels.


And more again: you can even add widgets to it - try

 console eval {pack [button .b -text hello -command {puts hello}]}

The button appears between the text widget and the scroll bar, and looks and does as expected. Pity though there's no way back: the console interpreter doesn't know the procs, variables etc in the main interpreter. Here's a code snippet from Bryan Oakley how to transport a command between interpreters:

I haven't looked at this code in ages. Looking back, I see I had to do something vaguely clever -- I placed the command in the clipboard and then generated a <<Paste>> event in the console's text widget. This triggered the console's code to evaluate the command:

    # performs a command. It has different behavior depending on whether
    # it is running from within the console interpreter or the master
    # interpreterproc ::projectbar::doCommand {cmd} {
        if {[runningInConsole]} {
            set cmd "[string trimright $cmd]\n"
            clipboard clear
            clipboard append $cmd
            event generate .console <<Paste>>
        } else {
            eval uplevel \#0 $cmd
        }
    }

Don't rely too much on these features, however - undocumented as they are, Scriptics may change them at any time without notice ;-)


KBK (14 November 2000) -- There is a way back: the main interpreter is visible in the console interpreter under the name, consoleinterp. With this in hand, check out some code for adding control of the console to the Windows system menu.


Ioi Lam - One could also rebuild wish.exe so that it's linked as a console app instead of a gui app. That way, wish uses the "DOS Windows" as the console. This also means the console history won't vanish after wish.exe exits. This is not very useful with Win9x, as the DOS console is limited to 50 lines. However, on WinNT, the console has upto 999 lines so this should be more or less equivalent to what you get on Unix.

'Piotr Deszcz' - Ioi. Could you put here some detail notes how to link 'DOS' console to wish ?

KBK -- On 8.4, you can get this effect even easier, by doing 'load Tk84' or 'package require Tk' inside tclsh!


14 May 2001: Tim Baker posts in comp.lang.tcl:

I like to add a Clear menu command:

    console eval {.menubar.edit add command \
        -label "Clear" -underline 4 \
        -command {.console delete 1.0 end ; tkConsolePrompt}}

HD: Here's some code to save a Tcl session. Click on the "File" menu, then "Save session". "Input only" saves only the commands you have entered, and "Input and Output" saves everything in the console window.

 console eval {
     .menubar.file add cascade -label "Save session" -underline 2 \
             -menu .menubar.file.sess
     menu .menubar.file.sess -tearoff 0
     .menubar.file.sess add command -label "Input only" \
         -underline 0 -command {saveSession 0}
     .menubar.file.sess add command -label "Input and Output" \
             -underline 10 -command {saveSession 1}
     proc saveSession {{all 1}} {
         set fTypes {{"Text files" {.txt}} {"All files" {*}}}
         set f [tk_getSaveFile -filetypes $fTypes -title "Save session"]
         if {$f == ""} {
             # User cancelled the dialog
             return
         }
         if [catch {open $f "w"} fh] {
             messageBox -icon error -message $fh -title \
                     "Error while saving session"
             return
         }
         if {$all == 1} {
             puts $fh [.console get 0.0 end]
         } else {
             foreach {start end} [.console tag ranges stdin] {
                 puts -nonewline $fh [.console get $start $end]
             }
         }
         catch {close $fh}
     }
 }

KBK (11 January 2002) - The Windows Wish console gets extremely slow once it contains more than a few hundred lines of text. If this problem makes your app slow to a crawl because it contains print-outs for debugging, you may want to do something like the following:

  proc keepConsoleClean {} {
      after 1000 keepConsoleClean
      console eval { .console delete 1.0 end-100l }
  }

to keep it to a smaller number of lines. Season to taste.

JH The console was updated for 8.3.4+ to have more features of tkcon. This also includes constraining the number of lines in the console, as the above problem was potentially serious and very subtle in affecting long-running apps where users didn't remember they were puts'ing all the time. The default maxLines is 600, but this can be changed with something like:

 console eval { set ::tk::console::maxLines 10000 }

[put in something here about hiding "DOS box"]

LV well, after a year, I am still wondering how one goes about hiding the DOS window that gets created when one runs the tclsh program.


Microsoft Windows and Tk - Arts and crafts of Tcl-Tk programming


Category Documentation