(read-quoted-char): Convert function keys like Return
[bpt/emacs.git] / lisp / subr.el
index e0a8e01..14ae2ba 100644 (file)
@@ -1,6 +1,6 @@
 ;;; subr.el --- basic lisp subroutines for Emacs
 
-;;; Copyright (C) 1985, 1986, 1992, 1994 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1992, 1994, 1995 Free Software Foundation, Inc.
 
 ;; This file is part of GNU Emacs.
 
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
 
 ;;; Code:
-
+(defvar custom-declare-variable-list nil
+  "Record `defcustom' calls made before `custom.el' is loaded to handle them.
+Each element of this list holds the arguments to one call to `defcustom'.")
+
+;; Use this rather that defcustom, in subr.el and other files loaded
+;; before custom.el.
+(defun custom-declare-variable-early (&rest arguments)
+  (setq custom-declare-variable-list
+       (cons arguments custom-declare-variable-list)))
 \f
 ;;;; Lisp language features.
 
@@ -32,7 +41,9 @@ function, i.e., stored as the function value of a symbol, passed to
 funcall or mapcar, etc.
 
 ARGS should take the same form as an argument list for a `defun'.
-DOCSTRING should be a string, as described for `defun'.  It may be omitted.
+DOCSTRING is an optional documentation string.
+ If present, it should describe how to call the function.
+ But documentation strings are usually not useful in nameless functions.
 INTERACTIVE should be a call to the function `interactive', which see.
 It may also be omitted.
 BODY should be a list of lisp expressions."
@@ -40,72 +51,17 @@ BODY should be a list of lisp expressions."
   ;; depend on backquote.el.
   (list 'function (cons 'lambda cdr)))
 
