Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
#!/bin/sh # the next line restarts using expect \ exec expect "$0" -- "$@" # (find-man "1 tclsh" "#!") # eeg4 and eeg: support for the "generic" interface for eev. proc COPYRIGHT {} { puts {\ This is the `eeg4' file of GNU eev (and also the `eeg' file, due to a link). Copyright (C) 2001,2002,2003,2004,2005,2008 Free Software Foundation, Inc. This file is part of GNU eev. GNU eev is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU eev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU eev; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Author: Eduardo Ochs <eduardoochs@gmail.com> Maintainer: Eduardo Ochs <eduardoochs@gmail.com> Version: 2008jul03 }} ### Comment: # eeg4 and eeg: support for the "generic" interface for eev. # Keywords: e-scripts, processes # # Latest version: <http://angg.twu.net/eev-current/eeg4> # htmlized: <http://angg.twu.net/eev-current/eeg4.html> # See also: <http://angg.twu.net/eev-current/README.html> # and: <http://angg.twu.net/eev-current/eegchannel.html> # With this script almost any program that takes input from stdin # becomes e-scriptable. The file $EEG (usually ~/eev-current/tmp/ee.eeg) # contains a sequence of "actions"; when we invoke a program through # eeg4 or eeg, with # # eeg4 [options] program [args] # or eeg [options] program [args] # # this script will run "program args" with a bit of keyboard (i.e., # stdin) translation: if we type a "M-l" ("meta-L", which is the Emacs # terminology for an alt-L), eeg4 will capture it and instead of # sending it to the program it will run an action from its list; for # example, in # # cat > $EEG <'---' # echo $shell # exit # --- # eeg tcsh # # the first action will be "send the string 'echo $shell' to the # controlled program, followed by a newline", and the second will be # "send the string 'exit' to the controlled program, followed by a # newline", and so if we run the block above with M-x eev and "ee" and # we type some "M-l"s to eeg we will see something like: # # /home/edrx(edrx)# ee # cat > $EEG <<'---' # echo $shell # exit # --- # eeg tcsh # angg:~# echo $shell # /usr/bin/tcsh # angg:~# exit # exit # /home/edrx(edrx)# # # Compare with what we would see if we had run tcsh and typed "echo # $shell" and "exit" by hand: # # /home/edrx(edrx)# tcsh # angg:~# echo $shell # /usr/bin/tcsh # angg:~# exit # exit # /home/edrx(edrx)# # # but in the first case we only had to type "e e <enter> M-l M-l" in # the shell. # # If this script is invoked as "eeg" then each line of $EEG becomes an # action like "send the contents of this line, followed by a newline"; # if it is invoked by any other name (for example, eeg4) then $EEG is # interpreted as a Tcl script; the block # # cat > $EEG <'---' # l {echo $shell} # l {exit} # --- # eeg4 tcsh # # is equivalent to the block used in the example above. # # I have tried to keep this script as minimal as possible; it works # and is useful enough, yet, plus, it has a mechanism for loading # extensions! Take a look at the "loadeeglib" section below and at the # "eeg libraries" that it refers to -- in Tcl it is trivial to replace # a function by just redefining it, so some of the extensions redefine # functions in this file by other, not so minimal, versions. # Note, 2004dec29: commented out the code for loadeeglib (see below). # «.misc» (to "misc") # «.loadeeglib» (to "loadeeglib") # «.actions» (to "actions") # «.dointeraction» (to "dointeraction") # «.actionkey» (to "actionkey") # «.doreadscript» (to "doreadscript") # «.eeg» (to "eeg") # «.dospawn» (to "dospawn") # «.arguments» (to "arguments") # «.mainloop» (to "mainloop") #### # # «misc» (to ".misc") # #### # I/O and generic library functions. proc readfile {fname} { set ch [open $fname r]; set str [read $ch]; close $ch; return $str } proc writefile {fname str} { set ch [open $fname w]; puts -nonewline $ch $str; close $ch } proc getenv {key {defaultvalue {}}} { global env expr {[info exist env($key)]?$env($key):$defaultvalue} } proc ord {str} {scan $str %c n; return $n} proc char {n} {format %c $n} proc gset {args} { uplevel #0 set $args } ;# "global set" # This is to remove a trailing newline, when there is one. proc rmlastnewline {str} { regexp "^(.*)\n\$" $str -> str return $str } proc HOME {} { getenv HOME } proc EEVDIR {} { getenv EEVDIR [HOME]/eev-current } proc EEVTMPDIR {} { getenv EEVTMPDIR [EEVDIR]/tmp } proc EEG {} { getenv EEG [EEVTMPDIR]/ee.eeg } #### # # «loadeeglib» (to ".loadeeglib") # #### # (find-angg "eev/libeeg/k") # (find-angg "eev/libeeg/term") # (find-angg "eev/libeeg/msg") # Just add the following to top of your eegscript if you want to load # all the standard extensions and don't want to worry too much about # the details: # # loadeeglibs all ;# (find-angg "eev/libeeg/all") # 2004dec29: This is very old code, I haven't used these libraries # ("all" and stuff) in a long time, and I have even removed their code # from the latest versions of eev... I'm commenting out the code # below. # proc toeeglibfname {stem} { # return [getenv LIBEEGDIR [getenv HOME]/eev/libeeg]/$stem # } # proc loadeeglib {stem} { uplevel #0 source [toeeglibfname $stem] } # proc loadeeglibs {args} { foreach stem $args {loadeeglib $stem} } #### # # «actions» (to ".actions") # #### set actions {} set actions_i 0 proc doaction {} { global actions actions_i uplevel #0 [lindex $actions $actions_i] incr actions_i } proc appendaction {str} { global actions; lappend actions $str } proc _str {str} { send -- $str } proc str {str} { appendaction [list _str $str] } proc _l {str} { send -- "$str\r" } proc l {str} { appendaction [list _l $str] } #### # # «dointeraction» (to ".dointeraction") # #### set action_re "\354|\033l" proc dointeraction {} { global action_re interact -re $action_re {doaction; inter_return 1} return 0 } #### # # «actionkey» (to ".actionkey") # #### proc meta_re {c} { format "%c|\033%s" [expr [ord $c]+128] $c } proc actionkey {c} { gset action_re [meta_re $c] } #### # # «doreadscript» (to ".doreadscript") # #### proc doreadscript {} { uplevel #0 source [EEG] } # «eeg» (to ".eeg") # A hack: if this script is invoked as "eeg" it will interpret the # $EEG file as a sequence of lines to be sent literally, instead of as # a Tcl script. proc doreadscript_eeg {} { foreach line [split [rmlastnewline [readfile [EEG]]] "\n"] {l $line} } proc eeg {} { proc doreadscript {} { doreadscript_eeg } } if {[file tail $argv0]=="eeg"} eeg #### # # «dospawn» (to ".dospawn") # «arguments» (to ".arguments") # «mainloop» (to ".mainloop") # #### proc dospawn {} { global argv; uplevel #0 spawn -noecho $argv; stty raw } set oldargv $argv while 1 { if {[lindex $argv 0]=="-c"} { uplevel #0 [lindex $argv 1] set argv [lrange $argv 2 end] } if {[lindex $argv 0]=="-f"} { set env(EEG) [lindex $argv 1]; # QUICK HACK, AFFECTS SUB-"eeg"S! FIX THIS! set argv [lrange $argv 2 end] } if {$oldargv==$argv} break else {set oldargv $argv} } doreadscript dospawn # Code for SIGWINCH added in 2005jan08. # Transmit resizings. From <http://www.hadron.org/~hatch/goodies/rrr>. trap { stty rows [stty rows] columns [stty columns] < $spawn_out(slave,name) } WINCH # The main loop: while {[dointeraction]} {} # # Local Variables: # mode: tcl # coding: raw-text-unix # ee-anchor-format: "«%s»" # End: