home *** CD-ROM | disk | FTP | other *** search
-
- Subject: franz to vi & back
-
- > We have a heavily loaded vax on which we run our Lisp classes. It
- > seems to me that we could lessen the load by not having VI start
- > up anew every time the student does a VIL in Franz.
- >
- > It would be nice to have two processes, one Lisp and the other VI.
- > There would be a function (like VIL) in Franz that would start up
- > a VI process if there wasn't one and if there was a VI process just
- > goto it. When the student is finished editing the file he/she would
- > hit a key that would save out the file and return to Lisp (without
- > killing the VI process). I believe that Gosling Emacs had something
- > like this, only more sophisticated.
- >
- > My questions. Has anyone done this for Franz & VI? Would this help
- > the load average on a VAX? If no one has done it, would it be difficult
- > to do?
- >
-
- I have developed something similar to what you describe, for franz
- running under bsd4.2
-
- It was moderately difficult at the time, but I was just learning to
- exploit job control.
-
- in this system, the user invokes:
- (vif foo)
- to edit the function foo.
-
- when he is finished editing, he saves the current buffer by:
- :w
- then exits the editor by pressing:
- ^Z [NOT wq!!]
-
- (getting users o use ^Z rather than wq is the biggest difficulty)
-
- the function is the read from a temporary file which is created
- by vif.
-
- if the user later wishes to modify the SAME function [often the case]
- he simply invokes:
- (vif)
- - and is returned to the [stopped] editing session EXACTLY where
- he left it.
- [ providing some motivation for putting up with ^Z ]
-
-
- The system people around here aren't too adventurous, so the only people
- who use this system are my friends and myself, so I can't say what effect
- it has on the load, [but it can only help]
-
- one problem: files in /tmp may accumulate, as there is no way to force
- a user to clean up all editing sessions before exiting lisp.
- [but that is what /tmp is for!] you might warn your system people
- to remove all VIF files that are over 2days old, or something like that.
-
-
- note: this package knows about changes made by [cmu]edit, and may
- be simplified if you are using a system where cmuedit is unavailable.
-
-
- NOTE!!!!!!
- Neither the University of Delaware
- nor Apperson H. Johnson
- relinquishes any rightts toi this software.
-
- Please do NOT transfer the software without written permission
- from both The University of Delaware and Apperson H. Johnson.
-
-
- **********************************************************
- setting up the system:
-
- Script started on Fri Mar 1 06:49:30 1985
- % make jced
- cc -c jced.c
- cc -c eroar.c
- ld -o jcedmod.o -r jced.o eroar.o
- % lisp
- Franz Lisp, Opus 38.79
- -> [load 'vif]
- [load vif.l]
- /usr/lib/lisp/nld -N -x -A /usr/ucb/lisp -T 95800 jcedmod.o -e _jced_ -o /tmp/Li8788.0 -lc
- t
- -> [dumplisp newlisp]
- nil
- -> (exit)
- script done on Fri Mar 1 06:51:45 1985
- *******************************************************************
-
- "newlisp" is now the lisp to use - you can put it in some directory
- in youtr student's path
- ---------- here is vif.l --------------------------------
- (setq sccid "#(@)vif.l V1.1 johnson@udel 10/13/84")
- (eval-when (compile)
- (msg "vif doen't work compiled!!!\\ "N) (exit))
- (declare (localf sccid))
- ;
- ; uses job-control to allow ^Z from 'vi' to return to inside of
- ; Lisp function
- ;
-
-
- ; ::vif::
- ;
- ; Usage: (vif [<function-name>])
- ; returns: t if function is loaded without errors, nil otherwise
- ; side-effect: starts vi with temporary file,
- ;
- ; does NOT REMOVE FILE UNLESS SUCCESSFUL LOAD HAS BEEN MADE
- ; AND user has "quit" the editor
- ;
- ; - allows ~instantaneous return to file being edited if
- ; vi has been exited by ^Z (or whatever the susp character is, [see stty.1])
- ;
- ; NOTE: file and vi session may stay "LIVE" even between invocations!!!
- ; eg:
- ;
- ; (def jnk '(lambda (x) "i am jnk"))
- ;
- ; (vif jnk)
- ; --> vi session, followed by :w, and then ^Z
- ; t
- ; followed by :
- ; (vif jnk )
- ; or:
- ; (vif)
- ; --> INSTANTLY returns to former vi session !!
- ;
- ;
- ;
- (declare (special *jced_lastf* *jced_lastc* %changes))
-
- (def vif
- (nlambda (fn)
- (prog (res tf er ppflag)
- (cond
- (fn
- (cond
- ((or (not (boundp '*jced_lastf*))
- (neq *jced_lastf* (car fn)))
- (setq ppflag t)
- (setq *jced_lastf* (car fn))))))
- (cond ((boundp '*jced_lastf*)
- (setq tf
- (substring (concat '/tmp/VF
- (concat (syscall 20)
- (concat '_
- *jced_lastf*)))
- 1))
- (cond
- ((and (boundp '%changes)
- (memq *jced_lastf* %changes)
- (or (not (boundp '*jced_lastc*))
- (neq *jced_lastc* (memq *jced_lastf* %changes))))
- (setq ppflag t)))
- (cond
- (ppflag
- (eval (list 'pp (list 'F tf) *jced_lastf*)))))
- (t (msg "vif: edit what ??" N) (return nil)))
- lp (setq res (jced_ tf ""))
- (setq er nil)
- (setq ER%all '(lambda (x)
- (setq er t))
- )
- (cond
- ((not (probef tf))
- (msg "vif: cannot find " tf)
- (cond
- ((eq res 1)
- (msg " want to return to the editor? {y/n} ")
- (cond ((eq (read) 'y) (go lp)))
- (return nil)))
- (msg " sorry." N)
- (makunbound '*jced_lastf*)
- (return t)))
- (errset (load tf))
- (cond
- ((boundp '%changes)
- (setq *jced_lastc* (memq *jced_lastf* %changes))))
- (cond
- (er (msg "vif: want to fix " *jced_lastf* "? {y/n} ")
- (cond ((eq (read) 'y) (go lp)))))
- (cond ((eq res 0)
- (makunbound '*jced_lastf*)
- (syscall 10 tf)
- (return t))
- (t (return nil))))))
-
-
- ;
- ; include modules written in C
- (cfasl 'jcedmod.o '_jced_ 'jced_ "integer-function")
-
- ; initialization string for jced
- (jced_ ":se lisp
- " "edinit")
-
- ; editor to use
- (jced_ "/usr/ucb/vi" "editor")
-
- --------------- ------- jced.c ---------------
- static char sccid[] = "@(#)jced.c 1.1 johnson@udel 11/2/84";
-
- #include <signal.h>
- #include <sgtty.h>
- #include <errno.h>
- #include <sys/wait.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/file.h>
- #include <stdio.h>
-
- #define streq(s1,s2) (0 == strcmp(s1,s2))
- #define file_exist(FN) (0 == access(FN,F_OK))
- static int chpgrp, pgrp;
- static union wait status;
- static struct stat st0,st1;
- static struct sigvec sv1 = { SIG_IGN, 0, 0};
- static struct sigvec sv0;
-
- static char curname[128];
- static char ed_buf[] = "/usr/ucb/vi";
- static char init_buf[] = "";
- static char myname_buf[] = "jced_";
- static char *editor = ed_buf;
- static char *edinit = init_buf;
- static char *myname = myname_buf;
-
- /* ::jced_::
- *
- * Usage: (jced_ "filename" "")
- *
- * jced_ is a job-control editor
- *
- * - starts an editor session with "filename"
- * (or resumes it if there is a 'living' session with that file)
- * - returns 1 if the session remains alive, 0 if the session is over
- *
- * NOTE: if the SECOND argument is not the EMPTY string,
- * then the following special calls may apply:
- *
- * (jced_ "/usr/ucb/vi" "editor")
- * - causes jced to use /usr/ucb/vi as the editor (this is the default)
- *
- * : (jced_ ":se bla" "edinit")
- * - causes jced cause the editor to pretend that the user typed ":se bla"
- * every time the editor is invoked (the default is "")
- *
- * : (jced_ "jced_" "myname")
- * - causes jced to use the name "jced_" in its prompts and messages
- * (this is the default)
- *
- */
- int
- jced_(fname,cmd)
- char *fname, *cmd;
- {
- union wait status;
- char resp[2];
-
-
- if (*cmd) {
- if (streq(cmd,"editor")) newstring(&editor,fname);
- else if (streq(cmd,"edinit")) newstring(&edinit,fname);
- else if (streq(cmd,"myname")) newstring(&myname,fname);
- else fprintf(stderr,"%s: %s is an unknown command",myname,cmd);
- return(0);
- }
-
- if (*curname) {
- if (*fname && !streq(fname,curname)) {
- if (file_exist(curname))
- eroar(unlink(curname),0,"unlink %",curname);
- kvil_();
- strcpy(curname,fname);
- begin_vi(); resume_vi();
- } else {
- /*
- * if file has been modified elsewhere,
- * new editing session is needed
- */
- if (file_exist(curname)) {
- eroar(stat(curname,&st1),0,"stat");
- if(st0.st_mtime != st1.st_mtime) {
- kvil_(); strcpy(curname,fname); begin_vi();
- }
- }
- resume_vi();
- }
- } else if (*fname) {
- strcpy(curname,fname);
- begin_vi(); resume_vi();
- } else
- return(0);
-
- return((*curname) ? 1 : 0);
- }
-
- /* to be called when a function is modified elsewhwre */
- kvil_()
- {
- eroar(killpg(chpgrp,SIGKILL),0,"killpg %d",chpgrp);
- wait3(&status,WUNTRACED,0);
- curname[0] = '\0';
- }
-
- static
- begin_vi()
- {
- if (chpgrp = fork()) {
- pgrp = getpgrp(0);
- eroar(setpgrp(chpgrp,chpgrp),0,"setpgrp");
- } else {
- fakeinput(edinit);
- execlp(editor,editor,curname,0);
- fprintf(stderr,"%s: exec of %s failed\n",myname,editor);
- }
- }
-
-
- static
- resume_vi()
- {
- char dum[2];
-
- for (;;) {
- eroar(sigvec(SIGTTOU,&sv1,&sv0),0,"sigvec -IGN TTOU");
- eroar(ioctl(0,TIOCSPGRP,&chpgrp),0,"SPGRP chpgrp");
- if (file_exist(curname))
- eroar(stat(curname,&st1),0,"stat");
- else
- st1.st_mtime = 0;
- killpg(chpgrp,SIGCONT);
- wait3(&status,WUNTRACED,0);
- eroar(ioctl(0,TIOCSPGRP,&pgrp),0,"ioctl SPGRP pid");
- eroar(sigvec(SIGTTOU,&sv0,0),0,"sigvec -DFL TTOU");
- if (file_exist(curname))
- eroar(stat(curname,&st0),0,"stat");
- else
- st0.st_mtime = st1.st_mtime;
-
- if(!status.w_status) {
- curname[0] = '\0'; break;
- }
- if(st0.st_mtime == st1.st_mtime) {
- fprintf(stderr,"%s: %s was not modified, try again? {y/n} ",
- myname, curname);
- if (1 == scanf("%1s",dum) && dum[0] == 'n') break;
- } else
- break;
- }
- }
-
- static
- fakeinput(s)
- char *s;
- {
- int i;
- /* pretend s was typed at the terminal */
- for(i=0;s[i]; ++i)
- ioctl(0,TIOCSTI,s+i);
- }
-
- static
- newstring(sptr,s)
- char **sptr, *s;
- {
- char *s2, *malloc();
-
- if (NULL == (s2 = malloc(1 + strlen(s)))) {
- fprintf(stderr,"%s: malloc failed\n",myname);
- } else {
- strcpy(s2,s);
- *sptr = s2;
- }
- }
-
- --------------------------- eroar.c --------------------
-
- static char sccid[] = "@(#)eroar.c 1.0 johnson@udel 10/13/84";
-
- /* ::eroar.c::
- *
- * error reporter-handler for faulty system function calls
- *
- * Usage: eroar( <system-call>, <exit-code>, <printf-pattern>,
- * <printf-arg>, <printf-arg>, ...... );
- *
- * behavior:
- * if the system call is successful, returns (1) immediately
- * else
- * prints out the error message (from the printf pattern)
- * and prints an error explanation
- * if exit-code is non-zero, exits with that code
- * else returns (0)
- */
-
-
- #include <errno.h>
- #include <stdio.h>
- #define ERR_BUFMAX 128
-
- extern int sys_nerr, errno;
- extern char *sys_errlist[];
-
- eroar(expr,code,s,p1,p2,p3,p4,p5,p6,p7,p8,p9)
- int expr,code; char *s;
- {
- static char errbuf[ERR_BUFMAX];
- if (-1 != expr) return(1);
- fprintf(stderr,s,p1,p2,p3,p4,p5,p6,p7,p8,p9);
- fprintf(stderr,": %s\n",
- (0 < errno && errno < sys_nerr) ?
- sys_errlist[errno] : "UNKNOWN ERROR");
- if (code) exit(code);
- return(0);
- }
-
- ----------------- makefile -----------------------
-
- jced : jcedmod.o
-
- jcedmod.o : jced.o eroar.o
- ld -o jcedmod.o -r jced.o eroar.o
- -------------------------------------------------------
-
- ... (share a little joke with the world) ...
-
- net: johnson@udel-ee
- usmail: Apperson H. Johnson
- 618 Lehigh Rd. apt S11
- Newark, De. 19711
- --------------------------------------------------------
-
-