From: CSBVAX::MRGATE!info-vax-relay@KL.SRI.COM@SMTP 15-MAY-1988 17:20 To: ARISIA::EVERHART Subj: GNU Emacs 18.50 changes and additions for VMS (long -- 27K) Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Tue 19 Apr 88 18:31:40-PDT Received: by ucbvax.Berkeley.EDU (5.59/1.28) id AA09423; Tue, 19 Apr 88 01:34:20 PDT Received: from USENET by ucbvax.Berkeley.EDU with netnews for info-vax@kl.sri.com (info-vax@kl.sri.com) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 19 Apr 88 05:46:14 GMT From: ut-emx!mic@sally.utexas.edu (Mic (... K[a-z]+) Kaczmarczik) Organization: UT Austin Computation Center, User Services Unix Support Group Subject: GNU Emacs 18.50 changes and additions for VMS (long -- 27K) Message-Id: <1762@ut-emx.UUCP> Sender: info-vax-request@kl.sri.com To: info-vax@kl.sri.com [Type 'n' if you don't run GNU Emacs under VMS] These are the source code changes I made in the process of installing GNU Emacs 18.50 on the Instructional VMS systems here at UT. The starred changes were necessary to get it to work correctly (or compile at all), the rest are hacks we've come to like at our site. A shell archive with the changes is at the end of this posting. The enhanced kept editor support (particularly the attach-to-parent command) makes for a lot fewer Emacs image activations, and make Emacs a more comfortable editing environment under VMS. I'm sending these changes to the FSF, but since they probably aren't tracking VMS mods too closely (I don't blame them, really, there's a lot of other things to do), I'm posting this in the hope that someone else will benefit from it. Cheers, Mic Kaczmarczik If you drink, don't drill. UT Austin Computation Center -- Matt Groening mic@emx.utexas.edu MIC@UTAIVC.BITNET ....!ut-sally!ut-emx!mic ---------------------------------------------------------------------------- Changes to GNU Emacs 18.50 for VMS 4.7 -- Mic Kaczmarczik 17-Apr-1988 * src/dired.c (VMS code in file_name_completion) Change call to readfunc() in VMS code to (*readfunc)(), since readfunc is a pointer to a function. * src/fileio.c (VMS code in Fwrite_region) Attempting to save a file whose name starts starts with '.' (like ".emacs") results in retaining the RMS file name field from the temporary file, so you end up with files like "$$$$SAVE$$$.EMACS". I punted and just check to see if the file name starts with a '.'. * src/sysdep.c (VMS include files) #include is superfluous (it's included by rms.h earlier on). * src/sysdep.c (VMS sys_access()) The VAX C 2.3 access() function doesn't like directory specs. Convert the spec to a VMS file name using directory_file_name(). More overhead, sigh... src/sysdep.c (VMS sys_getenv() function) We have taught our users to define one logical name, "TERM", to specify their terminal type for four editors: vi (under Eunice), CCA Emacs, GNU Emacs and MG. If EMACS_TERM doesn't translate to a string, sys_getenv() translates the logical name "TERM" before using VAX C's getenv(). src/vmspaths.h (VMS-specific path for termcap database) Add #define PATH_TERMCAP for those sites that already have a termcap file in a well-known place. Our site has Eunice, so we don't want to maintain two termcaps. src/termcap.c (VMS-specific default path for termcap database) Supply default PATH_TERMCAP (EMACS_LIBRARY:[ETC]TERMCAP.DAT) if none supplied by vmspaths.h. src/vmsfns.c (new VMS-specific functions) "attach" attaches to the specified process name, if possible. Supports before- and after- hooks, which are used to enhance the kept editor support in kepteditor.com. "push-to-dcl" spawns a vanilla DCL subprocess (not a SHELL buffer). Also supports before- and after- hooks (push-to-dcl{,resume}-hook). kepteditor.com A beefed up version of KEPTEDITOR.COM that defines job-wide logicals: EMACS_NEWDIRECTORY -- current directory EMACS_NEWFILE -- name of a new file to edit EMACS_ATTACHTO -- process to attach to when suspending next time The hooks in kepteditor.el use these to do the "right thing", although they could use some polishing. lisp/kepteditor.el GNU LISP support for kept editing. Rebinds C-z to "attach-to-parent", which either attaches to the process specified by EMACS_ATTACHTO or the parent, if possible. The suspend-hook provided by kepteditor.el knows the format of VMS MAIL temporary scratch files, and clears out the current buffer if the visited file name matches its template. This assures that you get a new buffer the next time you visit SYS$SCRATCH:MAIL_xxx.TMP, which used to be a continual source of annoyance. gnu_mailedit.com A copy of SYS$SYSTEM:MAILEDIT.COM that purges extra MAIL_xxx.TMP files and knows about the EMACS_ATTACHTO logical name. ---------------------------------------------------------------------- # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. -----cut here-----cut here-----cut here-----cut here----- #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # dired.diff # fileio.diff # sysdep.diff # termcap.diff # vmsfns.diff # vmspaths.diff # kepteditor.com # kepteditor.el # gnu_mailedit.com # This archive created: Mon Apr 18 23:33:58 1988 sed 's/^X//' << \SHAR_EOF > dired.diff X*** src/dired.c.orig Mon Apr 18 20:16:25 1988 X--- src/dired.c Mon Apr 18 20:33:35 1988 X*************** X*** 220,226 X int len; X X #ifdef VMS X! dp = readfunc (d); X #else X dp = readdir (d); X #endif X X--- 220,226 ----- X int len; X X #ifdef VMS X! dp = (*readfunc) (d); X #else X dp = readdir (d); X #endif SHAR_EOF sed 's/^X//' << \SHAR_EOF > fileio.diff X*** fileio.c.orig Mon Apr 18 21:47:45 1988 X--- fileio.c Mon Apr 18 21:47:48 1988 X*************** X*** 1590,1595 X } X else /* Write to temporary name and rename if no errors */ X { X Lisp_Object temp_name; X temp_name = Ffile_name_directory (filename); X X X--- 1590,1596 ----- X } X else /* Write to temporary name and rename if no errors */ X { X+ int nullname = 0; X Lisp_Object temp_name; X Lisp_Object temp_file; X X*************** X*** 1591,1596 X else /* Write to temporary name and rename if no errors */ X { X Lisp_Object temp_name; X temp_name = Ffile_name_directory (filename); X X if (!NULL (temp_name)) X X--- 1592,1599 ----- X { X int nullname = 0; X Lisp_Object temp_name; X+ Lisp_Object temp_file; X+ X temp_name = Ffile_name_directory (filename); X temp_file = Ffile_name_nondirectory (filename); X X*************** X*** 1592,1597 X { X Lisp_Object temp_name; X temp_name = Ffile_name_directory (filename); X X if (!NULL (temp_name)) X { X X--- 1595,1601 ----- X Lisp_Object temp_file; X X temp_name = Ffile_name_directory (filename); X+ temp_file = Ffile_name_nondirectory (filename); X X if (!NULL (temp_file)) X nullname = (XSTRING (temp_file)->data[0] == '.'); X*************** X*** 1593,1598 X Lisp_Object temp_name; X temp_name = Ffile_name_directory (filename); X X if (!NULL (temp_name)) X { X temp_name = Fmake_temp_name (concat2 (temp_name, X X--- 1597,1605 ----- X temp_name = Ffile_name_directory (filename); X temp_file = Ffile_name_nondirectory (filename); X X+ if (!NULL (temp_file)) X+ nullname = (XSTRING (temp_file)->data[0] == '.'); X+ X if (!NULL (temp_name)) X { X temp_name = Fmake_temp_name (concat2 (temp_name, X*************** X*** 1596,1602 X if (!NULL (temp_name)) X { X temp_name = Fmake_temp_name (concat2 (temp_name, X! build_string ("$$SAVE$$"))); X fname = XSTRING (filename)->data; X fn = XSTRING (temp_name)->data; X fd = creat_copy_attrs (fname, fn); X X--- 1603,1610 ----- X if (!NULL (temp_name)) X { X temp_name = Fmake_temp_name (concat2 (temp_name, X! build_string (nullname ? ".$$SAVE$$" : "$$SAVE$$"))); X! X fname = XSTRING (filename)->data; X fn = XSTRING (temp_name)->data; X fd = creat_copy_attrs (fname, fn); SHAR_EOF sed 's/^X//' << \SHAR_EOF > sysdep.diff X*** src/sysdep.c.orig Mon Apr 18 20:16:58 1988 X--- src/sysdep.c Mon Apr 18 20:36:01 1988 X*************** X*** 61,67 X #include X #include X #include X- #include X #define MAXIOSIZE ( 32 * PAGESIZE ) /* Don't I/O more than 32 blocks at a time */ X #endif /* VMS */ X X X--- 61,66 ----- X #include X #include X #include X #define MAXIOSIZE ( 32 * PAGESIZE ) /* Don't I/O more than 32 blocks at a time */ X #endif /* VMS */ X X*************** X*** 1678,1684 X #ifdef getenv X /* If any place else asks for the TERM variable, X allow it to be overridden with the EMACS_TERM variable X! before getting VMS's special idea of the TERM variable. */ X #undef getenv X char * X sys_getenv (name) X X--- 1677,1684 ----- X #ifdef getenv X /* If any place else asks for the TERM variable, X allow it to be overridden with the EMACS_TERM variable X! before attempting to translate the logical name TERM. As a last X! resort, ask for VAX C's special idea of the TERM variable. */ X #undef getenv X char * X sys_getenv (name) X*************** X*** 1685,1690 X char *name; X { X register char *val; X X if (!strcmp (name, "TERM")) X { X X--- 1685,1697 ----- X char *name; X { X register char *val; X+ static char buf[256]; X+ static struct dsc$descriptor_s equiv = { X+ sizeof(buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf X+ }, d_name = { X+ 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0 X+ }; X+ short eqlen; X X if (!strcmp (name, "TERM")) X { X*************** X*** 1691,1696 X val = (char *) getenv ("EMACS_TERM"); X if (val) X return val; X } X return (char *) getenv (name); X } X X--- 1698,1711 ----- X val = (char *) getenv ("EMACS_TERM"); X if (val) X return val; X+ X+ d_name.dsc$w_length = strlen (name); X+ d_name.dsc$a_pointer = name; X+ if (lib$sys_trnlog(&d_name, &eqlen, &equiv) & 1) X+ { X+ buf[eqlen] = '\0'; X+ return buf; X+ } X } X return (char *) getenv (name); X } X*************** X*** 2201,2207 X #undef access X X /* The following is necessary because 'access' emulation by VMS C (2.0) does X! * not work correctly. X */ X X #ifdef VMS4_4 X X--- 2216,2222 ----- X #undef access X X /* The following is necessary because 'access' emulation by VMS C (2.0) does X! * not work correctly. Nor does it work well under VAX C 2.3... X */ X X #ifdef VMS4_4 X*************** X*** 2234,2240 X int mode; X { X static char *user = NULL; X! X if (mode == F_OK) X return access (path, mode); X if (user == NULL && (user = getenv("USER")) == NULL) X X--- 2249,2262 ----- X int mode; X { X static char *user = NULL; X! char dir_fn[512]; X! X! /* translate possible directory spec into .DIR file name, so brain-dead X! * access() can treat the directory like a file. X! */ X! if (directory_file_name(path,dir_fn)) X! path = dir_fn; X! X if (mode == F_OK) X return access (path, mode); X if (user == NULL && (user = getenv("USER")) == NULL) X*************** X*** 2236,2242 X static char *user = NULL; X X if (mode == F_OK) X! return access (path, mode); X if (user == NULL && (user = getenv("USER")) == NULL) X return -1; X { X X--- 2258,2264 ----- X path = dir_fn; X X if (mode == F_OK) X! return access (path, mode); X if (user == NULL && (user = getenv("USER")) == NULL) X return -1; X { SHAR_EOF sed 's/^X//' << \SHAR_EOF > termcap.diff X*** src/termcap.c.orig Mon Apr 18 20:17:06 1988 X--- src/termcap.c Mon Apr 18 20:36:06 1988 X*************** X*** 458,463 X X if (!tem) X #ifdef VMS X tem = "emacs_library:[etc]termcap.dat"; X #else X tem = "/etc/termcap"; X X--- 458,464 ----- X X if (!tem) X #ifdef VMS X+ #ifndef PATH_TERMCAP X tem = "emacs_library:[etc]termcap.dat"; X #else X tem = PATH_TERMCAP; X*************** X*** 459,464 X if (!tem) X #ifdef VMS X tem = "emacs_library:[etc]termcap.dat"; X #else X tem = "/etc/termcap"; X #endif X X--- 460,468 ----- X #ifdef VMS X #ifndef PATH_TERMCAP X tem = "emacs_library:[etc]termcap.dat"; X+ #else X+ tem = PATH_TERMCAP; X+ #endif X #else X tem = "/etc/termcap"; X #endif SHAR_EOF sed 's/^X//' << \SHAR_EOF > vmsfns.diff X*** src/vmsfns.c.orig Mon Apr 18 20:17:12 1988 X--- src/vmsfns.c Mon Apr 18 20:36:35 1988 X*************** X*** 18,24 X file named COPYING. Among other things, the copyright notice X and this notice must be preserved on all copies. */ X X! /* Written by Mukesh Prasad. */ X X /* X * INTERFACE PROVIDED BY EMACS FOR VMS SUBPROCESSES: X X--- 18,24 ----- X file named COPYING. Among other things, the copyright notice X and this notice must be preserved on all copies. */ X X! /* Written by Mukesh Prasad. Attach and push-to-dcl by Mic Kaczmarczik */ X X /* X * INTERFACE PROVIDED BY EMACS FOR VMS SUBPROCESSES: X*************** X*** 65,70 X #include X #include X #include X X #define CLI$M_NOWAIT 1 /* clidef.h is missing from C library */ X X X--- 65,71 ----- X #include X #include X #include X+ #include X X #define CLI$M_NOWAIT 1 /* clidef.h is missing from C library */ X X*************** X*** 508,513 X return Qnil; X } X X init_vmsfns () X { X process_list = 0; X X--- 509,614 ----- X return Qnil; X } X X+ X+ DEFUN ("attach", Fattach, Sattach, 1, 1, "sAttach to process named: ", X+ "Stop Emacs and attempt to attach to the process specified by PROCNAME.\n\ X+ If PROCNAME is nil, attempt to attach to the parent of the current process.\n\ X+ Attaching back to the Emacs process resumes Emacs. Before suspending Emacs,\n\ X+ if `attach-hook' is bound and value is non-nil call the value as a function\n\ X+ of no args. Don't suspend if it returns non-nil. Otherwise, suspend\n\ X+ normally and after resumption call `attach-resume-hook' if that is bound\n\ X+ and non-nil.") X+ (procname) X+ Lisp_Object procname; X+ { X+ register Lisp_Object tem; X+ long pid = -1, jpi_code, status; X+ struct dsc$descriptor_s procname_d; X+ X+ if (NULL (procname)) X+ { X+ if ((pid = getppid ()) == 0) X+ error ("Can't attach from top level process to itself"); X+ else if (pid == -1) X+ error ("Can't get parent PID"); X+ } X+ else X+ { X+ CHECK_STRING (procname, 0); X+ X+ jpi_code = JPI$_PID; X+ procname_d.dsc$a_pointer = XSTRING (procname)->data; X+ procname_d.dsc$w_length = strlen ( XSTRING (procname)->data ); X+ procname_d.dsc$b_dtype = DSC$K_DTYPE_T; X+ procname_d.dsc$b_class = DSC$K_CLASS_S; X+ X+ status = LIB$GETJPI (&jpi_code, 0, &procname_d, &pid, 0); X+ if (status != SS$_NORMAL) X+ error ("Process \"%s\" not found", XSTRING (procname)->data); X+ } X+ X+ /* Call value of attach-hook X+ if it is bound and value is non-nil. */ X+ tem = intern ("attach-hook"); X+ tem = XSYMBOL (tem)->value; X+ if (! EQ (tem, Qunbound) && ! EQ (tem, Qnil)) X+ { X+ tem = call0 (tem); X+ if (!EQ (tem, Qnil)) return Qnil; X+ } X+ X+ reset_sys_modes (); X+ status = LIB$ATTACH (&pid); X+ init_sys_modes (); X+ if (status != SS$_NORMAL) X+ error("Attach to process \"%s\" failed", XSTRING (procname)->data); X+ X+ /* Call value of attach-resume-hook X+ if it is bound and value is non-nil. */ X+ tem = intern ("attach-resume-hook"); X+ tem = XSYMBOL (tem)->value; X+ if (! EQ (tem, Qunbound) && ! EQ (tem, Qnil)) X+ call0 (tem); X+ return Qnil; X+ } X+ X+ DEFUN ("push-to-dcl", Fpush_to_dcl, Spush_to_dcl, 0, 0, "", X+ "Suspend Emacs and spawn an interactive subprocess, similar to the\n\ X+ DCL spawn command. Logging out from the subprocess returns control to\n\ X+ Emacs. Before suspending Emacs, if `push-to-dcl-hook' is bound and value\n\ X+ is non-nil call the value as a function of no args. Don't suspend if it\n\ X+ returns non-nil. Otherwise, suspend normally and after resumption call\n\ X+ `push-to-dcl-resume-hook' if that is bound and non-nil.") X+ () X+ { X+ register Lisp_Object tem; X+ long status, substatus; X+ struct dsc$descriptor_s procname_d; X+ X+ /* Call value of push-to-dcl-hook X+ if it is bound and value is non-nil. */ X+ tem = intern ("push-to-dcl-hook"); X+ tem = XSYMBOL (tem)->value; X+ if (! EQ (tem, Qunbound) && ! EQ (tem, Qnil)) X+ { X+ tem = call0 (tem); X+ if (!EQ (tem, Qnil)) return Qnil; X+ } X+ X+ reset_sys_modes (); X+ status = lib$spawn (0); /* default *everything* */ X+ init_sys_modes (); X+ X+ /* Call value of push-to-dcl-resume-hook X+ if it is bound and value is non-nil. */ X+ tem = intern ("push-to-dcl-resume-hook"); X+ tem = XSYMBOL (tem)->value; X+ if (! EQ (tem, Qunbound) && ! EQ (tem, Qnil)) X+ call0 (tem); X+ return Qnil; X+ } X+ X+ X init_vmsfns () X { X process_list = 0; X*************** X*** 521,526 X defsubr (&Ssend_command_to_subprocess); X defsubr (&Sstop_subprocess); X defsubr (&Ssetprv); X Qdefault_subproc_input_handler = intern ("default-subprocess-input-handler"); X staticpro (&Qdefault_subproc_input_handler); X } X X--- 622,629 ----- X defsubr (&Ssend_command_to_subprocess); X defsubr (&Sstop_subprocess); X defsubr (&Ssetprv); X+ defsubr (&Sattach); X+ defsubr (&Spush_to_dcl); X Qdefault_subproc_input_handler = intern ("default-subprocess-input-handler"); X staticpro (&Qdefault_subproc_input_handler); X } SHAR_EOF sed 's/^X//' << \SHAR_EOF > vmspaths.diff X*** src/vmspaths.h.orig Mon Apr 18 20:17:14 1988 X--- src/vmspaths.h Mon Apr 18 20:36:38 1988 X*************** X*** 13,15 X /* the name of the file !!!SuperLock!!! in the directory X specified by PATH_LOCK. Yes, this is redundant. */ X #define PATH_SUPERLOCK "EMACS_LIBRARY:[LOCK]$$$SUPERLOCK$$$." X X--- 13,18 ----- X /* the name of the file !!!SuperLock!!! in the directory X specified by PATH_LOCK. Yes, this is redundant. */ X #define PATH_SUPERLOCK "EMACS_LIBRARY:[LOCK]$$$SUPERLOCK$$$." X+ X+ /* the name of the termcap file (for sites that already have one elsewhere) */ X+ #define PATH_TERMCAP "ETC:TERMCAP" SHAR_EOF sed 's/^X//' << \SHAR_EOF > kepteditor.com X$ Verify = 'F$Verify (0) X$ ! X$ ! KeptEditor.COM -- comments at the end. X$ ! X$ ! Run or attach to an editor in a kept fork. X$ ! X$ If P1 .Eqs. "EMACS" Then - X Name = F$Trnlnm("EMACS_PROCESS_NAME") X$ If Name .Eqs. "" Then - X Name = P1 + " " + F$Trnlnm ( "TT" ) - ":" X$ Edit = "" X$ Priv_List = F$Setprv ("NOWORLD, NOGROUP") X$ Args = P2 + " " + P3 + " " + P4 + " " + P5 + " " + - X P6 + " " + P7 + " " + P8 X$ Pid = 0 X$ 10$: X$ Proc = F$Getjpi ( F$Pid ( Pid ), "PRCNAM") X$ If Proc .Eqs. Name Then - X$ Goto Attach X$ If Pid .Ne. 0 Then - X$ Goto 10$ X$ ! X$ ! Spawn EDIT/TPU X$ ! X$ Spawn: X$ Priv_List = F$Setprv ( Priv_List ) X$ Write Sys$Error "[Spawning a kept ''P1' in process ''Name']" X$ If P1 .Nes. "TPU" Then - X$ Goto Check_Emacs X$ Define/User/NoLog Sys$Input Sys$Command X$ Spawn /Nolog /Process="''Name'" Edit/'P1' 'Args' X$ Goto Quit X$ ! X$ ! Spawn an Emacs subprocess X$ ! X$ Check_Emacs: X$ If P1 .Nes. "EMACS" Then - X$ Goto Un_Kempt X$ Prcnam = F$Getjpi("","PRCNAM") X$ Define/Job/Nolog Emacs_AttachTo "''Prcnam'" X$ Define/User/NoLog Sys$Input Sys$Command X$ Spawn /Nolog /Process="''Name'" Runemacs 'Args' X$ Deassign/Job Emacs_AttachTo X$ Goto Quit X$ ! X$ ! The editor is unruly - spawn a process and let the user X$ ! deal with the editor himself. X$ ! X$ Un_Kempt: X$ Spawn /Nolog /Process="''Name'" X$ Goto Quit X$ ! X$ ! Here to tune into a kept editor already in progress X$ ! X$ Attach: X$ Priv_List = F$Setprv ( Priv_List ) X$ Write Sys$Error "[Attaching to process ''NAME']" X$ Define/User/NoLog Sys$Input Sys$Command X$ If P1 .Nes. "EMACS" Then - X Goto Doit X$ ! X$ ! Communicate the working directory and any command-line X$ ! to Emacs -- almost as good as starting from scratch. X$ ! X$ Prcnam = F$Getjpi("","PRCNAM") X$ Dir = F$Trnlnm("SYS$DISK") + F$Directory() X$ Define/Job/Nolog Emacs_Newdirectory "''Dir'" X$ Define/Job/Nolog Emacs_AttachTo "''Prcnam'" X$ Args = F$Edit(Args,"TRIM,UPCASE") X$ If Args .Eqs. "" Then - X Args = "!" X$ If F$Element(0," ",Args) .Nes. " " Then - ! only 1 arg right now X Args = F$Element(0," ",Args) X$ Define/Job/Nolog Emacs_Newfile "''Args'" X$Doit: X$ Set Message/Nofacility/Noident/Noseverity/Notext ! ignore DCL msg X$ Attach "''Name'" X$ Set Message/Facility/Ident/Severity/Text X$ Deassign/Job Emacs_AttachTo X$ Deassign/Job Emacs_Newdirectory X$ Deassign/Job Emacs_Newfile X$Quit: X$ Write Sys$Error "[Directory ''F$TRNLNM("SYS$DISK")'''F$DIRECTORY()']" X$ If F$GetDvi("TT","TT_APP_KEYPAD") Then - X Set Terminal/Application_Keypad X$ If Verify Then - X Set Verify X$ Exit X$ ! X$ ! Command file for use on VMS to spawn an Emacs process that can be X$ ! suspended with C-z and will not go away when other programs are run. X$ ! This is the normal way for users to invoke Emacs on VMS; the command X$ ! "emacs" is normally defined to execute this file. X$ ! X$ ! That definition, and other definitions used by it, are done by X$ ! 'emacs.com'. Users who want to use Emacs should have their X$ ! `login.com' files execute `emacs.com', which is to be found in X$ ! this directory. X$ ! X$ ! Joe Kelsey X$ ! FlexComm Corp. X$ ! X$ ! September, 1985 X$ ! X$ ! Modified by Mic Kaczmarczik, July 1987 for U.T. Austin Instructional VMS X$ ! - Define EMACS_NEWFILE and EMACS_NEWDIRECTORY to tell suspend-resume-hook X$ ! about a new default directory and file to edit X$ ! - Do set message to avoid (personally) annoying "returning to DCL" message. X$ ! - Look for logical name "EMACS_PROCESS_NAME" to allow user to X$ ! define his own name for his Emacs process. X$ ! X$ ! Modified by Garland Joseph, Decemeber 8, 1987 for ditto X$ ! Added a conditional to set terminal APPLICATION_KEYPAD mode since X$ ! the Micro-Term Ergo 320 fails to retain APPLICATION_KEYPAD mode X$ ! (when set prior to entering EMACS). X$ ! X$ ! Modified 12-Apr-1988 MPK for locally hacked GNU Emacs 18.50 X$ ! - Define logical EMACS_ATTACHTO so the local "attach" function X$ ! knows where to re-attach us to. This lets us use GNU as a mail X$ ! editor! SHAR_EOF sed 's/^X//' << \SHAR_EOF > kepteditor.el X;;; X;;; This code implements the LISP portion of a "kept" editor interface X;;; that allows Emacs users to attach from Emacs to any process. This X;;; is used in conjunction with KEPTEDITOR.COM, which defines logical X;;; names as a way to communicate command-line args to the kept Emacs X;;; subprocess. X;;; X;;; Written 12-Apr-1988 by Mic Kaczmarczik for a locally-enhanced version X;;; of GNU Emacs 18.50 which provides the "attach" function. X;;; X X(defun clear-mail-buffer nil X "If the current buffer's file name is that of a VMS MAIL scratch file Xadd the message to the buffer *OLD-MAIL* and kill the current buffer. This Xmakes sure that people who use SEND/EDIT=(REPLY=EXTRACT) will get what they Xwant. You also get a log of sent mail messages in the bargain." X (let* ((buf (current-buffer)) X (filename (buffer-file-name))) X (if (and filename X (string= (substring filename 0 17) "SYS$SCRATCH:MAIL_") X (string= (substring filename -4) ".TMP")) X (progn X (save-excursion X (get-buffer-create "*OLD-MAIL*") X (set-buffer "*OLD-MAIL*") X (insert-buffer (buffer-name buf)) X (goto-char (point-max)) X (insert X"---------------------------------------------------------------------------- X") X (goto-char (point-max)) X (set-buffer buf) X (set-buffer-modified-p nil)) X (kill-buffer buf))))) X X;;; X;;; Make suspend-emacs and attach call save-some-buffers, because DCL X;;; will cheerfully let you log out with an Emacs subprocess, unlike X;;; the C-shell under Unix. If the current buffer is a mail message, X;;; save it in the buffer *OLD-MAIL* and kill the buffer. X;;; X(defun clear-mail-suspend-hook nil X "Call save-some-buffers, then return nil so suspend will continue" X (save-some-buffers) X (clear-mail-buffer) X (message "") X nil) X X(defvar suspend-hook (function clear-mail-suspend-hook) X "Hook called by suspend-emacs before returning to command level. Calls Xsave-some-buffers to make sure you want to save things before suspending. XPut the line (setq suspend-hook nil) in your init file if you don't want Xthis to happen when you suspend Emacs.") X X(defvar attach-hook (function clear-mail-suspend-hook) X "Hook called by attach before returning to command level. Calls Xsave-some-buffers to make sure you want to save things before suspending. XPut the line (setq suspend-hook nil) in your init file if you don't Xwant this to happen when you attach to another process.") X X;;; X;;; Next define a process resumption hook that does nice stuff when we X;;; re-attach to Emacs from another VMS process. This includes changing X;;; the current directory and visiting a new file, if desired. X;;; X X(defun vms-resume-hook () X "Function called while resuming VMS Emacs after a M-x suspend or XM-x attach. Translates the logical name EMACS_NEWDIRECTORY, then attempts Xto change the current buffer's current directory to the directory, Xand visits the file specified by the logical name EMACS_NEWFILE. X XThis function is local to the UT Austin Instructional VMS systems. XSend comments and suggestions to the mail address REMARK." X X (let ((newwd (getenv "EMACS_NEWDIRECTORY"))) X (if (and newwd (not (string-equal default-directory newwd))) X (cd newwd))) X X (let ((newfile (getenv "EMACS_NEWFILE"))) X (if (and newfile (not (string-equal newfile "!"))) X (find-file newfile)))) X X;;; X;;; suspend-resume-hook and attach-resume-hook are the same right now... X;;; X X(defvar suspend-resume-hook (function vms-resume-hook) X "Hook called when resuming Emacs after calling suspend-emacs. XThe default hook changes the current directory and attempts to Xvisit a new file, if specified by the logical name EMACS_NEWFILE.") X X(defvar attach-resume-hook (function vms-resume-hook) X "Hook called when resuming VMS Emacs after calling attach. The default Xhook changes the current directory and attempts to visit a new file, if Xspecified by the logical name EMACS_NEWFILE.") X X;;; X;;; A function that we bind to C-z, which calls attach instead of X;;; suspend-emacs. X;;; X X(defun attach-to-parent nil X "Attach the terminal to the parent process, or the process specified Xby the logical name EMACS_ATTACHTO, if present." X (interactive nil) X (let ((parent (getenv "EMACS_ATTACHTO"))) X (if parent X (attach parent) X (attach nil)))) X X(global-set-key "" 'attach-to-parent) X SHAR_EOF sed 's/^X//' << \SHAR_EOF > gnu_mailedit.com X$ Verify = 'F$Verify(0) X$ ! X$ ! Command procedure to invoke Emacs from MAIL. You should X$ ! have the symbol Emacs globally defined, by running the command X$ ! file EMACS_LIBRARY:[000000]EMACS.COM. X$ ! X$ ! Then X$ ! DEFINE MAIL$EDIT SYS$PUBLIC:GNU_MAILEDIT.COM X$ ! X$ ! to make MAIL look for this file when you do a SEND/EDIT X$ ! X$ ! When you're done editing your message, use C-x C-s to save the message X$ ! file, then exit Emacs by typing C-z. X$ ! X$ ! Inputs: X$ ! X$ ! P1 = Input file name. X$ ! P2 = Output file name. X$ ! X$ ! The default directory is the same as the parent process. X$ ! X$ ! Copy the input file to the output file, then invoke GNU Emacs on it. X$ ! X$ Set Noon X$ Define/Job Emacs_AttachTo "''F$Process()'" X$ If P2 .Nes. "" .AND. P1 .Nes. "" Then Copy 'P1' 'P2' X$ Define/User Sys$Input Sys$Command X$ Emacs 'P2' X$ If F$Trnlnm("Emacs_AttachTo") .Nes. "" Then - X Deassign/Job Emacs_AttachTo ! command file might have done it already X$ If F$Search(P2) Then - X Purge/Nolog P2 ! avoid multiple copies of the message file X$ If Verify Then - X Set Verify SHAR_EOF # End of shell archive exit 0 -- Mic Kaczmarczik If you drink, don't drill. UT Austin Computation Center -- Matt Groening mic@emx.utexas.edu MIC@UTAIVC.BITNET -------