home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / lisp / lispnews / text0323.txt < prev    next >
Encoding:
Text File  |  1985-11-10  |  11.6 KB  |  437 lines

  1.  
  2. Subject: franz to vi & back
  3.  
  4. > We have a heavily loaded vax on which we run our Lisp classes.  It
  5. > seems to me that we could lessen the load by not having VI start
  6. > up anew every time the student does a VIL in Franz.  
  7. > It would be nice to have two processes, one Lisp and the other VI.
  8. > There would be a function (like VIL) in Franz that would start up
  9. > a VI process if there wasn't one and if there was a VI process just
  10. > goto it.  When the student is finished editing the file he/she would
  11. > hit a key that would save out the file and return to Lisp (without
  12. > killing the VI process).  I believe that Gosling Emacs had something
  13. > like this, only more sophisticated.
  14. > My questions.  Has anyone done this for Franz & VI?  Would this help
  15. > the load average on a VAX?  If no one has done it, would it be difficult
  16. > to do?
  17.  
  18. I have developed something similar to what you describe, for franz
  19. running under bsd4.2
  20.  
  21. It was moderately difficult at the time, but I was just learning to
  22. exploit job control.
  23.  
  24. in this system, the user invokes: 
  25. (vif  foo)
  26. to edit the function foo.
  27.  
  28. when he is finished editing, he saves the current buffer by:
  29. :w
  30. then exits the editor by pressing:
  31. ^Z  [NOT wq!!]
  32.  
  33. (getting users o use ^Z rather than wq is the biggest difficulty)
  34.  
  35. the function is the read from a temporary file which is created
  36. by vif.
  37.  
  38. if the user later wishes to modify the SAME function [often the case]
  39. he simply invokes:
  40. (vif)
  41. - and is returned to the [stopped] editing session EXACTLY where
  42. he left it.  
  43. [ providing some motivation for putting up with ^Z ]
  44.  
  45.  
  46. The system people around here aren't too adventurous, so the only people
  47. who use this system are my friends and myself, so I can't say what effect
  48. it has on the load, [but it can only help]
  49.  
  50. one problem:  files in /tmp may accumulate, as there is no way to force
  51. a user to clean up all editing sessions before exiting lisp.
  52. [but that is what /tmp is for!]  you might warn your system people
  53. to remove all VIF files that are over 2days old, or something like that.
  54.  
  55.  
  56. note: this package knows about changes made by [cmu]edit, and may
  57. be simplified if you are using a system where cmuedit is unavailable.
  58.  
  59.  
  60. NOTE!!!!!!
  61. Neither the University of Delaware
  62. nor Apperson H. Johnson
  63. relinquishes any rightts toi this software.
  64.  
  65. Please do NOT transfer the software without written permission
  66. from both The University of Delaware and Apperson H. Johnson.
  67.  
  68.  
  69. **********************************************************
  70. setting up the system:
  71.  
  72. Script started on Fri Mar  1 06:49:30 1985
  73. % make jced
  74. cc  -c jced.c
  75. cc  -c eroar.c
  76. ld -o jcedmod.o -r  jced.o eroar.o
  77. % lisp
  78. Franz Lisp, Opus 38.79
  79. -> [load 'vif]
  80. [load vif.l]
  81. /usr/lib/lisp/nld -N -x -A /usr/ucb/lisp -T 95800 jcedmod.o -e _jced_ -o /tmp/Li8788.0  -lc
  82. t
  83. -> [dumplisp newlisp]
  84. nil
  85. -> (exit)
  86. script done on Fri Mar  1 06:51:45 1985
  87. *******************************************************************
  88.  
  89. "newlisp" is now the lisp to use - you can put it in some directory
  90. in youtr student's path
  91. ----------  here is vif.l  --------------------------------
  92. (setq sccid "#(@)vif.l    V1.1    johnson@udel    10/13/84")
  93. (eval-when (compile)
  94.     (msg "vif doen't work compiled!!!\\ "N) (exit))
  95. (declare (localf sccid))
  96. ;
  97. ;  uses job-control to allow ^Z from 'vi' to return to inside of
  98. ;  Lisp function
  99. ;
  100.  
  101.  
  102. ; ::vif::
  103. ;
  104. ;  Usage: (vif [<function-name>])
  105. ;  returns: t if function is loaded without errors, nil otherwise
  106. ;  side-effect: starts vi with temporary file,
  107. ;
  108. ;  does NOT REMOVE FILE UNLESS SUCCESSFUL LOAD HAS BEEN MADE
  109. ;  AND user has "quit" the editor
  110. ;
  111. ;  - allows ~instantaneous return to file being edited if
  112. ;    vi has been exited by ^Z (or whatever the susp character is, [see stty.1])
  113. ;   
  114. ;  NOTE: file and vi session may stay "LIVE" even between invocations!!!
  115. ; eg:
  116. ;
  117. ;  (def jnk '(lambda (x) "i am jnk"))
  118. ;
  119. ;  (vif jnk)
  120. ;    --> vi session, followed by :w, and then ^Z
  121. ;  t
  122. ;  followed by  :
  123. ;     (vif jnk ) 
  124. ;  or:
  125. ;     (vif)
  126. ;   --> INSTANTLY returns to former vi session !!
  127. ;
  128. ;
  129. ;
  130. (declare (special *jced_lastf* *jced_lastc*  %changes))
  131.  
  132. (def vif
  133.   (nlambda (fn)
  134.     (prog (res tf er ppflag)
  135.           (cond
  136.            (fn
  137.             (cond
  138.              ((or (not (boundp '*jced_lastf*))
  139.                   (neq *jced_lastf* (car fn)))
  140.               (setq ppflag t)
  141.               (setq *jced_lastf* (car fn))))))
  142.           (cond ((boundp '*jced_lastf*)
  143.                  (setq tf
  144.                        (substring (concat '/tmp/VF
  145.                                           (concat (syscall 20)
  146.                                                   (concat '_
  147.                                                           *jced_lastf*)))
  148.                                   1))
  149.                  (cond
  150.                   ((and (boundp '%changes)
  151.                         (memq *jced_lastf* %changes)
  152.                         (or (not (boundp '*jced_lastc*))
  153.                             (neq *jced_lastc* (memq *jced_lastf* %changes))))
  154.                    (setq ppflag t)))
  155.                  (cond
  156.                   (ppflag
  157.                    (eval (list 'pp (list 'F tf) *jced_lastf*)))))
  158.                 (t (msg "vif: edit what ??" N) (return nil)))
  159.      lp   (setq res (jced_ tf ""))
  160.           (setq er nil)
  161.           (setq ER%all '(lambda (x)
  162.                                 (setq er t))
  163.                         )
  164.           (cond
  165.            ((not (probef tf))
  166.             (msg "vif: cannot find " tf)
  167.             (cond
  168.              ((eq res 1)
  169.               (msg " want to return to the editor? {y/n} ")
  170.               (cond ((eq (read) 'y) (go lp)))
  171.               (return nil)))
  172.             (msg " sorry." N)
  173.             (makunbound '*jced_lastf*)
  174.             (return t)))
  175.           (errset (load tf))
  176.           (cond
  177.            ((boundp '%changes)
  178.             (setq *jced_lastc* (memq *jced_lastf* %changes))))
  179.           (cond
  180.            (er (msg "vif: want to fix " *jced_lastf* "? {y/n} ")
  181.                (cond ((eq (read) 'y) (go lp)))))
  182.           (cond ((eq res 0)
  183.                  (makunbound '*jced_lastf*)
  184.                  (syscall 10 tf)
  185.                  (return t))
  186.                 (t (return nil))))))
  187.  
  188.  
  189. ;
  190. ; include modules written in C
  191. (cfasl 'jcedmod.o '_jced_ 'jced_ "integer-function")
  192.  
  193. ;  initialization string for jced
  194. (jced_ ":se lisp
  195. " "edinit")
  196.  
  197. ;  editor to use
  198. (jced_ "/usr/ucb/vi" "editor")
  199.  
  200. --------------- -------     jced.c             ---------------
  201. static char sccid[] = "@(#)jced.c    1.1    johnson@udel 11/2/84";
  202.  
  203. #include  <signal.h>
  204. #include  <sgtty.h>
  205. #include  <errno.h>
  206. #include  <sys/wait.h>
  207. #include  <sys/types.h>
  208. #include  <sys/stat.h>
  209. #include  <sys/file.h>
  210. #include  <stdio.h>
  211.  
  212. #define streq(s1,s2)    (0 == strcmp(s1,s2))
  213. #define file_exist(FN)  (0 == access(FN,F_OK))
  214. static int chpgrp, pgrp;   
  215. static union wait status;
  216. static struct stat st0,st1;
  217. static struct sigvec sv1 = { SIG_IGN, 0, 0};
  218. static struct sigvec sv0;
  219.  
  220. static char curname[128];
  221. static char ed_buf[] = "/usr/ucb/vi";
  222. static char init_buf[] = "";
  223. static char myname_buf[] = "jced_";
  224. static char *editor = ed_buf;
  225. static char *edinit = init_buf;
  226. static char *myname = myname_buf;
  227.  
  228. /*    ::jced_::
  229.  *    
  230.  *    Usage: (jced_ "filename" "")
  231.  *    
  232.  *            jced_ is a job-control editor
  233.  *
  234.  *    - starts an editor session with "filename"
  235.  *      (or resumes it if there is a 'living' session with that file)
  236.  *    - returns 1 if the session remains alive, 0 if the session is over
  237.  *    
  238.  *     NOTE: if the SECOND argument is not the EMPTY string, 
  239.  *    then the following special calls may apply:
  240.  *    
  241.  *         (jced_ "/usr/ucb/vi" "editor") 
  242.  *    - causes jced to use /usr/ucb/vi as the editor (this is the default)
  243.  *    
  244.  *        : (jced_ ":se bla" "edinit") 
  245.  *    - causes jced cause the editor to pretend that the user typed ":se bla"
  246.  *    every time the editor is invoked (the default is "")
  247.  *
  248.  *        : (jced_ "jced_" "myname") 
  249.  *    - causes jced to use the name "jced_" in its prompts and messages
  250.  *    (this is the default)
  251.  *
  252.  */
  253. int
  254. jced_(fname,cmd)
  255. char *fname, *cmd;
  256. {
  257. union wait  status;
  258. char resp[2];
  259.  
  260.  
  261.     if (*cmd) {
  262.         if (streq(cmd,"editor")) newstring(&editor,fname);
  263.         else if (streq(cmd,"edinit")) newstring(&edinit,fname);
  264.         else if (streq(cmd,"myname")) newstring(&myname,fname);
  265.         else fprintf(stderr,"%s: %s is an unknown command",myname,cmd);
  266.         return(0);
  267.     }
  268.  
  269.     if (*curname) {
  270.         if (*fname &&  !streq(fname,curname)) {
  271.                 if (file_exist(curname))
  272.                     eroar(unlink(curname),0,"unlink %",curname);
  273.                 kvil_();
  274.                 strcpy(curname,fname);
  275.                 begin_vi(); resume_vi();
  276.         } else {
  277.              /*
  278.              * if file has been modified elsewhere,
  279.              * new editing session is needed
  280.              */ 
  281.             if (file_exist(curname)) { 
  282.                 eroar(stat(curname,&st1),0,"stat");
  283.                 if(st0.st_mtime != st1.st_mtime) {
  284.                     kvil_(); strcpy(curname,fname); begin_vi();
  285.                 }
  286.             }
  287.             resume_vi();
  288.         }
  289.     } else if (*fname) {
  290.             strcpy(curname,fname);
  291.             begin_vi(); resume_vi();
  292.     } else
  293.         return(0);
  294.         
  295.     return((*curname) ? 1 : 0);
  296. }
  297.  
  298. /*  to be called when a function is modified elsewhwre */
  299. kvil_()
  300. {
  301.     eroar(killpg(chpgrp,SIGKILL),0,"killpg %d",chpgrp);
  302.     wait3(&status,WUNTRACED,0);
  303.     curname[0] = '\0';
  304. }
  305.  
  306. static
  307. begin_vi()
  308. {
  309.     if (chpgrp = fork()) {
  310.         pgrp = getpgrp(0);
  311.         eroar(setpgrp(chpgrp,chpgrp),0,"setpgrp");
  312.     } else {
  313.         fakeinput(edinit);
  314.         execlp(editor,editor,curname,0);
  315.         fprintf(stderr,"%s: exec of %s failed\n",myname,editor);
  316.     }
  317. }
  318.  
  319.  
  320. static
  321. resume_vi()
  322. {
  323. char dum[2];
  324.  
  325.     for (;;) {
  326.         eroar(sigvec(SIGTTOU,&sv1,&sv0),0,"sigvec -IGN TTOU");
  327.         eroar(ioctl(0,TIOCSPGRP,&chpgrp),0,"SPGRP chpgrp");
  328.         if (file_exist(curname))
  329.             eroar(stat(curname,&st1),0,"stat");
  330.         else
  331.             st1.st_mtime = 0;
  332.         killpg(chpgrp,SIGCONT);
  333.         wait3(&status,WUNTRACED,0);
  334.         eroar(ioctl(0,TIOCSPGRP,&pgrp),0,"ioctl SPGRP pid");
  335.         eroar(sigvec(SIGTTOU,&sv0,0),0,"sigvec -DFL TTOU");
  336.         if (file_exist(curname))
  337.             eroar(stat(curname,&st0),0,"stat");
  338.         else
  339.             st0.st_mtime = st1.st_mtime;
  340.  
  341.         if(!status.w_status) {
  342.              curname[0] = '\0'; break;
  343.         }
  344.         if(st0.st_mtime == st1.st_mtime) {
  345.             fprintf(stderr,"%s: %s was not modified, try again? {y/n} ",
  346.                 myname, curname);
  347.             if (1 == scanf("%1s",dum) && dum[0] == 'n')  break;
  348.         } else 
  349.             break;
  350.     }
  351. }
  352.  
  353. static
  354. fakeinput(s)
  355. char *s;
  356. {
  357. int i;
  358.     /* pretend s was typed at the terminal */
  359.     for(i=0;s[i]; ++i)
  360.         ioctl(0,TIOCSTI,s+i);
  361. }
  362.  
  363. static
  364. newstring(sptr,s)
  365. char **sptr, *s;
  366. {
  367. char *s2, *malloc();
  368.  
  369.     if (NULL == (s2 = malloc(1 + strlen(s)))) {
  370.         fprintf(stderr,"%s: malloc failed\n",myname);
  371.     } else {
  372.         strcpy(s2,s);
  373.         *sptr = s2;
  374.     }
  375. }
  376.  
  377. ---------------------------  eroar.c  --------------------
  378.  
  379. static char sccid[] = "@(#)eroar.c    1.0    johnson@udel 10/13/84";
  380.  
  381. /*    ::eroar.c::
  382.  *    
  383.  *    error reporter-handler for faulty system function calls
  384.  *    
  385.  *    Usage: eroar( <system-call>, <exit-code>, <printf-pattern>, 
  386.  *                        <printf-arg>, <printf-arg>,  ...... );
  387.  *    
  388.  *    behavior:
  389.  *        if the system call is successful, returns (1) immediately
  390.  *        else
  391.  *            prints out the error message (from the printf pattern)
  392.  *              and prints an error explanation
  393.  *             if exit-code is non-zero, exits with that code
  394.  *            else returns (0)
  395.  */
  396.  
  397.  
  398. #include <errno.h>
  399. #include <stdio.h>
  400. #define ERR_BUFMAX 128
  401.  
  402. extern int sys_nerr, errno;
  403. extern char *sys_errlist[];
  404.  
  405. eroar(expr,code,s,p1,p2,p3,p4,p5,p6,p7,p8,p9)
  406. int expr,code; char *s;
  407. {
  408.     static char errbuf[ERR_BUFMAX];
  409.     if (-1 != expr) return(1);
  410.     fprintf(stderr,s,p1,p2,p3,p4,p5,p6,p7,p8,p9);
  411.     fprintf(stderr,": %s\n",
  412.         (0 < errno && errno < sys_nerr) ?
  413.                 sys_errlist[errno] : "UNKNOWN ERROR");
  414.     if (code) exit(code);
  415.     return(0);
  416. }
  417.  
  418. -----------------    makefile -----------------------
  419.  
  420. jced : jcedmod.o
  421.  
  422. jcedmod.o : jced.o eroar.o
  423.     ld -o jcedmod.o -r  jced.o eroar.o
  424. -------------------------------------------------------
  425.  
  426. ... (share a little joke with the world) ...
  427.  
  428. net:        johnson@udel-ee
  429. usmail:     Apperson H. Johnson
  430.             618 Lehigh Rd. apt S11
  431.             Newark, De. 19711
  432. --------------------------------------------------------
  433.  
  434.