-;;(defmacro defun-inline (name args &rest body)
-;;  "Create an \"inline defun\" (actually a macro).
-;;Use just like `defun'."
-;;  (nconc (list 'defmacro name '(&rest args))
-;;      (if (stringp (car body))
-;;          (prog1 (list (car body))
-;;            (setq body (or (cdr body) body))))
-;;      (list (list 'cons (list 'quote
-;;                              (cons 'lambda (cons args body)))
-;;                  'args))))
-
-\f
-;;;; Window tree functions.
-
-(defun one-window-p (&optional nomini all-frames)
-  "Returns non-nil if the selected window is the only window (in its frame).
-Optional arg NOMINI non-nil means don't count the minibuffer
-even if it is active.
-
-The optional arg ALL-FRAMES t means count windows on all frames.
-If it is `visible', count windows on all visible frames.
-ALL-FRAMES nil or omitted means count only the selected frame, 
-plus the minibuffer it uses (which may be on another frame).
-If ALL-FRAMES is neither nil nor t, count only the selected frame."
-  (let ((base-window (selected-window)))
-    (if (and nomini (eq base-window (minibuffer-window)))
-       (setq base-window (next-window base-window)))
-    (eq base-window
-       (next-window base-window (if nomini 'arg) all-frames))))
-
-(defun walk-windows (proc &optional minibuf all-frames)
-  "Cycle through all visible windows, calling PROC for each one.
-PROC is called with a window as argument.
-Optional second arg MINIBUF t means count the minibuffer window
-even if not active.  If MINIBUF is neither t nor nil it means
-not to count the minibuffer even if it is active.
-
-Optional third arg ALL-FRAMES, if t, means include all frames.
-ALL-FRAMES nil or omitted means cycle within the selected frame,
-but include the minibuffer window (if MINIBUF says so) that that
-frame uses, even if it is on another frame.
-If ALL-FRAMES is neither nil nor t, stick strictly to the selected frame."
-  ;; If we start from the minibuffer window, don't fail to come back to it.
-  (if (window-minibuffer-p (selected-window))
-      (setq minibuf t))
-  (let* ((walk-windows-start (selected-window))
-        (walk-windows-current walk-windows-start))
-    (while (progn
-            (setq walk-windows-current
-                  (next-window walk-windows-current minibuf all-frames))
-            (funcall proc walk-windows-current)
-            (not (eq walk-windows-current walk-windows-start))))))
-
-(defun minibuffer-window-active-p (window)
-  "Return t if WINDOW (a minibuffer window) is now active."
-  ;; nil nil means include WINDOW's frame
-  ;; and other frames using WINDOW as minibuffer,
-  ;; and include minibuffer if active.
-  (let ((prev (previous-window window nil nil)))
-    ;; If PREV equals WINDOW, WINDOW must be on a minibuffer-only frame
-    ;; and it's not currently being used.  So return nil.
-    (and (not (eq window prev))
-        (let ((should-be-same (next-window prev nil nil)))
-          ;; If next-window doesn't reverse previous-window,
-          ;; WINDOW must be outside the cycle specified by nil nil.
-          (eq should-be-same window)))))
+(defmacro when (cond &rest body)
+  "(when COND BODY...): if COND yields non-nil, do BODY, else return nil."
+  (list 'if cond (cons 'progn body)))
+(put 'when 'lisp-indent-function 1)
+(put 'when 'edebug-form-spec '(&rest form))
+
+(defmacro unless (cond &rest body)
+  "(unless COND BODY...): if COND yields nil, do BODY, else return nil."
+  (cons 'if (cons cond (cons nil body))))
+(put 'unless 'lisp-indent-function 1)
+(put 'unless 'edebug-form-spec '(&rest form))
 \f
 ;;;; Keymap support.
 
@@ -177,12 +133,18 @@ in KEYMAP as NEWDEF those chars which are defined as OLDDEF in OLDMAP."
              (while (and (symbolp inner-def)
                          (fboundp inner-def))
                (setq inner-def (symbol-function inner-def)))
-             (if (eq defn olddef)
+             (if (or (eq defn olddef)
+                     ;; Compare with equal if definition is a key sequence.
+                     ;; That is useful for operating on function-key-map.
+                     (and (or (stringp defn) (vectorp defn))
+                          (equal defn olddef)))
                  (define-key keymap prefix1 (nconc (nreverse skipped) newdef))
                (if (and (keymapp defn)
                         ;; Avoid recursively scanning
                         ;; where KEYMAP does not have a submap.
-                        (keymapp (lookup-key keymap prefix1))
+                        (let ((elt (lookup-key keymap prefix1)))
+                          (or (null elt)
+                              (keymapp elt)))
                         ;; Avoid recursively rescanning keymap being scanned.
                         (not (memq inner-def
                                    key-substitution-in-progress)))
@@ -191,7 +153,7 @@ in KEYMAP as NEWDEF those chars which are defined as OLDDEF in OLDMAP."
                    (substitute-key-definition olddef newdef keymap
                                               inner-def
                                               prefix1)))))
-       (if (arrayp (car scan))
+       (if (vectorp (car scan))
            (let* ((array (car scan))
                   (len (length array))
                   (i 0))
@@ -212,27 +174,73 @@ in KEYMAP as NEWDEF those chars which are defined as OLDDEF in OLDMAP."
                    (while (and (symbolp inner-def)
                                (fboundp inner-def))
                      (setq inner-def (symbol-function inner-def)))
-                   (if (eq defn olddef)
+                   (if (or (eq defn olddef)
+                           (and (or (stringp defn) (vectorp defn))
+                                (equal defn olddef)))
                        (define-key keymap prefix1
                          (nconc (nreverse skipped) newdef))
                      (if (and (keymapp defn)
-                              (keymapp (lookup-key keymap prefix1))
+                              (let ((elt (lookup-key keymap prefix1)))
+                                (or (null elt)
+                                    (keymapp elt)))
                               (not (memq inner-def
                                          key-substitution-in-progress)))
                          (substitute-key-definition olddef newdef keymap
                                                     inner-def
                                                     prefix1)))))
-               (setq i (1+ i))))))
+               (setq i (1+ i))))
+         (if (char-table-p (car scan))
+             (map-char-table
+              (function (lambda (char defn)
+                          (let ()
+                            ;; The inside of this let duplicates exactly
+                            ;; the inside of the previous let,
+                            ;; except that it uses set-char-table-range
+                            ;; instead of define-key.
+                            (aset vec1 0 char)
+                            (aset prefix1 (length prefix) char)
+                            (let (inner-def skipped)
+                              ;; Skip past menu-prompt.
+                              (while (stringp (car-safe defn))
+                                (setq skipped (cons (car defn) skipped))
+                                (setq defn (cdr defn)))
+                              (and (consp defn) (consp (car defn))
+                                   (setq defn (cdr defn)))
+                              (setq inner-def defn)
+                              (while (and (symbolp inner-def)
+                                          (fboundp inner-def))
+                                (setq inner-def (symbol-function inner-def)))
+                              (if (or (eq defn olddef)
+                                      (and (or (stringp defn) (vectorp defn))
+                                           (equal defn olddef)))
+                                  (define-key keymap prefix1
+                                    (nconc (nreverse skipped) newdef))
+                                (if (and (keymapp defn)
+                                         (let ((elt (lookup-key keymap prefix1)))
+                                           (or (null elt)
+                                               (keymapp elt)))
+                                         (not (memq inner-def
+                                                    key-substitution-in-progress)))
+                                    (substitute-key-definition olddef newdef keymap
+                                                               inner-def
+                                                               prefix1)))))))
+              (car scan)))))
       (setq scan (cdr scan)))))
 
 (defun define-key-after (keymap key definition after)
   "Add binding in KEYMAP for KEY => DEFINITION, right after AFTER's binding.
 This is like `define-key' except that the binding for KEY is placed
 just after the binding for the event AFTER, instead of at the beginning
-of the map.
-The order matters when the keymap is used as a menu.
+of the map.  Note that AFTER must be an event type (like KEY), NOT a command
+\(like DEFINITION).
+
+If AFTER is t, the new binding goes at the end of the keymap.
+
 KEY must contain just one event type--that is to say, it must be
-a string or vector of length 1."
+a string or vector of length 1.
+
+The order of bindings in a keymap matters when it is used as a menu."
+
   (or (keymapp keymap)
       (signal 'wrong-type-argument (list 'keymapp keymap)))
   (if (> (length key) 1)
@@ -246,7 +254,8 @@ a string or vector of length 1."
       ;; When we reach AFTER's binding, insert the new binding after.
       ;; If we reach an inherited keymap, insert just before that.
       ;; If we reach the end of this keymap, insert at the end.
-      (if (or (eq (car-safe (car tail)) after)
+      (if (or (and (eq (car-safe (car tail)) after)
+                  (not (eq after t)))
              (eq (car (cdr tail)) 'keymap)
              (null (cdr tail)))
          (progn
@@ -261,22 +270,21 @@ a string or vector of length 1."
            (setq inserted t)))
       (setq tail (cdr tail)))))
 
+(defmacro kbd (keys)
+  "Convert KEYS to the internal Emacs key representation.
+KEYS should be a string constant in the format used for
+saving keyboard macros (see `insert-kbd-macro')."
+  (read-kbd-macro keys))
+
+(put 'keyboard-translate-table 'char-table-extra-slots 0)
+
 (defun keyboard-translate (from to)
   "Translate character FROM to TO at a low level.
 This function creates a `keyboard-translate-table' if necessary
 and then modifies one entry in it."
-  (or (arrayp keyboard-translate-table)
-      (setq keyboard-translate-table ""))
-  (if (or (> from (length keyboard-translate-table))
-         (> to   (length keyboard-translate-table)))
-      (progn
-       (let* ((i (length keyboard-translate-table))
-              (table (concat keyboard-translate-table
-                             (make-string (- 256 i) 0))))
-         (while (< i 256)
-           (aset table i i)
-           (setq i (1+ i)))
-         (setq keyboard-translate-table table))))
+  (or (char-table-p keyboard-translate-table)
+      (setq keyboard-translate-table
+           (make-char-table 'keyboard-translate-table nil)))
   (aset keyboard-translate-table from to))
 
 \f
@@ -470,6 +478,7 @@ as returned by the `event-start' and `event-end' functions."
 (defalias 'buffer-flush-undo 'buffer-disable-undo)
 (defalias 'eval-current-buffer 'eval-buffer)
 (defalias 'compiled-function-p 'byte-code-function-p)
+(defalias 'define-function 'defalias)
 
 ;; Some programs still use this as a function.
 (defun baud-rate ()
@@ -477,13 +486,14 @@ as returned by the `event-start' and `event-end' functions."
 Please convert your programs to use the variable `baud-rate' directly."
   baud-rate)
 
+(defalias 'focus-frame 'ignore)
+(defalias 'unfocus-frame 'ignore)
 \f
 ;;;; Alternate names for functions - these are not being phased out.
 
 (defalias 'string= 'string-equal)
 (defalias 'string< 'string-lessp)
 (defalias 'move-marker 'set-marker)
-(defalias 'eql 'eq)
 (defalias 'not 'null)
 (defalias 'rplaca 'setcar)
 (defalias 'rplacd 'setcdr)
@@ -501,123 +511,6 @@ Please convert your programs to use the variable `baud-rate' directly."
 \f
 ;;;; Hook manipulation functions.
 
-(defun run-hooks (&rest hooklist)
-  "Takes hook names and runs each one in turn.  Major mode functions use this.
-Each argument should be a symbol, a hook variable.
-These symbols are processed in the order specified.
-If a hook symbol has a non-nil value, that value may be a function
-or a list of functions to be called to run the hook.
-If the value is a function, it is called with no arguments.
-If it is a list, the elements are called, in order, with no arguments.
-
-To make a hook variable buffer-local, use `make-local-hook', not
-`make-local-variable'."
-  (while hooklist
-    (let ((sym (car hooklist)))
-      (and (boundp sym)
-          (symbol-value sym)
-          (let ((value (symbol-value sym)))
-            (if (and (listp value) (not (eq (car value) 'lambda)))
-                (while value
-                  (if (eq (car value) t)
-                      ;; t indicates this hook has a local binding;
-                      ;; it means to run the global binding too.
-                      (let ((functions (default-value sym)))
-                        (while functions
-                          (funcall (car functions))
-                          (setq functions (cdr functions))))
-                    (funcall (car value)))
-                  (setq value (cdr value)))
-              (funcall value)))))
-    (setq hooklist (cdr hooklist))))
-
-(defun run-hook-with-args (hook &rest args)
-  "Run HOOK with the specified arguments ARGS.
-HOOK should be a symbol, a hook variable.  If HOOK has a non-nil
-value, that value may be a function or a list of functions to be
-called to run the hook.  If the value is a function, it is called with
-the given arguments and its return value is returned.  If it is a list
-of functions, those functions are called, in order,
-with the given arguments ARGS.
-It is best not to depend on the value return by `run-hook-with-args',
-as that may change.
-
-To make a hook variable buffer-local, use `make-local-hook', not
-`make-local-variable'."
-  (and (boundp hook)
-       (symbol-value hook)
-       (let ((value (symbol-value hook)))
-        (if (and (listp value) (not (eq (car value) 'lambda)))
-            (while value
-              (if (eq (car value) t)
-                  ;; t indicates this hook has a local binding;
-                  ;; it means to run the global binding too.
-                  (let ((functions (default-value hook)))
-                    (while functions
-                      (apply (car functions) args)
-                      (setq functions (cdr functions))))
-                (apply (car value) args))
-              (setq value (cdr value)))
-          (apply value args)))))
-
-(defun run-hook-with-args-until-success (hook &rest args)
-  "Run HOOK with the specified arguments ARGS.
-HOOK should be a symbol, a hook variable.  Its value should
-be a list of functions.  We call those functions, one by one,
-passing arguments ARGS to each of them, until one of them
-returns a non-nil value.  Then we return that value.
-If all the functions return nil, we return nil.
-
-To make a hook variable buffer-local, use `make-local-hook', not
-`make-local-variable'."
-  (and (boundp hook)
-       (symbol-value hook)
-       (let ((value (symbol-value hook))
-            success)
-        (while (and value (not success))
-          (if (eq (car value) t)
-              ;; t indicates this hook has a local binding;
-              ;; it means to run the global binding too.
-              (let ((functions (default-value hook)))
-                (while (and functions (not success))
-                  (setq success (apply (car functions) args))
-                  (setq functions (cdr functions))))
-            (setq success (apply (car value) args)))
-          (setq value (cdr value)))
-        success)))
-
-(defun run-hook-with-args-until-failure (hook &rest args)
-  "Run HOOK with the specified arguments ARGS.
-HOOK should be a symbol, a hook variable.  Its value should
-be a list of functions.  We call those functions, one by one,
-passing arguments ARGS to each of them, until one of them
-returns nil.  Then we return nil.
-If all the functions return non-nil, we return non-nil.
-
-To make a hook variable buffer-local, use `make-local-hook', not
-`make-local-variable'."
-  ;; We must return non-nil if there are no hook functions!
-  (or (not (boundp hook))
-      (not (symbol-value hook))
-      (let ((value (symbol-value hook))
-           (success t))
-       (while (and value success)
-         (if (eq (car value) t)
-             ;; t indicates this hook has a local binding;
-             ;; it means to run the global binding too.
-             (let ((functions (default-value hook)))
-               (while (and functions success)
-                 (setq success (apply (car functions) args))
-                 (setq functions (cdr functions))))
-           (setq success (apply (car value) args)))
-         (setq value (cdr value)))
-       success)))
-
-;; Tell C code how to call this function.
-(defconst run-hooks 'run-hooks
-  "Variable by which C primitives find the function `run-hooks'.
-Don't change it.")
-
 (defun make-local-hook (hook)
   "Make the hook HOOK local to the current buffer.
 When a hook is local, its local and global values
@@ -625,7 +518,15 @@ work in concert: running the hook actually runs all the hook
 functions listed in *either* the local value *or* the global value
 of the hook variable.
 
-This function does nothing if HOOK is already local in the current buffer.
+This function works by making `t' a member of the buffer-local value,
+which acts as a flag to run the hook functions in the default value as
+well.  This works for all normal hooks, but does not work for most
+non-normal hooks yet.  We will be changing the callers of non-normal
+hooks so that they can handle localness; this has to be done one by
+one.
+
+This function does nothing if HOOK is already local in the current
+buffer.
 
 Do not use `make-local-variable' to make a hook variable buffer-local."
   (if (local-variable-p hook)
@@ -659,7 +560,7 @@ function, it is changed to a list of functions."
   (if (or local
          ;; Detect the case where make-local-variable was used on a hook
          ;; and do what we used to do.
-         (and (local-variable-p hook)
+         (and (local-variable-if-set-p hook)
               (not (memq t (symbol-value hook)))))
       ;; Alter the local value only.
       (or (if (consp function)
@@ -717,6 +618,7 @@ To make a hook variable buffer-local, always use
 
 (defun add-to-list (list-var element)
   "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet.
+The test for presence of ELEMENT is done with `equal'.
 If you want to use `add-to-list' on a variable that is not defined
 until a certain package is loaded, you should put the call to `add-to-list'
 into a hook function that will be run only after loading the package.
@@ -755,30 +657,66 @@ FILE should be the name of a library, with no directory name."
 \f
 ;;;; Input and display facilities.
 
+(defvar read-quoted-char-radix 8
+  "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
+Legitimate radix values are 8, 10 and 16.")
+
+(custom-declare-variable-early
+ 'read-quoted-char-radix 8 
+ "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
+Legitimate radix values are 8, 10 and 16."
+  :type '(choice (const 8) (const 10) (const 16))
+  :group 'editing-basics)
+
 (defun read-quoted-char (&optional prompt)
-  "Like `read-char', except that if the first character read is an octal
-digit, we read up to two more octal digits and return the character
-represented by the octal number consisting of those digits.
-Optional argument PROMPT specifies a string to use to prompt the user."
-  (let ((message-log-max nil) (count 0) (code 0) char)
-    (while (< count 3)
-      (let ((inhibit-quit (zerop count))
-           (help-form nil))
+  "Like `read-char', but do not allow quitting.
+Also, if the first character read is an octal digit,
+we read any number of octal digits and return the
+soecified character code.  Any nondigit terminates the sequence.
+If the terminator is RET, it is discarded;
+any other terminator is used itself as input.
+
+The optional argument PROMPT specifies a string to use to prompt the user."
+  (let ((message-log-max nil) done (first t) (code 0) char)
+    (while (not done)
+      (let ((inhibit-quit first)
+           ;; Don't let C-h get the help message--only help function keys.
+           (help-char nil)
+           (help-form
+            "Type the special character you want to use,
+or the octal character code.
+RET terminates the character code and is discarded;
+any other non-digit terminates the character code and is then used as input."))
        (and prompt (message "%s-" prompt))
-       (setq char (read-char))
+       (setq char (read-event))
        (if inhibit-quit (setq quit-flag nil)))
+      ;; Translate TAB key into control-I ASCII character, and so on.
+      (and char
+          (let ((translated (lookup-key function-key-map (vector char))))
+            (if translated
+                (setq char (aref translated 0)))))
       (cond ((null char))
-           ((and (<= ?0 char) (<= char ?7))
-            (setq code (+ (* code 8) (- char ?0))
-                  count (1+ count))
-            (and prompt (message (setq prompt
-                                       (format "%s %c" prompt char)))))
-           ((> count 0)
-            (setq unread-command-events (list char) count 259))
-           (t (setq code char count 259))))
+           ((not (integerp char))
+            (setq unread-command-events (list char)
+                  done t))
+           ((and (<= ?0 char) (< char (+ ?0 (min 10 read-quoted-char-radix))))
+            (setq code (+ (* code read-quoted-char-radix) (- char ?0)))
+            (and prompt (setq prompt (message "%s %c" prompt char))))
+           ((and (<= ?a (downcase char))
+                 (< (downcase char) (+ ?a -10 (min 26 read-quoted-char-radix))))
+            (setq code (+ (* code read-quoted-char-radix) (+ 10 (- char ?a))))
+            (and prompt (setq prompt (message "%s %c" prompt char))))
+           ((and (not first) (eq char ?\C-m))
+            (setq done t))
+           ((not first)
+            (setq unread-command-events (list char)
+                  done t))
+           (t (setq code char
+                    done t)))
+      (setq first nil))
     ;; Turn a meta-character into a character with the 0200 bit set.
     (logior (if (/= (logand code ?\M-\^@) 0) 128 0)
-           (logand 255 code))))
+           code)))
 
 (defun force-mode-line-update (&optional all)
   "Force the mode-line of the current buffer to be redisplayed.
@@ -844,6 +782,17 @@ This variable is meaningful on MS-DOG and Windows NT.
 On those systems, it is automatically local in every buffer.
 On other systems, this variable is normally always nil.")
 
+;; This should probably be written in C (i.e., without using `walk-windows').
+(defun get-buffer-window-list (buffer &optional minibuf frame)
+  "Return windows currently displaying BUFFER, or nil if none.
+See `walk-windows' for the meaning of MINIBUF and FRAME."
+  (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows)
+    (walk-windows (function (lambda (window)
+                             (if (eq (window-buffer window) buffer)
+                                 (setq windows (cons window windows)))))
+                 minibuf frame)
+    windows))
+
 (defun ignore (&rest ignore)
   "Do nothing and return nil.
 This function accepts any number of arguments, but ignores them."
@@ -851,7 +800,10 @@ This function accepts any number of arguments, but ignores them."
   nil)
 
 (defun error (&rest args)
-  "Signal an error, making error message by passing all args to `format'."
+  "Signal an error, making error message by passing all args to `format'.
+In Emacs, the convention is that error messages start with a capital
+letter but *do not* end with a period.  Please follow this convention
+for the sake of consistency."
   (while t
     (signal 'error (list (apply 'format args)))))
 
@@ -877,61 +829,182 @@ Wildcards and redirection are handled as usual in the shell."
    (t
     (start-process name buffer shell-file-name shell-command-switch
                   (mapconcat 'identity args " ")))))
+\f
+(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'.
+See also `with-temp-file' and `with-output-to-string'."
+  (let ((temp-buffer (make-symbol "temp-buffer")))
+    `(let ((,temp-buffer
+           (get-buffer-create (generate-new-buffer-name " *temp*"))))
+       (unwind-protect
+          (with-current-buffer ,temp-buffer
+            ,@forms)
+        (and (buffer-name ,temp-buffer)
+             (kill-buffer ,temp-buffer))))))
+
+(defmacro with-output-to-string (&rest body)
+  "Execute BODY, return the text it sent to `standard-output', as a string."
+  `(let ((standard-output
+         (get-buffer-create (generate-new-buffer-name " *string-output*"))))
+     (let ((standard-output standard-output))
+       ,@body)
+     (with-current-buffer standard-output
+       (prog1
+          (buffer-string)
+        (kill-buffer nil)))))
+
+(defmacro combine-after-change-calls (&rest body)
+  "Execute BODY, but don't call the after-change functions till the end.
+If BODY makes changes in the buffer, they are recorded
+and the functions on `after-change-functions' are called several times
+when BODY is finished.
+The return value is the value of the last form in BODY.
+
+If `before-change-functions' is non-nil, then calls to the after-change
+functions can't be deferred, so in that case this macro has no effect.
+
+Do not alter `after-change-functions' or `before-change-functions'
+in BODY."
+  `(unwind-protect
+       (let ((combine-after-change-calls t))
+        . ,body)
+     (combine-after-change-execute)))
+
+\f
+(defvar save-match-data-internal)
 
+;; We use save-match-data-internal as the local variable because
+;; that works ok in practice (people should not use that variable elsewhere).
+;; We used to use an uninterned symbol; the compiler handles that properly
+;; now, but it generates slower code.
 (defmacro save-match-data (&rest body)
   "Execute the BODY forms, restoring the global value of the match data."
-  (let ((original (make-symbol "match-data")))
-    (list
-     'let (list (list original '(match-data)))
-     (list 'unwind-protect
-           (cons 'progn body)
-           (list 'store-match-data original)))))
-
-(defun match-string (n &optional string)
-  "Return the Nth subexpression matched by the last regexp search or match.
-If the last search or match was done against a string,
-specify that string as the second argument STRING."
-  (if string
-      (substring string (match-beginning n) (match-end n))
-    (buffer-substring (match-beginning n) (match-end n))))
-
+  `(let ((save-match-data-internal (match-data)))
+       (unwind-protect
+          (progn ,@body)
+        (store-match-data save-match-data-internal))))
+
+(defun match-string (num &optional string)
+  "Return string of text matched by last search.
+NUM specifies which parenthesized expression in the last regexp.
+ Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
+Zero means the entire text matched by the whole regexp or whole string.
+STRING should be given if the last search was by `string-match' on STRING."
+  (if (match-beginning num)
+      (if string
+         (substring string (match-beginning num) (match-end num))
+       (buffer-substring (match-beginning num) (match-end num)))))
+
+(defun split-string (string &optional separators)
+  "Splits STRING into substrings where there are matches for SEPARATORS.
+Each match for SEPARATORS is a splitting point.
+The substrings between the splitting points are made into a list
+which is returned.
+If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
+  (let ((rexp (or separators "[ \f\t\n\r\v]+"))
+       (start 0)
+       (list nil))
+    (while (string-match rexp string start)
+      (or (eq (match-beginning 0) 0)
+         (setq list
+               (cons (substring string start (match-beginning 0))
+                     list)))
+      (setq start (match-end 0)))
+    (or (eq start (length string))
+       (setq list
+             (cons (substring string start)
+                   list)))
+    (nreverse list)))
+\f
 (defun shell-quote-argument (argument)
   "Quote an argument for passing as argument to an inferior shell."
-  ;; Quote everything except POSIX filename characters.
-  ;; This should be safe enough even for really weird shells.
-  (let ((result "") (start 0) end)
-    (while (string-match "[^-0-9a-zA-Z_./]" argument start)
-      (setq end (match-beginning 0)
-           result (concat result (substring argument start end)
-                          "\\" (substring argument end (1+ end)))
-           start (1+ end)))
-    (concat result (substring argument start))))
+  (if (eq system-type 'ms-dos)
+      ;; MS-DOS shells don't have quoting, so don't do any.
+      argument
+    (if (eq system-type 'windows-nt)
+       (concat "\"" argument "\"")
+      (if (equal argument "")
+         "''"
+       ;; Quote everything except POSIX filename characters.
+       ;; This should be safe enough even for really weird shells.
+       (let ((result "") (start 0) end)
+         (while (string-match "[^-0-9a-zA-Z_./]" argument start)
+           (setq end (match-beginning 0)
+                 result (concat result (substring argument start end)
+                                "\\" (substring argument end (1+ end)))
+                 start (1+ end)))
+         (concat result (substring argument start)))))))
 
 (defun make-syntax-table (&optional oldtable)
   "Return a new syntax table.
-It inherits all letters and control characters from the standard
-syntax table; other characters are copied from the standard syntax table."
+If OLDTABLE is non-nil, copy OLDTABLE.
+Otherwise, create a syntax table which inherits
+all letters and control characters from the standard syntax table;
+other characters are copied from the standard syntax table."
   (if oldtable
       (copy-syntax-table oldtable)
     (let ((table (copy-syntax-table))
          i)
       (setq i 0)
       (while (<= i 31)
-       (aset table i 13)
+       (aset table i nil)
        (setq i (1+ i)))
       (setq i ?A)
       (while (<= i ?Z)
-       (aset table i 13)
+       (aset table i nil)
        (setq i (1+ i)))
       (setq i ?a)
       (while (<= i ?z)
-       (aset table i 13)
+       (aset table i nil)
        (setq i (1+ i)))
       (setq i 128)
       (while (<= i 255)
-       (aset table i 13)
+       (aset table i nil)
        (setq i (1+ i)))
       table)))
+
+(defun add-to-invisibility-spec (arg)
+  "Add elements to `buffer-invisibility-spec'.
+See documentation for `buffer-invisibility-spec' for the kind of elements
+that can be added."
+  (cond
+   ((or (null buffer-invisibility-spec) (eq buffer-invisibility-spec t))
+       (setq buffer-invisibility-spec (list arg)))
+   (t
+    (setq buffer-invisibility-spec
+         (cons arg buffer-invisibility-spec)))))
+
+(defun remove-from-invisibility-spec (arg)
+  "Remove elements from `buffer-invisibility-spec'."
+  (if buffer-invisibility-spec
+    (setq buffer-invisibility-spec (delete arg buffer-invisibility-spec))))
 \f
 (defun global-set-key (key command)
   "Give KEY a global binding as COMMAND.
@@ -978,6 +1051,21 @@ KEY is a string representing a sequence of keystrokes."
       (local-set-key key nil))
   nil)
 \f
+;; We put this here instead of in frame.el so that it's defined even on
+;; systems where frame.el isn't loaded.
+(defun frame-configuration-p (object)
+  "Return non-nil if OBJECT seems to be a frame configuration.
+Any list whose car is `frame-configuration' is assumed to be a frame
+configuration."
+  (and (consp object)
+       (eq (car object) 'frame-configuration)))
+
+(defun functionp (object)
+  "Non-nil if OBJECT is a type of object that can be called as a function."
+  (or (subrp object) (compiled-function-p object)
+      (eq (car-safe object) 'lambda)
+      (and (symbolp object) (fboundp object))))
+
 ;; now in fns.c
 ;(defun nth (n list)
 ;  "Returns the Nth element of LIST.
@@ -999,4 +1087,3 @@ KEY is a string representing a sequence of keystrokes."
 ;  alist)
 
 ;;; subr.el ends here
-