Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
243 lines (242 sloc) 5.11 KB
.Dd August 2 2018
.Dt FEED 1
.Nm feed
.Nd feeds commands into a REPL
.Bk -words
.Ar file|-
.Ar command
.Op Ar args ..
reads lines from the given
.Pa file
(or standard input) and feeds these lines to the subsequent
.Ar command ,
Once all the lines have been fed, the user will be able to
.Ic interact
with the REPL manually.
Support for a REPL should ideally be written into
.Pa ~/.feedrc .
See the code for the default behavior.
Input of
.Ic control+z
will cause
(and the
.Ar command )
to stop. A
.Ic control+c
will be relayed from
to the
.Ar command .
.Ic control+\e
if things go horribly awry.
environment variable offers a means to customize the path to what by default
is the
.Pa ~/.feedrc
The file
.Pa ~/.feedrc
must exist, and should contain TCL code that specifies a
.Cm dosomethingwith
proc that will be passed each line of the input in turn.
.Pa ~/.feedrc
will likely end up with a series of if/else statements along the lines
.Dl # "tocall" contains the command name (2nd argument to feed)
.Dl if {$tocall eq \&"pfe\&"} {
.Dl \& \& \& \& expect -re {(ok|bye)}
.Dl \& \& \& \& proc dosomethingwith {line} {
.Dl \& \& \& \& \& \& \& \& if {[regexp {^[[:blank:]]*(\e\e[[:blank:]].*)?$} $line]} {
.Dl \& \& \& \& \& \& \& \& \& \& \& \& return
.Dl \& \& \& \& \& \& \& \& }
.Dl \& \& \& \& \& \& \& \& send -- \&"$line\er\&"
.Dl \& \& \& \& }
.Dl } elseif {$tocall eq \&"gdb\&"} {
.Dl \& \& \& \& ...
There is a default
.Cm dosomethingwith
that will be used if
.Pa ~/.feedrc
does not set one. If this is a problem, end
.Pa ~/.feedrc
with something like:
.Dl if {[info commands dosomethingwith] eq \&"\&"} {
.Dl \& \& \& \& puts stderr oops
.Dl \& \& \& \& exit 1
.Dl }
.Cm dosomethingwith
can signal that no more lines should be processed via the
.Dv terminate
.Dl proc dosomethingwith {line} {
.Dl \& \& \& \& global terminate
.Dl \& \& \& \& ...
.Dl \& \& \& \& if {...} { set terminate 1 }
.Dl \& \& \& \& ...
Various other parts of the code of
can be overridden from
.Pa ~/.feedrc .
You get to keep all the pieces if you break something.
.Ex -std
The exit status once
has begun to
.Ic interact
with the given
.Ar command
will likely always be 0 (regardless how the
.Ar command
exits), unless a
.Dv HUP ,
.Dv PIPE ,
signal is sent.
From a
.Xr vim 1
buffer containing LISP code in a file, one could issue
.Dl Ic :!feed % sbcl --noinform
to feed the data to
.Pa sbcl .
Standard input can also be used;
.Dl $ Ic echo run -al \&| feed - gdb -q ls
would run
.Pa ls
.Pa gdb
and then launch
.Pa ls
with the arguments
.Ar -al
and then turn
.Pa gdb
over to the user. From an editor, one may use a
.Pa fooprog.gdb
file containing whatever GDB commands are necessary, e.g.
.Dl shell make fooprog
.Dl file ./fooprog
.Dl set args some args to fooprog
.Dl break somecall
.Dl commands
.Dl silent
.Dl watch somevarinsomecall
.Dl continue
.Dl end
.Dl run
and then set your editor to feed this to
.Nm .
.Xr vim 1
mapping might look something like:
.Dl map <Leader>t :!feed % gdb -q<CR><CR>
assisted the design and debugging of the ZSH completion script for
.Nm ;
given a
.Pa vi
buffer containing
.Dl rm ~/.zcompdump
.Dl fpath=(~/co/zsh/compdef $fpath)
.Dl autoload -U compinit && compinit
.Dl # fake completion on ls as want to see if complete its arguments
.Dl zstyle ':completion:*:*:feed:*:commands' fake-always ls
.Dl zstyle ':completion:*:*:feed:*:commands' ignored-patterns '*'
.Dl # stdin completion testing
.Dl #print -z 'echo foo | feed '
.Dl print -z 'feed '
one can then feed a test shell invocation with these commands via
.Dl Ic :!feed % zsh -f
and then try out the tab completion (edited elsewhere) until it works. The
.Ar -f
.Pa zsh
prevents anything in the regular shell configuration from interfering
with the task at hand. Note that undesirable environment variables may
still be passed through from the parent process.
Functions may be difficult to pass through
as these span multiple lines during which
may waste time waiting for a prompt to appear that will not appear. One
workaround is to define any necessary functions in a separate file and
then to include that file in the commands passed to the REPL. Using R,
one could define a
.Pa libfoo
file containing
.Dl examplefn = function()
.Dl {
.Dl \& \& print("asdf")
.Dl }
and then in the file that is passed through
.Pa libfoo
along with any other necessary commands:
.Dl source("libfoo")
.Dl examplefn()
.Dl ...
An even easier workaround is to lower the
.Dv timeout
.Pa ~/.feedrc
wastes less time waiting:
.Dl } elseif {$tocall eq \&"sbcl\&"} {
.Dl \& \& \& \& expect -ex {* }
.Dl \& \& \& \& set timeout .05
.Dl \& \& \& \& proc dosomethingwith {line} {
.Dl \& \& \& \& \& \& \& \& ...
.Xr expect 1 ,
.Xr regexp n ,
.Xr vim 1 ,
.Xr zcomppoke 1
.An Jeremy Mates
The history may need to be disabled for the REPL because repeated
runs may spam the history for the REPL with repeated entries.