From xemacs-m  Thu Jun 12 00:30:37 1997
Received: from jagor.srce.hr (hniksic@jagor.srce.hr [161.53.2.130])
	by xemacs.org (8.8.5/8.8.5) with ESMTP id AAA14442
	for <xemacs-beta@xemacs.org>; Thu, 12 Jun 1997 00:30:36 -0500 (CDT)
Received: (from hniksic@localhost)
          by jagor.srce.hr (8.8.5/8.8.4)
	  id HAA18039; Thu, 12 Jun 1997 07:30:36 +0200 (MET DST)
To: XEmacs Developers <xemacs-beta@xemacs.org>
Subject: `save-current-buffer': take two
X-Attribution: Hrv
X-Face: Mie8:rOV<\c/~z{s.X4A{!?vY7{drJ([U]0O=W/<W*SMo/Mv:58:*_y~ki>xDi&N7XG
        KV^$k0m3Oe/)'e%3=$PCR&3ITUXH,cK>]bci&<qQ>Ff%x_>1`T(+M2Gg/fgndU%k*ft
        [(7._6e0n-V%|%'[c|q:;}td$#INd+;?!-V=c8Pqf}3J
From: Hrvoje Niksic <hniksic@srce.hr>
Date: 12 Jun 1997 07:30:35 +0200
Message-ID: <kigrae8pev8.fsf@jagor.srce.hr>
Lines: 279
X-Mailer: Gnus v5.4.52/XEmacs 20.3(beta5)

RMS has agreed to move `save-current-buffer' to 0162 (which was my
location).  Hooray! -- now my patch should be the compatible one,
without further changes.

To remind you all, here are the patches to install to test it.
Rebytecompiling subr.el can be tricky, because you must get rid of the 
old `save-current-buffer' macro.  The easiest route to get it all
right is the following:

a. Apply the patches and remove lisp/prim/subr.elc;
b. Build XEmacs;
c. Byte-compile subr.el;
d. Redump XEmacs.

To check whether everything went OK, you can check whether the
documentation for `save-current-buffer' calls it a macro or a bultin.

--- etc/NEWS.orig	Wed Jun 11 02:38:44 1997
+++ etc/NEWS	Wed Jun 11 02:40:17 1997
@@ -202,6 +202,23 @@
 ** The PATTERN argument to `split-string' is now optional and defaults
 to whitespace ("[ \f\t\n\r\v]+").
 
+** The new macro `with-current-buffer' lets you evaluate an expression
+conveniently with a different current buffer.  It looks like this:
+
+  (with-current-buffer BUFFER BODY-FORMS...)
+
+BUFFER is the expression that says which buffer to use.
+BODY-FORMS say what to do in that buffer.
+
+** The new primitive `save-current-buffer' saves and restores the
+choice of current buffer, like `save-excursion', but without saving or
+restoring the value of point or the mark.  `with-current-buffer'
+works using `save-current-buffer'.
+
+** The new macro `with-temp-file' lets you do some work in a new buffer and
+write the output to a specified file.  Like `progn', it returns the value
+of the last form.
+
 
 
 * Changes in XEmacs 20.2
--- src/editfns.c.orig	Wed Jun 11 01:35:49 1997
+++ src/editfns.c	Wed Jun 11 01:39:14 1997
@@ -489,6 +489,20 @@
 			 
   return unbind_to (speccount, Fprogn (args));
 }
+
+DEFUN ("save-current-buffer", Fsave_current_buffer, 0, UNEVALLED, 0, /*
+Save the current buffer; execute BODY; restore the current buffer.
+Executes BODY just like `progn'.
+*/
+  (args))
+{
+  /* This function can GC */
+  int speccount = specpdl_depth ();
+
+  record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+
+  return unbind_to (speccount, Fprogn (args));
+}
 
 DEFUN ("buffer-size", Fbufsize, 0, 1, 0, /*
 Return the number of characters in BUFFER.
@@ -2100,6 +2114,7 @@
   DEFSUBR (Fregion_beginning);
   DEFSUBR (Fregion_end);
   DEFSUBR (Fsave_excursion);
+  DEFSUBR (Fsave_current_buffer);
 
   DEFSUBR (Fbufsize);
   DEFSUBR (Fpoint_max);
--- src/bytecode.c.orig	Wed Jun 11 01:49:24 1997
+++ src/bytecode.c	Wed Jun 11 01:53:33 1997
@@ -155,7 +155,8 @@
 #define Bbobp 0157
 #define Bcurrent_buffer 0160
 #define Bset_buffer 0161
-#define Bread_char 0162 /* No longer generated as of v19 */
+#define Bsave_current_buffer 0162 /* was Bread_char, but no longer
+				     generated as of v19 */
 #define Bmemq 0163 /* was Bset_mark, but no longer generated as of v18 */
 #define Binteractive_p 0164 /* Needed since interactive-p takes unevalled args */
 
@@ -941,8 +942,8 @@
 	  TOP = Fset_buffer (TOP);
 	  break;
 
-	case Bread_char:
-	  error ("read-char is an obsolete byte code");
+	case Bsave_current_buffer:
+	  record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
 	  break;
 
 	case Binteractive_p:
--- lisp/prim/subr.el.orig	Tue Jun 10 22:38:11 1997
+++ lisp/prim/subr.el	Wed Jun 11 02:27:22 1997
@@ -333,6 +333,33 @@
 	   (buffer-string)
 	 (erase-buffer)))))
 
