If you don't use the language Tcl/Tk
then this probably won't be of any use to you. Tcl/Tk is an awesome
programming language for throwing together GUI applications on the
desktop, and I've used it for many years. It's not well-known,
however, and sometimes its interface can feel a little lacking. For
instance, for a long time I thought there were only two ways to run
tcl from the command line: either you could type tcl
and enter
interactive mode, or you could type tcl filename.tcl
to run
filename.tcl
in non-interactive mode. There wasn't really a hybrid
option to open an interactive session after running some code, the way
python -i
does. Or at least, so I thought.
The RC Files
Today I discovered that if you create .tclshrc
in your home
directory, then tclsh
will always run that code and then open an
interactive session. Or if you run wish
(the version of tclsh
which includes the Tk graphical extension), it will always run
.wishrc
from your home directory.
Note that it always runs the same file, the one in your home
directory. This might be useful if there are certain packages or
default settings you always like to use, but what if you want to be
able to use different init files in different circumstances?
Well, one thing you can do is to place this code into ~/.tclshrc
or
~/.wishrc
:
catch {source .tclinit}
Then when you run the command in a folder that contains the file
.tclinit
, it will treat that file as an init file instead. If the
.tclinit
file doesn't exist, then it continues on into interactive
mode as usual. You can use any name you want in place of .tclinit
,
although I don't recommend using .tclshrc
or .wishrc
themselves or
else you could end up in an infinite loop if you run tclsh
in the
home directory.
Or maybe you want to be able to choose your init file straight from
the command-line, like python -i file.py
? In that case, put into
~/.tclshrc
the code
catch {source {*}[lrange $argv 1 end]}
Then you can type tclsh -i initfile.tcl
and it will run
initfile.tcl
before dropping into interactive mode.
(You may be wondering where the -i
comes from since it doesn't show
up in the code. Well, the command-line definition of tclsh
is
tclsh ?-encoding name? ?fileName arg arg ...?
What this means is that tclsh
takes the first argument it is given
and tries to open it as a file, which would be great except it does so
non-interactively. But for some reason, if that first argument starts
with a -
and it's not a recognized flag, then Tcl knows that there
isn't a filename coming, and it puts all of its arguments into the
argv
list. You could in fact use any flag in place of -i
so
long as it wasn't known by the interpreter. (For tclsh
, that just
means you need to avoid encoding
; wish
has the flags colormap
,
display
, geometry
, name
, sync
, use
, and visual
as well.)
We could do even more sophisticated things with this method. For
instance, we could combine the two options, running .tclinit
only if
another init file isn't provided:
if {$argc>1} {
catch {source {*}[lrange $argv 1 end]}
} elseif {catch {source .tclinit}} {
puts "No init file found."
}
You could even define your own command-line flags for tclsh
or
wish
by parsing argv
for elements that start with -
. Have a
favorite package like tablelist
that you want to be able to use
interactively in a quick way?
if {[lsearch $argv "-table"]>=0} {
package require tablelist
}
#then continue with the rest of your init code