Version 1 of commandloop

Updated 2004-05-18 15:19:56 by kbk

Tclx documents commandloop as:

     commandloop ?-async? ?-interactive on | off

          Create an interactive command loop reading commands from
          stdin and writing results to stdout. Command loops are maybe
          either be blocking or event oriented. This command is useful
          for Tcl scripts that do not normally converse interactively
          with a user through a Tcl command interpreter, but which
          sometimes want to enter this mode, perhaps for debugging or
          user configuration. The command loop terminates on EOF.

          The following options are available:

          -async
               A command handler will be associated with stdin. When
               input is available on stdin, it will be read and
               accumulated until a full command is available. That
               command will then be evaluated. An event loop must be
               entered for input to be read and processed.

          -interactive on | off | tty
               Enable or disable interactive command mode. In
               interactive mode, commands are prompted for and the
               results of comments are printed. The value maybe any
               boolean value or tty. If tty is used, interactive mode
               is enabled if stdin is associated with a terminal or
               terminal emulator. The default is tty.

          -prompt1 cmd
               If specified, cmd is used is evaluate and its result
               used for the main command prompt. If not specified, the
               command in tcl_prompt1 is evaluated to output the prompt.
               Note the difference in behavior, cmd results is used,
               while tcl_prompt1 outputs. This is to allow for future
               expansion to command loops that write to other than
               stdout.

          -prompt2 cmd
               If specified, cmd is used is evaluate and its result used
               for the secondary (continuation) command prompt. If not
               specified, the command in tcl_prompt2 is evaluated to
               output the prompt.

          -endcommand cmd
               If specified, cmd is evaluated when the command loop
               terminates.

               In interactive mode, the results of set commands with two
               arguments are not printed.

               If SIGINT is configured to generate a Tcl error, it can
               be used to delete the current command being type without
               aborting the program in progress.

KBK 2004-05-18 - Something very similar can be done in pure Tcl; the signal handling and 'isatty' checking is Unix and hence unportable, but the following code works for many purposes:

 namespace eval ::mainloop {
     variable partialCommand {}
 }

 proc ::mainloop::prompt {} {
     variable partialCommand

     if { [info complete $partialCommand] } {
         set status [catch {
             uplevel \#0 $partialCommand
         } result]
         if { $result ne {} } {
             if { $status != 0 } {
                 puts stderr $result
             } else {
                 puts stdout $result
             }
         }
         set partialCommand {}
         if { [info exists ::tcl_prompt1] } {
             catch { uplevel \#0 $::tcl_prompt1 } prompt
         } else {
             set prompt "% "
         }
     } else {
         append partialCommand \n
         if { [info exists ::tcl_prompt2] } {
             catch { uplevel \#0 $::tcl_prompt2 } prompt
         } else {
             set prompt "> "
         }
     }
     puts -nonewline stderr $prompt

     return
 }

 proc ::mainloop::readable {} {
     variable partialCommand
     variable eof

     if { [gets stdin text] < 0 } {
         fileevent stdin readable {}
         set eof 1
     } else {
         append partialCommand $text
         prompt
     }
     return
 }

 proc ::mainloop::mainloop {} {

     variable eof

     set ::tcl_interactive 1
     info script ""

     fconfigure stdin -buffering line -blocking 0
     fileevent stdin readable ::mainloop::readable

     ::mainloop::prompt

     vwait [namespace which -variable eof]

     return
 }

 ::mainloop::mainloop


Category Command, a part of Tclx