Updated 2011-11-24 08:08:43 by AMG

Command to control Tk's simulated console for environments without a real console available.
http://purl.org/tcl/home/man/tcl8.5/TkCmd/console.htm

Supported subcommands:
console eval script
console hide
console show
console title ?string?

DGP Many of the comments on this page might more usefully be made over in the Tracker at Tk Feature Request 532540 [1].

It is my understanding that, for some strange reason, Tk does not yet support console on Unix. That seems very anti-Tk to me - why waste so much time being cross platform and then break it by not offering something so simple?

RS I think it was the other way round: on Unixes, where Tcl originated, you'd start wish at a console and be able to use its stdin/out/err from inside Tcl. Windows apps typically don't have these channels, so the Windows wish console was added to compensate for the loss. That WinTk's console grew more powerful (e.g. you can interact with the interpreter while a script is running, which you can't by default on Unix) justifies your wish to re-implant the original "bugfix" into generic Tk - or pull tkcon into the core?

LV I was just thinking of the cases where tcl applications are launched from an application's exec command, or from another tk application, or from a Unix desktop icon or launcher, etc. The stdin and stdout in all these cases will not necessarily be an interactive terminal window.

LV over on manipulating data with tcl an interesting note came up - when the user invoked a piece of code making use of Plotchart from Tkcon on Windows XP, the console command failed, but if they invoked it from a wish console, the code worked fine.

LV Okay, so what is an example of portable code to make up for the fact that console show does not work on many platforms?

RJM Well, I think this question is worth a separate page: console platform portability

Certainly I can see having at least the minimal console everywhere -I would also be heartily in favor of tkcon or something better being the default console across platforms.

Of course, in both cases, a TIP is going to be needed...

Actually, would a TIP really be needed to activate a command that was already present on the other platforms?

See console for Unix.

[JL] Why hasn't the console ever been made available on Unix? (I've checked up to 8.4) console.n and console.tcl are already installed, and it is useful for simple interactive debugging. All that's needed is to supply the 'console' command, or use something like the workaround above.

This is not the same as adding tkcon. All I want is just the same, simple console across all platforms.

LV I don't recall whether a TIP has been filed to make this happen.

RS uses the following binding to have a console for debugging pop up when needed:
 bind . ? {catch {console show}}

RA2 Hi! I'd like to attach a console to my TCL program. What code do I enter, where and how to start a console maximized (100%)? Thanks I appreciate!

RS: See console and Maximizing a toplevel window, but here's what works for me on Win XP:
 % console show
 % console eval {wm state . zoomed}

RA2 Thanks so much Richard! You are very kind!

MG Feb 16th 2005 - Out of sheer curiousity, I had a quick poke around to see if I could find how to change the prompt on the console, and found this (in ActiveTcl 8.4.9.0 on WinXP):
  (Griffiths) 2 % console eval {set ::tk::console::defaultPrompt}
  subst {([file tail [pwd]]) [history nextid] % }

I don't know if that's the default on all platforms, and I doubt that this is the Right Way to change the prompt (I think the internals of the console are subject to change without notification), but for now at least this works..
  console eval {set ::tk::console::defaultPrompt {return "% "}}
  proc % {args} {
     eval $args
  }