+(defmacro with-current-buffer (buffer &rest body)
+  "Execute the forms in BODY with BUFFER as the current buffer.
+The value returned is the value of the last form in BODY.
+See also `with-temp-buffer'."
+  `(save-current-buffer
+    (set-buffer ,buffer)
+    ,@body))
+
+(defmacro with-temp-file (file &rest forms)
+  "Create a new buffer, evaluate FORMS there, and write the buffer to FILE.
+The value of the last form in FORMS is returned, like `progn'.
+See also `with-temp-buffer'."
+  (let ((temp-file (make-symbol "temp-file"))
+	(temp-buffer (make-symbol "temp-buffer")))
+    `(let ((,temp-file ,file)
+	   (,temp-buffer
+	    (get-buffer-create (generate-new-buffer-name " *temp file*"))))
+       (unwind-protect
+	   (prog1
+	       (with-current-buffer ,temp-buffer
+                  ,@forms)
+	     (with-current-buffer ,temp-buffer
+               (widen)
+	       (write-region (point-min) (point-max) ,temp-file nil 0)))
+	 (and (buffer-name ,temp-buffer)
+	      (kill-buffer ,temp-buffer))))))
+
 (defmacro with-temp-buffer (&rest forms)
   "Create a temporary buffer, and evaluate FORMS there like `progn'."
   (let ((temp-buffer (make-symbol "temp-buffer")))
--- lisp/bytecomp/bytecomp.el.orig	Wed Jun 11 01:56:45 1997
+++ lisp/bytecomp/bytecomp.el	Wed Jun 11 02:00:45 1997
@@ -577,7 +577,9 @@
 (byte-defop 111  1 byte-bobp)
 (byte-defop 112  1 byte-current-buffer)
 (byte-defop 113  0 byte-set-buffer)
-(byte-defop 114  1 byte-read-char-OBSOLETE) ;obsolete as of v19
+(byte-defop 114  0 byte-save-current-buffer
+  "To make a binding to record the current buffer.")
+;;(byte-defop 114  1 byte-read-char-OBSOLETE) ;obsolete as of v19
 (byte-defop 115 -1 byte-memq) ; new as of v20
 (byte-defop 116  1 byte-interactive-p)
 
@@ -3527,6 +3529,7 @@
 (byte-defop-compiler-1 unwind-protect)
 (byte-defop-compiler-1 condition-case)
 (byte-defop-compiler-1 save-excursion)
+(byte-defop-compiler-1 save-current-buffer)
 (byte-defop-compiler-1 save-restriction)
 (byte-defop-compiler-1 save-window-excursion)
 (byte-defop-compiler-1 with-output-to-temp-buffer)
@@ -3611,6 +3614,11 @@
 
 (defun byte-compile-save-restriction (form)
   (byte-compile-out 'byte-save-restriction 0)
+  (byte-compile-body-do-effect (cdr form))
+  (byte-compile-out 'byte-unbind 1))
+
+(defun byte-compile-save-current-buffer (form)
+  (byte-compile-out 'byte-save-current-buffer 0)
   (byte-compile-body-do-effect (cdr form))
   (byte-compile-out 'byte-unbind 1))
 
--- lisp/bytecomp/byte-optimize.el.orig	Wed Jun 11 02:02:47 1997
+++ lisp/bytecomp/byte-optimize.el	Wed Jun 11 02:02:59 1997
@@ -433,7 +433,7 @@
 	       (cons (byte-optimize-form (nth 2 form) for-effect)
 		     (byte-optimize-body (cdr (cdr (cdr form))) t)))))
 	  
-	  ((memq fn '(save-excursion save-restriction))
+	  ((memq fn '(save-excursion save-restriction save-current-buffer))
 	   ;; those subrs which have an implicit progn; it's not quite good
 	   ;; enough to treat these like normal function calls.
 	   ;; This can turn (save-excursion ...) into (save-excursion) which
--- lisp/edebug/edebug.el.orig	Wed Jun 11 02:07:16 1997
+++ lisp/edebug/edebug.el	Wed Jun 11 02:10:38 1997
@@ -2164,6 +2164,14 @@
 (def-edebug-spec eval-when-compile t)
 (def-edebug-spec eval-and-compile t)
 
+(def-edebug-spec save-selected-window t)
+(def-edebug-spec save-current-buffer t)
+(def-edebug-spec save-match-data t)
+(def-edebug-spec with-output-to-string t)
+(def-edebug-spec with-current-buffer t)
+(def-edebug-spec with-temp-file t)
+(def-edebug-spec with-temp-buffer t)
+
 ;; Anything else?
 
 
--- lisp/modes/lisp-mode.el.orig	Wed Jun 11 02:23:19 1997
+++ lisp/modes/lisp-mode.el	Wed Jun 11 02:34:39 1997
@@ -713,6 +713,10 @@
 (put 'catch 'lisp-indent-function 1)
 (put 'condition-case 'lisp-indent-function 2)
 (put 'unwind-protect 'lisp-indent-function 1)
+(put 'save-current-buffer 'lisp-indent-function 0)
+(put 'with-current-buffer 'lisp-indent-function 1)
+(put 'with-temp-file 'lisp-indent-function 1)
+(put 'with-output-to-string 'lisp-indent-function 0)
 (put 'with-output-to-temp-buffer 'lisp-indent-function 1)
 
 (defun indent-sexp (&optional endpos)
--- src/bytecode.c.orig	Wed Jun 11 05:30:42 1997
+++ src/bytecode.c	Wed Jun 11 05:31:03 1997
@@ -943,8 +943,13 @@
 	  break;
 
 	case Bsave_current_buffer:
-	  record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
-	  break;
+	  {
+	    Lisp_Object save_current_buffer_restore (Lisp_Object);
+
+	    record_unwind_protect (save_current_buffer_restore,
+				   Fcurrent_buffer ());
+	    break;
+	  }
 
 	case Binteractive_p:
 	  PUSH (Finteractive_p ());
--- src/editfns.c.orig	Wed Jun 11 05:28:52 1997
+++ src/editfns.c	Wed Jun 11 05:51:36 1997
@@ -490,6 +490,16 @@
   return unbind_to (speccount, Fprogn (args));
 }
 
+Lisp_Object
+save_current_buffer_restore(Lisp_Object buffer)
+{
+  struct buffer *buf = XBUFFER (buffer);
+  if (!BUFFER_LIVE_P (buf))
+    return Qnil;
+  set_buffer_internal (buf);
+  return Qnil;
+}
+
 DEFUN ("save-current-buffer", Fsave_current_buffer, 0, UNEVALLED, 0, /*
 Save the current buffer; execute BODY; restore the current buffer.
 Executes BODY just like `progn'.
@@ -499,7 +509,7 @@
   /* This function can GC */
   int speccount = specpdl_depth ();
 
-  record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+  record_unwind_protect (save_current_buffer_restore, Fcurrent_buffer ());
 
   return unbind_to (speccount, Fprogn (args));
 }
--- lisp/prim/subr.el.orig	Wed Jun 11 05:50:53 1997
+++ lisp/prim/subr.el	Wed Jun 11 05:50:57 1997
@@ -551,16 +551,6 @@
   (interactive)
   nil)
 
-(defmacro save-current-buffer (&rest forms)
-  "Restore the current buffer setting after executing FORMS.
-Does not restore the values of point and mark.
-See also: `save-excursion'."
-  ;; by Stig@hackvan.com
-  (` (let ((_cur_buf_ (current-buffer)))
-       (unwind-protect
-	   (progn (,@ forms))
-	 (set-buffer _cur_buf_)))))
-
 (defmacro eval-in-buffer (buffer &rest forms)
   "Evaluate FORMS in BUFFER.
 See also: `save-current-buffer' and `save-excursion'."


-- 
Hrvoje Niksic <hniksic@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
* Q: What is an experienced Emacs user?
* A: A person who wishes that the terminal had pedals.

