Can a non-interactive tclsh be made interactive?

57 Views Asked by At

When developing Tcl code, I find the interactive facilities of tclsh very useful, and I'll often launch tclsh interactively, source code from files, and continue to run and debug from there.

What I'm wondering is: is there a way to drop into the interactive shell from a tclsh instance that is not interactive (say because it was run with a script file argument)? I know there's a tcl_interactive variable, which can be set, but doing so does not result in an interactive prompt.

I'd prefer to be able to do this within the same process and terminal (though Tkcon is certainly wonderful).

(I would guess that the tricky thing would be switching Tcl's input from the specified script file to the terminal/pty's stdin. That may be something that requires Expect's magic to work. I've also pondered some trickery using .tclshrc, but that gets messy; I wish tclsh let you specify an rc-file on the command line or via an environment variable.)

2

There are 2 best solutions below

0
On

You could start up a tclreadline REPL:

proc poll {} {
    puts "doing something"
    if {[incr ::pollnum] == 3} {
        package require tclreadline
        tclreadline::Loop
    }
    after 2000 poll
}

poll

vwait forever
doing something
doing something
doing something
tclsh8.7 [/tmp] puts "hello, repl"
hello, repl
tclsh8.7 [/tmp] 
0
On

On all Unix platforms, you get a handle to the terminal by opening /dev/tty. You can then implement your own REPL. The code to do that will look something like this.

set tty [open /dev/tty r+]
fconfigure $tty -buffering none
set buffer ""
while {![eof $tty]} {
    puts -nonewline $tty "> "
    gets $tty line
    append buffer $line "\n"
    if {[info complete $buffer]} {
        try {
            # Or uplevel or interp eval
            eval $buffer
        } on ok result {
            if {$result ne ""} {puts $tty $result}
        } on error {msg opt} {
            puts stderr [dict get $opt -errorinfo]
        }
        set buffer ""
    }
}