That sets the prompt to "% ", so that you can copy things you've typed into the console and paste them back in to run them again without having to remove the prompt. If you want the same effect but you want to keep the line number, just use
  console eval {set ::tk::console::defaultPrompt {subst {% ([history nextid]) }}
  proc % {lineNumber args} {
    eval $args
  }

2005-04-23 Derek Peschel Evidently the discussion goes here and the code goes on the console for UNIX page. See my questions in Ask, and it shall be given # 2. I've put these items here because they aren't questions.

Brian Theado and I and maybe others have changed the console for UNIX script as part of the TkOutline project [2]. After someone helps answer two questions I have, I think the changes should be propagated back here. They are:

  1. The script has a few more comments. I also changed the punctuation of the comments for no other reason than personal taste.
  2. It uses the $_ variable when evaluating the library console.tcl file as well as when checking it for readability. I changed the name of the library file (so I could have my own version with a bigger font) and wasted some time wondering why my changes weren't being read.
  3. Maybe more; I haven't looked in detail.

Brian Theado - I'm pretty sure my console.tcl code is verbatim from console for UNIX--I've made no changes to it. I don't think anyone would object to enhancing the comments in the code on that page.

As mentioned in private email, I recommend against having your own copy of the library console.tcl and instead use the [console eval] command to get access to the console's interpreter and change the font. i.e.
 console eval {.console configure -font {Courier 14}}

Examples illustrating the console interpreter vs. the main Tcl interpreter

Show the windows available to the main application interpreter:
 winfo children .

Show the windows that makeup the console toplevel:
 console eval {winfo children .}

Text typed into the console is read by the console interpreter and the command is passed to the main application interpreter.

The [console eval] command provides access to the console's interpreter.

The console uses a separate interpreter likely in order to avoid confusion/collision of window names and command names that are used by the console.

By having this interpreter, these windows and commands are hidden unless the [console eval] command is used.

08/31/2005 [BHE] I added an extra menu to the menubar for 'Options' and created an (un)word wrap option. It required that I also add a horizontal scrollbar and change the geometry manager from 'pack' to 'grid'.

Add this block to proc tk::ConsoleInit before the help menu is added:
       .menubar add cascade -label Options -menu .menubar.options -underline 0
       menu .menubar.options -tearoff 0
       .menubar.options add checkbutton -label "Word Wrap" \
          -underline 0 -command tk::ConsoleWrap -variable ::tk::console::wrapLines \
          -onvalue char -offvalue none
       variable ::tk::console::wrapLines char

And then add the horizontal scrollbar to proc tk::ConsoleInit and change the geometry manager:
    set con [text .console  -yscrollcommand [list .sb set] -xscrollcommand [list .hsb set] -setgrid true]
    scrollbar .sb -command [list $con yview]
    scrollbar .hsb -orient horizontal -command [list $con xview]
    #pack .sb -side right -fill both
    #pack $con -fill both -expand 1 -side left
    grid $con .sb -sticky nsew
    grid .hsb -column 0 -row 1 -sticky ew
    grid remove .hsb
    
    grid columnconfigure . 0 -weight 1
    grid rowconfigure . 0 -weight 1

and finally, add this procedure:
 # ::tk::ConsoleWrap --
 #
 # Toggles the word wrapping in the console
 #
 # Arguments:
 # None.
 
 proc tk::ConsoleWrap {} {
     variable ::tk::console::wrapLines
     .console config -wrap $::tk::console::wrapLines
     if {$::tk::console::wrapLines == "char"} {
         # hide the hscrollbar
         grid remove .hsb
         
     } else {
         grid .hsb
     }
 }

It might be a good idea to add a font dialog option to the Options menu as well.

LV One of the frustrating things when using GUI applications is finding that they haven't made it easy to change the font size. Some authors just point people to resource files or suggest they hack the code. But adding something like a font dialog option would be a great step forward.

Inline image in console: This is a good one-liner with fascinating effect:

 proc see name {
    console eval [string map [list @ $name] {.console image create end -image [image create photo -file @]}]
 }

Tested to work on Windows XP and CE (eTcl console). With Img loaded before for extra formats, a lot of images can be inspected interactively... RS 2006-01-16

NEM See the TkCon page for a version for that console. - RS: NEM convinced me that to do it in two lines can make more robust code (say when spaces are in the filename). So the revised version is:
 proc see name  {
   set im [console eval [list image create photo -file $name]]
   console eval [list .console image create end -image $im]
 }

Console menu magic: Put the commands you need most often into existing or newly created sub-menus. This way you can turn the console into your custom IDE, step by step. (RS 2006-01-19)

Add a heading to the console menu:
  console eval {
    .menubar add casc -label Extra -menu [menu .menubar.extra -tearoff 0]
 }

Add an item to the console menu:
 proc menu+ {head label cmd} {
   set cmd2 [list consoleinterp eval $cmd]
   console eval [list .menubar.$head add command -label $label -command $cmd2]
 }

Usage example (with the "Extra" menu created just before):
 menu+ extra auto_mkindex {auto_mkindex . *.tcl}

See also Extending the eTcl console - except for the toolbar stuff, what's said there applies to all consoles.

See also a minimal console.

The wiki page deep console covers an enhanced console.

LV 2007 June 05 - is there a way to add code to my application so that if the application attempts to write to stdout, stderr, or attempts to read from stdin, then the console is shown, but otherwise, it remains hidden?

MG You could overload puts (and probably read and gets as well) to run a [console show] when they're used on one of those channels. This isn't a complete solution, though - I'm fairly sure there are commands that can take a -channel arg to read or output to a channel directly which don't go through puts or gets/read. It's the closest I can think of, though...

Set the maximum number of lines
console eval {set ::tk::console::maxLines 10000}

Add color and style to console output
proc cputs {dest string} {
    if { ! [info exist ::tk::my_color_set] } {
        set ::tk::my_color_set 1
        console eval {
            .console tag configure green            -foreground green  -font {courier 20 bold}
            .console tag configure yellowonblack    -foreground yellow -background black
            .console tag configure yellow           -foreground yellow
            .console tag configure whiteonred       -foreground white -background red
            .console tag configure red              -foreground red
        }
    }
    console eval [list ::tk::ConsoleOutput $dest $string]
}

# demo use

cputs yellowonblack "this is a sample warning" ; cputs normal "\n"
cputs whiteonred    "this will extend to window border\n"
cputs green "go ahead, the light is green\n"

#Any unknown color reverts to black on white - e.g. use of the tag normal here. 
#Tags can be reconfigured and will affect all previous cputs output.

ET The above provides an alternative to puts, this lets you define your own text formatting. The actual console code defines a number of tags already, (stderr = red, stdin = blue, and others). This is why [puts stderr {string}] writes to the console in red.

This does not output a newline. You can add the \n escape in your string. You can intersperse with puts statements, as these eventually all get to the ConsoleOutput code. ET old version would bug out with a } in the text string.

ET I've recently tried out a new version of tcl/tk (8.6b1.1 as of 6/6/2010) and now the added widgets I've included into my console get focus when I type <tab> in the console window (to fill in such things as variable names - like tab in a unix shell). Since <escape> does the same function as <tab> in the console, this is not a showstopper but is just rather annoying. I haven't been able to figure out what has changed and how to fix it.

AMG: On win32, [console] prefers to set the font to ProFontWindows, if present. This font can be found here: [3]. It's available in both bitmap and TrueType formats.

AMG: [console] behaves weird when there are already stdin/stdout/stderr channels. For instance, run wish from a MinGW [rxvt] terminal, then type "console show" into the rxvt. The console window will appear, it'll show the prompt like normal, and it'll accept commands. However, subsequent prompts will be sent to the rxvt, as will anything that's written to stdout or stderr.


See also: