changeset 51349:dd8d7c8c6ae8

Moved from lisp/.
author Juanma Barranquero <lekktu@gmail.com>
date Fri, 30 May 2003 23:31:15 +0000
parents ae6bdfe1f4ce
children d555ff64edde
files lisp/emacs-lisp/byte-run.el lisp/emacs-lisp/derived.el lisp/emacs-lisp/float-sup.el lisp/emacs-lisp/map-ynp.el lisp/emacs-lisp/regi.el lisp/emacs-lisp/timer.el lisp/emacs-lisp/warnings.el lisp/progmodes/which-func.el lisp/textmodes/enriched.el
diffstat 9 files changed, 2713 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/emacs-lisp/byte-run.el	Fri May 30 23:31:15 2003 +0000
@@ -0,0 +1,172 @@
+;;; byte-run.el --- byte-compiler support for inlining
+
+;; Copyright (C) 1992 Free Software Foundation, Inc.
+
+;; Author: Jamie Zawinski <jwz@lucid.com>
+;;	Hallvard Furuseth <hbf@ulrik.uio.no>
+;; Maintainer: FSF
+;; Keywords: internal
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; interface to selectively inlining functions.
+;; This only happens when source-code optimization is turned on.
+
+;;; Code:
+
+;; Redefined in byte-optimize.el.
+;; This is not documented--it's not clear that we should promote it.
+(fset 'inline 'progn)
+(put 'inline 'lisp-indent-hook 0)
+
+
+;;; Interface to inline functions.
+
+;; (defmacro proclaim-inline (&rest fns)
+;;   "Cause the named functions to be open-coded when called from compiled code.
+;; They will only be compiled open-coded when byte-compile-optimize is true."
+;;   (cons 'eval-and-compile
+;; 	(mapcar '(lambda (x)
+;; 		   (or (memq (get x 'byte-optimizer)
+;; 			     '(nil byte-compile-inline-expand))
+;; 		       (error
+;; 			"%s already has a byte-optimizer, can't make it inline"
+;; 			x))
+;; 		   (list 'put (list 'quote x)
+;; 			 ''byte-optimizer ''byte-compile-inline-expand))
+;; 		fns)))
+
+;; (defmacro proclaim-notinline (&rest fns)
+;;   "Cause the named functions to no longer be open-coded."
+;;   (cons 'eval-and-compile
+;; 	(mapcar '(lambda (x)
+;; 		   (if (eq (get x 'byte-optimizer) 'byte-compile-inline-expand)
+;; 		       (put x 'byte-optimizer nil))
+;; 		   (list 'if (list 'eq (list 'get (list 'quote x) ''byte-optimizer)
+;; 				   ''byte-compile-inline-expand)
+;; 			 (list 'put x ''byte-optimizer nil)))
+;; 		fns)))
+
+;; This has a special byte-hunk-handler in bytecomp.el.
+(defmacro defsubst (name arglist &rest body)
+  "Define an inline function.  The syntax is just like that of `defun'."
+  (or (memq (get name 'byte-optimizer)
+	    '(nil byte-compile-inline-expand))
+      (error "`%s' is a primitive" name))
+  (list 'prog1
+	(cons 'defun (cons name (cons arglist body)))
+	(list 'eval-and-compile
+	      (list 'put (list 'quote name)
+		    ''byte-optimizer ''byte-compile-inline-expand))))
+
+(defun make-obsolete (fn new &optional when)
+  "Make the byte-compiler warn that FUNCTION is obsolete.
+The warning will say that NEW should be used instead.
+If NEW is a string, that is the `use instead' message.
+If provided, WHEN should be a string indicating when the function
+was first made obsolete, for example a date or a release number."
+  (interactive "aMake function obsolete: \nxObsoletion replacement: ")
+  (let ((handler (get fn 'byte-compile)))
+    (if (eq 'byte-compile-obsolete handler)
+	(setq handler (nth 1 (get fn 'byte-obsolete-info)))
+      (put fn 'byte-compile 'byte-compile-obsolete))
+    (put fn 'byte-obsolete-info (list new handler when)))
+  fn)
+
+(defun make-obsolete-variable (var new &optional when)
+  "Make the byte-compiler warn that VARIABLE is obsolete,
+and NEW should be used instead.  If NEW is a string, then that is the
+`use instead' message.
+If provided, WHEN should be a string indicating when the variable
+was first made obsolete, for example a date or a release number."
+  (interactive
+   (list
+    (let ((str (completing-read "Make variable obsolete: " obarray 'boundp t)))
+      (if (equal str "") (error ""))
+      (intern str))
+    (car (read-from-string (read-string "Obsoletion replacement: ")))))
+  (put var 'byte-obsolete-variable (cons new when))
+  var)
+
+(put 'dont-compile 'lisp-indent-hook 0)
+(defmacro dont-compile (&rest body)
+  "Like `progn', but the body always runs interpreted (not compiled).
+If you think you need this, you're probably making a mistake somewhere."
+  (list 'eval (list 'quote (if (cdr body) (cons 'progn body) (car body)))))
+
+
+;;; interface to evaluating things at compile time and/or load time
+;;; these macro must come after any uses of them in this file, as their
+;;; definition in the file overrides the magic definitions on the
+;;; byte-compile-macro-environment.
+
+(put 'eval-when-compile 'lisp-indent-hook 0)
+(defmacro eval-when-compile (&rest body)
+  "Like `progn', but evaluates the body at compile time.
+The result of the body appears to the compiler as a quoted constant."
+  ;; Not necessary because we have it in b-c-initial-macro-environment
+  ;; (list 'quote (eval (cons 'progn body)))
+  (cons 'progn body))
+
+(put 'eval-and-compile 'lisp-indent-hook 0)
+(defmacro eval-and-compile (&rest body)
+  "Like `progn', but evaluates the body at compile time and at load time."
+  ;; Remember, it's magic.
+  (cons 'progn body))
+
+(defun with-no-warnings (&optional first &rest body)
+  "Like `progn', but prevents compiler warnings in the body."
+  ;; The implementation for the interpreter is basically trivial.
+  (if body (car (last body))
+    first))
+
+
+;;; I nuked this because it's not a good idea for users to think of using it.
+;;; These options are a matter of installation preference, and have nothing to
+;;; with particular source files; it's a mistake to suggest to users
+;;; they should associate these with particular source files.
+;;; There is hardly any reason to change these parameters, anyway.
+;;; --rms.
+
+;; (put 'byte-compiler-options 'lisp-indent-hook 0)
+;; (defmacro byte-compiler-options (&rest args)
+;;   "Set some compilation-parameters for this file.  This will affect only the
+;; file in which it appears; this does nothing when evaluated, and when loaded
+;; from a .el file.
+;;
+;; Each argument to this macro must be a list of a key and a value.
+;;
+;;   Keys:		  Values:		Corresponding variable:
+;;
+;;   verbose	  t, nil		byte-compile-verbose
+;;   optimize	  t, nil, source, byte	byte-compile-optimize
+;;   warnings	  list of warnings	byte-compile-warnings
+;; 		      Legal elements: (callargs redefine free-vars unresolved)
+;;   file-format	  emacs18, emacs19	byte-compile-compatibility
+;;
+;; For example, this might appear at the top of a source file:
+;;
+;;     (byte-compiler-options
+;;       (optimize t)
+;;       (warnings (- free-vars))		; Don't warn about free variables
+;;       (file-format emacs19))"
+;;   nil)
+
+;;; byte-run.el ends here
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/emacs-lisp/derived.el	Fri May 30 23:31:15 2003 +0000
@@ -0,0 +1,436 @@
+;;; derived.el --- allow inheritance of major modes
+;;; (formerly mode-clone.el)
+
+;; Copyright (C) 1993, 1994, 1999, 2003 Free Software Foundation, Inc.
+
+;; Author: David Megginson (dmeggins@aix1.uottawa.ca)
+;; Maintainer: FSF
+;; Keywords: extensions
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; GNU Emacs is already, in a sense, object oriented -- each object
+;; (buffer) belongs to a class (major mode), and that class defines
+;; the relationship between messages (input events) and methods
+;; (commands) by means of a keymap.
+;;
+;; The only thing missing is a good scheme of inheritance.  It is
+;; possible to simulate a single level of inheritance with generous
+;; use of hooks and a bit of work -- sgml-mode, for example, also runs
+;; the hooks for text-mode, and keymaps can inherit from other keymaps
+;; -- but generally, each major mode ends up reinventing the wheel.
+;; Ideally, someone should redesign all of Emacs's major modes to
+;; follow a more conventional object-oriented system: when defining a
+;; new major mode, the user should need only to name the existing mode
+;; it is most similar to, then list the (few) differences.
+;;
+;; In the mean time, this package offers most of the advantages of
+;; full inheritance with the existing major modes.  The macro
+;; `define-derived-mode' allows the user to make a variant of an existing
+;; major mode, with its own keymap.  The new mode will inherit the key
+;; bindings of its parent, and will, in fact, run its parent first
+;; every time it is called.  For example, the commands
+;;
+;;  (define-derived-mode hypertext-mode text-mode "Hypertext"
+;;    "Major mode for hypertext.\n\n\\{hypertext-mode-map}"
+;;    (setq case-fold-search nil))
+;;
+;;  (define-key hypertext-mode-map [down-mouse-3] 'do-hyper-link)
+;;
+;; will create a function `hypertext-mode' with its own (sparse)
+;; keymap `hypertext-mode-map.'  The command M-x hypertext-mode will
+;; perform the following actions:
+;;
+;; - run the command (text-mode) to get its default setup
+;; - replace the current keymap with 'hypertext-mode-map,' which will
+;;   inherit from 'text-mode-map'.
+;; - replace the current syntax table with
+;;   'hypertext-mode-syntax-table', which will borrow its defaults
+;;   from the current text-mode-syntax-table.
+;; - replace the current abbrev table with
+;;   'hypertext-mode-abbrev-table', which will borrow its defaults
+;;   from the current text-mode-abbrev table
+;; - change the mode line to read "Hypertext"
+;; - assign the value 'hypertext-mode' to the 'major-mode' variable
+;; - run the body of commands provided in the macro -- in this case,
+;;   set the local variable `case-fold-search' to nil.
+;;
+;; The advantages of this system are threefold.  First, text mode is
+;; untouched -- if you had added the new keystroke to `text-mode-map,'
+;; possibly using hooks, you would have added it to all text buffers
+;; -- here, it appears only in hypertext buffers, where it makes
+;; sense.  Second, it is possible to build even further, and make
+;; a derived mode from a derived mode.  The commands
+;;
+;;   (define-derived-mode html-mode hypertext-mode "HTML")
+;;   [various key definitions]
+;;
+;; will add a new major mode for HTML with very little fuss.
+;;
+;; Note also the function `derived-mode-p' which can tell if the current
+;; mode derives from another.  In a hypertext-mode, buffer, for example,
+;; (derived-mode-p 'text-mode) would return non-nil.  This should always
+;; be used in place of (eq major-mode 'text-mode).
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+;;; PRIVATE: defsubst must be defined before they are first used
+
+(defsubst derived-mode-hook-name (mode)
+  "Construct the mode hook name based on mode name MODE."
+  (intern (concat (symbol-name mode) "-hook")))
+
+(defsubst derived-mode-map-name (mode)
+  "Construct a map name based on a MODE name."
+  (intern (concat (symbol-name mode) "-map")))
+
+(defsubst derived-mode-syntax-table-name (mode)
+  "Construct a syntax-table name based on a MODE name."
+  (intern (concat (symbol-name mode) "-syntax-table")))
+
+(defsubst derived-mode-abbrev-table-name (mode)
+  "Construct an abbrev-table name based on a MODE name."
+  (intern (concat (symbol-name mode) "-abbrev-table")))
+
+;; PUBLIC: define a new major mode which inherits from an existing one.
+
+;;;###autoload
+(defmacro define-derived-mode (child parent name &optional docstring &rest body)
+  "Create a new mode as a variant of an existing mode.
+
+The arguments to this command are as follow:
+
+CHILD:     the name of the command for the derived mode.
+PARENT:    the name of the command for the parent mode (e.g. `text-mode')
+           or nil if there is no parent.
+NAME:      a string which will appear in the status line (e.g. \"Hypertext\")
+DOCSTRING: an optional documentation string--if you do not supply one,
+           the function will attempt to invent something useful.
+BODY:      forms to execute just before running the
+           hooks for the new mode.  Do not use `interactive' here.
+
+BODY can start with a bunch of keyword arguments.  The following keyword
+  arguments are currently understood:
+:group GROUP
+	Declare the customization group that corresponds to this mode.
+:syntax-table TABLE
+	Use TABLE instead of the default.
+	A nil value means to simply use the same syntax-table as the parent.
+:abbrev-table TABLE
+	Use TABLE instead of the default.
+	A nil value means to simply use the same abbrev-table as the parent.
+
+Here is how you could define LaTeX-Thesis mode as a variant of LaTeX mode:
+
+  (define-derived-mode LaTeX-thesis-mode LaTeX-mode \"LaTeX-Thesis\")
+
+You could then make new key bindings for `LaTeX-thesis-mode-map'
+without changing regular LaTeX mode.  In this example, BODY is empty,
+and DOCSTRING is generated by default.
+
+On a more complicated level, the following command uses `sgml-mode' as
+the parent, and then sets the variable `case-fold-search' to nil:
+
+  (define-derived-mode article-mode sgml-mode \"Article\"
+    \"Major mode for editing technical articles.\"
+    (setq case-fold-search nil))
+
+Note that if the documentation string had been left out, it would have
+been generated automatically, with a reference to the keymap."
+  (declare (debug (&define name symbolp sexp [&optional stringp]
+			   [&rest keywordp sexp] def-body)))
+
+  (when (and docstring (not (stringp docstring)))
+    ;; Some trickiness, since what appears to be the docstring may really be
+    ;; the first element of the body.
+    (push docstring body)
+    (setq docstring nil))
+
+  (when (eq parent 'fundamental-mode) (setq parent nil))
+
+  (let ((map (derived-mode-map-name child))
+	(syntax (derived-mode-syntax-table-name child))
+	(abbrev (derived-mode-abbrev-table-name child))
+	(declare-abbrev t)
+	(declare-syntax t)
+	(hook (derived-mode-hook-name child))
+	(group nil))
+
+    ;; Process the keyword args.
+    (while (keywordp (car body))
+      (case (pop body)
+	(:group (setq group (pop body)))
+	(:abbrev-table (setq abbrev (pop body)) (setq declare-abbrev nil))
+	(:syntax-table (setq syntax (pop body)) (setq declare-syntax nil))
+	(t (pop body))))
+
+    (setq docstring (derived-mode-make-docstring
+		     parent child docstring syntax abbrev))
+
+    `(progn
+       (defvar ,map (make-sparse-keymap))
+       ,(if declare-syntax
+	    `(defvar ,syntax (make-syntax-table)))
+       ,(if declare-abbrev
+	    `(defvar ,abbrev
+	       (progn (define-abbrev-table ',abbrev nil) ,abbrev)))
+       (put ',child 'derived-mode-parent ',parent)
+       ,(if group `(put ',child 'custom-mode-group ,group))
+
+       (defun ,child ()
+	 ,docstring
+	 (interactive)
+					; Run the parent.
+	 (delay-mode-hooks
+
+	  (,(or parent 'kill-all-local-variables))
+					; Identify the child mode.
+	  (setq major-mode (quote ,child))
+	  (setq mode-name ,name)
+					; Identify special modes.
+	  ,(when parent
+	     `(progn
+		(if (get (quote ,parent) 'mode-class)
+		    (put (quote ,child) 'mode-class
+			 (get (quote ,parent) 'mode-class)))
+					; Set up maps and tables.
+		(unless (keymap-parent ,map)
+		  (set-keymap-parent ,map (current-local-map)))
+		,(when declare-syntax
+		   `(let ((parent (char-table-parent ,syntax)))
+		      (unless (and parent
+				   (not (eq parent (standard-syntax-table))))
+			(set-char-table-parent ,syntax (syntax-table)))))))
+
+	  (use-local-map ,map)
+	  ,(when syntax `(set-syntax-table ,syntax))
+	  ,(when abbrev `(setq local-abbrev-table ,abbrev))
+					; Splice in the body (if any).
+	  ,@body
+	  )
+	 ;; Run the hooks, if any.
+	 ;; Make the generated code work in older Emacs versions
+	 ;; that do not yet have run-mode-hooks.
+	 (if (fboundp 'run-mode-hooks)
+	     (run-mode-hooks ',hook)
+	   (run-hooks ',hook))))))
+
+;; PUBLIC: find the ultimate class of a derived mode.
+
+(defun derived-mode-class (mode)
+  "Find the class of a major MODE.
+A mode's class is the first ancestor which is NOT a derived mode.
+Use the `derived-mode-parent' property of the symbol to trace backwards.
+Since major-modes might all derive from `fundamental-mode', this function
+is not very useful."
+  (while (get mode 'derived-mode-parent)
+    (setq mode (get mode 'derived-mode-parent)))
+  mode)
+(make-obsolete 'derived-mode-class 'derived-mode-p "21.4")
+
+
+;;; PRIVATE
+
+(defun derived-mode-make-docstring (parent child &optional
+					   docstring syntax abbrev)
+  "Construct a docstring for a new mode if none is provided."
+
+  (let ((map (derived-mode-map-name child))
+	(hook (derived-mode-hook-name child)))
+
+    (unless (stringp docstring)
+      ;; Use a default docstring.
+      (setq docstring
+	    (if (null parent)
+		(format "Major-mode.
+Uses keymap `%s', abbrev table `%s' and syntax-table `%s'." map abbrev syntax)
+	      (format "Major mode derived from `%s' by `define-derived-mode'.
+It inherits all of the parent's attributes, but has its own keymap,
+abbrev table and syntax table:
+
+  `%s', `%s' and `%s'
+
+which more-or-less shadow %s's corresponding tables."
+		      parent map abbrev syntax parent))))
+
+    (unless (string-match (regexp-quote (symbol-name hook)) docstring)
+      ;; Make sure the docstring mentions the mode's hook.
+      (setq docstring
+	    (concat docstring
+		    (if (null parent)
+			"\n\nThis mode "
+		      (concat
+		       "\n\nIn addition to any hooks its parent mode "
+		       (if (string-match (regexp-quote (format "`%s'" parent))
+					 docstring) nil
+			 (format "`%s' " parent))
+		       "might have run,\nthis mode "))
+		    (format "runs the hook `%s'" hook)
+		    ", as the final step\nduring initialization.")))
+
+    (unless (string-match "\\\\[{[]" docstring)
+      ;; And don't forget to put the mode's keymap.
+      (setq docstring (concat docstring "\n\n\\{" (symbol-name map) "}")))
+
+    docstring))
+
+
+;;; OBSOLETE
+;; The functions below are only provided for backward compatibility with
+;; code byte-compiled with versions of derived.el prior to Emacs-21.
+
+(defsubst derived-mode-setup-function-name (mode)
+  "Construct a setup-function name based on a MODE name."
+  (intern (concat (symbol-name mode) "-setup")))
+
+
+;; Utility functions for defining a derived mode.
+
+;;;###autoload
+(defun derived-mode-init-mode-variables (mode)
+  "Initialise variables for a new MODE.
+Right now, if they don't already exist, set up a blank keymap, an
+empty syntax table, and an empty abbrev table -- these will be merged
+the first time the mode is used."
+
+  (if (boundp (derived-mode-map-name mode))
+      t
+    (eval `(defvar ,(derived-mode-map-name mode)
+	       (make-sparse-keymap)
+	       ,(format "Keymap for %s." mode)))
+    (put (derived-mode-map-name mode) 'derived-mode-unmerged t))
+
+  (if (boundp (derived-mode-syntax-table-name mode))
+      t
+    (eval `(defvar ,(derived-mode-syntax-table-name mode)
+	     ;; Make a syntax table which doesn't specify anything
+	     ;; for any char.  Valid data will be merged in by
+	     ;; derived-mode-merge-syntax-tables.
+	     (make-char-table 'syntax-table nil)
+	     ,(format "Syntax table for %s." mode)))
+    (put (derived-mode-syntax-table-name mode) 'derived-mode-unmerged t))
+
+  (if (boundp (derived-mode-abbrev-table-name mode))
+      t
+    (eval `(defvar ,(derived-mode-abbrev-table-name mode)
+	     (progn
+	       (define-abbrev-table (derived-mode-abbrev-table-name mode) nil)
+	       (make-abbrev-table))
+	     ,(format "Abbrev table for %s." mode)))))
+
+;; Utility functions for running a derived mode.
+
+(defun derived-mode-set-keymap (mode)
+  "Set the keymap of the new MODE, maybe merging with the parent."
+  (let* ((map-name (derived-mode-map-name mode))
+	 (new-map (eval map-name))
+	 (old-map (current-local-map)))
+    (and old-map
+	 (get map-name 'derived-mode-unmerged)
+	 (derived-mode-merge-keymaps old-map new-map))
+    (put map-name 'derived-mode-unmerged nil)
+    (use-local-map new-map)))
+
+(defun derived-mode-set-syntax-table (mode)
+  "Set the syntax table of the new MODE, maybe merging with the parent."
+  (let* ((table-name (derived-mode-syntax-table-name mode))
+	 (old-table (syntax-table))
+	 (new-table (eval table-name)))
+    (if (get table-name 'derived-mode-unmerged)
+	(derived-mode-merge-syntax-tables old-table new-table))
+    (put table-name 'derived-mode-unmerged nil)
+    (set-syntax-table new-table)))
+
+(defun derived-mode-set-abbrev-table (mode)
+  "Set the abbrev table for MODE if it exists.
+Always merge its parent into it, since the merge is non-destructive."
+  (let* ((table-name (derived-mode-abbrev-table-name mode))
+	 (old-table local-abbrev-table)
+	 (new-table (eval table-name)))
+    (derived-mode-merge-abbrev-tables old-table new-table)
+    (setq local-abbrev-table new-table)))
+
+;;;(defun derived-mode-run-setup-function (mode)
+;;;  "Run the setup function if it exists."
+
+;;;  (let ((fname (derived-mode-setup-function-name mode)))
+;;;    (if (fboundp fname)
+;;;	(funcall fname))))
+
+(defun derived-mode-run-hooks (mode)
+  "Run the mode hook for MODE."
+  (let ((hooks-name (derived-mode-hook-name mode)))
+    (if (boundp hooks-name)
+	(run-hooks hooks-name))))
+
+;; Functions to merge maps and tables.
+
+(defun derived-mode-merge-keymaps (old new)
+  "Merge an OLD keymap into a NEW one.
+The old keymap is set to be the last cdr of the new one, so that there will
+be automatic inheritance."
+  ;; ?? Can this just use `set-keymap-parent'?
+  (let ((tail new))
+    ;; Scan the NEW map for prefix keys.
+    (while (consp tail)
+      (and (consp (car tail))
+	   (let* ((key (vector (car (car tail))))
+		  (subnew (lookup-key new key))
+		  (subold (lookup-key old key)))
+	     ;; If KEY is a prefix key in both OLD and NEW, merge them.
+	     (and (keymapp subnew) (keymapp subold)
+		  (derived-mode-merge-keymaps subold subnew))))
+      (and (vectorp (car tail))
+	   ;; Search a vector of ASCII char bindings for prefix keys.
+	   (let ((i (1- (length (car tail)))))
+	     (while (>= i 0)
+	       (let* ((key (vector i))
+		      (subnew (lookup-key new key))
+		      (subold (lookup-key old key)))
+		 ;; If KEY is a prefix key in both OLD and NEW, merge them.
+		 (and (keymapp subnew) (keymapp subold)
+		      (derived-mode-merge-keymaps subold subnew)))
+	       (setq i (1- i)))))
+      (setq tail (cdr tail))))
+  (setcdr (nthcdr (1- (length new)) new) old))
+
+(defun derived-mode-merge-syntax-tables (old new)
+  "Merge an OLD syntax table into a NEW one.
+Where the new table already has an entry, nothing is copied from the old one."
+  (set-char-table-parent new old))
+
+;; Merge an old abbrev table into a new one.
+;; This function requires internal knowledge of how abbrev tables work,
+;; presuming that they are obarrays with the abbrev as the symbol, the expansion
+;; as the value of the symbol, and the hook as the function definition.
+(defun derived-mode-merge-abbrev-tables (old new)
+  (if old
+      (mapatoms
+       (lambda (symbol)
+	 (or (intern-soft (symbol-name symbol) new)
+	     (define-abbrev new (symbol-name symbol)
+	       (symbol-value symbol) (symbol-function symbol))))
+       old)))
+
+(provide 'derived)
+
+;;; derived.el ends here
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/emacs-lisp/float-sup.el	Fri May 30 23:31:15 2003 +0000
@@ -0,0 +1,63 @@
+;;; float-sup.el --- define some constants useful for floating point numbers.
+
+;; Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
+
+;; Maintainer: FSF
+;; Keywords: internal
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+;; Provide a meaningful error message if we are running on
+;; bare (non-float) emacs.
+
+(if (fboundp 'atan)
+    nil
+  (error "Floating point was disabled at compile time"))
+
+;; provide an easy hook to tell if we are running with floats or not.
+;; define pi and e via math-lib calls. (much less prone to killer typos.)
+(defconst pi (* 4 (atan 1)) "The value of Pi (3.1415926...).")
+;; It's too inconvenient to make `e' a constant because it's used as
+;; a temporary variable all the time.
+(defvar e (exp 1) "The value of e (2.7182818...).")
+
+;; Careful when editing this file ... typos here will be hard to spot.
+;; (defconst pi       3.14159265358979323846264338327
+;;  "The value of Pi (3.14159265358979323846264338327...)")
+
+(defconst degrees-to-radians (/ pi 180.0)
+  "Degrees to radian conversion constant.")
+(defconst radians-to-degrees (/ 180.0 pi)
+  "Radian to degree conversion constant.")
+
+;; these expand to a single multiply by a float when byte compiled
+
+(defmacro degrees-to-radians (x)
+  "Convert ARG from degrees to radians."
+  (list '* (/ pi 180.0) x))
+(defmacro radians-to-degrees (x)
+  "Convert ARG from radians to degrees."
+  (list '* (/ 180.0 pi) x))
+
+(provide 'lisp-float-type)
+
+;;; float-sup.el ends here
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/emacs-lisp/map-ynp.el	Fri May 30 23:31:15 2003 +0000
@@ -0,0 +1,264 @@
+;;; map-ynp.el --- general-purpose boolean question-asker
+
+;; Copyright (C) 1991, 1992, 1993, 1994, 1995, 2000 Free Software Foundation, Inc.
+
+;; Author: Roland McGrath <roland@gnu.org>
+;; Maintainer: FSF
+;; Keywords: lisp, extensions
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; map-y-or-n-p is a general-purpose question-asking function.
+;; It asks a series of y/n questions (a la y-or-n-p), and decides to
+;; apply an action to each element of a list based on the answer.
+;; The nice thing is that you also get some other possible answers
+;; to use, reminiscent of query-replace: ! to answer y to all remaining
+;; questions; ESC or q to answer n to all remaining questions; . to answer
+;; y once and then n for the remainder; and you can get help with C-h.
+
+;;; Code:
+
+(defun map-y-or-n-p (prompter actor list &optional help action-alist
+			      no-cursor-in-echo-area)
+  "Ask a series of boolean questions.
+Takes args PROMPTER ACTOR LIST, and optional args HELP and ACTION-ALIST.
+
+LIST is a list of objects, or a function of no arguments to return the next
+object or nil.
+
+If PROMPTER is a string, the prompt is \(format PROMPTER OBJECT\).  If not
+a string, PROMPTER is a function of one arg (an object from LIST), which
+returns a string to be used as the prompt for that object.  If the return
+value is not a string, it may be nil to ignore the object or non-nil to act
+on the object without asking the user.
+
+ACTOR is a function of one arg (an object from LIST),
+which gets called with each object that the user answers `yes' for.
+
+If HELP is given, it is a list (OBJECT OBJECTS ACTION),
+where OBJECT is a string giving the singular noun for an elt of LIST;
+OBJECTS is the plural noun for elts of LIST, and ACTION is a transitive
+verb describing ACTOR.  The default is \(\"object\" \"objects\" \"act on\"\).
+
+At the prompts, the user may enter y, Y, or SPC to act on that object;
+n, N, or DEL to skip that object; ! to act on all following objects;
+ESC or q to exit (skip all following objects); . (period) to act on the
+current object and then exit; or \\[help-command] to get help.
+
+If ACTION-ALIST is given, it is an alist (KEY FUNCTION HELP) of extra keys
+that will be accepted.  KEY is a character; FUNCTION is a function of one
+arg (an object from LIST); HELP is a string.  When the user hits KEY,
+FUNCTION is called.  If it returns non-nil, the object is considered
+\"acted upon\", and the next object from LIST is processed.  If it returns
+nil, the prompt is repeated for the same object.
+
+Final optional argument NO-CURSOR-IN-ECHO-AREA non-nil says not to set
+`cursor-in-echo-area' while prompting.
+
+This function uses `query-replace-map' to define the standard responses,
+but not all of the responses which `query-replace' understands
+are meaningful here.
+
+Returns the number of actions taken."
+  (let* ((actions 0)
+	 user-keys mouse-event map prompt char elt tail def
+	 ;; Non-nil means we should use mouse menus to ask.
+	 use-menus
+	 delayed-switch-frame
+	 (next (if (or (and list (symbolp list))
+		       (subrp list)
+		       (byte-code-function-p list)
+		       (and (consp list)
+			    (eq (car list) 'lambda)))
+		   (function (lambda ()
+			       (setq elt (funcall list))))
+		 (function (lambda ()
+			     (if list
+				 (progn
+				   (setq elt (car list)
+					 list (cdr list))
+				   t)
+			       nil))))))
+    (if (and (listp last-nonmenu-event)
+	     use-dialog-box)
+	;; Make a list describing a dialog box.
+	(let ((object (if help (capitalize (nth 0 help))))
+	      (objects (if help (capitalize (nth 1 help))))
+	      (action (if help (capitalize (nth 2 help)))))
+	  (setq map `(("Yes" . act) ("No" . skip) ("Quit" . exit)
+		      (,(if help (concat action " " object " And Quit")
+			  "Do it and Quit") . act-and-exit)
+		      (,(if help (concat action " All " objects)
+			  "Do All") . automatic)
+		      ,@(mapcar (lambda (elt)
+				  (cons (capitalize (nth 2 elt))
+					(vector (nth 1 elt))))
+				action-alist))
+		use-menus t
+		mouse-event last-nonmenu-event))
+      (setq user-keys (if action-alist
+			  (concat (mapconcat (function
+					      (lambda (elt)
+						(key-description
+						 (char-to-string (car elt)))))
+					     action-alist ", ")
+				  " ")
+			"")
+	    ;; Make a map that defines each user key as a vector containing
+	    ;; its definition.
+	    map (cons 'keymap
+		      (append (mapcar (lambda (elt)
+					(cons (car elt) (vector (nth 1 elt))))
+				      action-alist)
+			      query-replace-map))))
+    (unwind-protect
+	(progn
+	  (if (stringp prompter)
+	      (setq prompter `(lambda (object)
+				(format ,prompter object))))
+	  (while (funcall next)
+	    (setq prompt (funcall prompter elt))
+	    (cond ((stringp prompt)
+		   ;; Prompt the user about this object.
+		   (setq quit-flag nil)
+		   (if use-menus
+		       (setq def (or (x-popup-dialog (or mouse-event use-menus)
+						     (cons prompt map))
+				     'quit))
+		     ;; Prompt in the echo area.
+		     (let ((cursor-in-echo-area (not no-cursor-in-echo-area))
+			   (message-log-max nil))
+		       (message "%s(y, n, !, ., q, %sor %s) "
+				prompt user-keys
+				(key-description (vector help-char)))
+		       (if minibuffer-auto-raise
+			   (raise-frame (window-frame (minibuffer-window))))
+		       (while (progn
+				(setq char (read-event))
+				;; If we get -1, from end of keyboard
+				;; macro, try again.
+                                (equal char -1)))
+		       ;; Show the answer to the question.
+		       (message "%s(y, n, !, ., q, %sor %s) %s"
+				prompt user-keys
+				(key-description (vector help-char))
+				(single-key-description char)))
+		     (setq def (lookup-key map (vector char))))
+		   (cond ((eq def 'exit)
+			  (setq next (function (lambda () nil))))
+			 ((eq def 'act)
+			  ;; Act on the object.
+			  (funcall actor elt)
+			  (setq actions (1+ actions)))
+			 ((eq def 'skip)
+			  ;; Skip the object.
+			  )
+			 ((eq def 'act-and-exit)
+			  ;; Act on the object and then exit.
+			  (funcall actor elt)
+			  (setq actions (1+ actions)
+				next (function (lambda () nil))))
+			 ((eq def 'quit)
+			  (setq quit-flag t)
+			  (setq next `(lambda ()
+					(setq next ',next)
+					',elt)))
+			 ((eq def 'automatic)
+			  ;; Act on this and all following objects.
+			  (if (funcall prompter elt)
+			      (progn
+				(funcall actor elt)
+				(setq actions (1+ actions))))
+			  (while (funcall next)
+			    (if (funcall prompter elt)
+				(progn
+				  (funcall actor elt)
+				  (setq actions (1+ actions))))))
+			 ((eq def 'help)
+			  (with-output-to-temp-buffer "*Help*"
+			    (princ
+			     (let ((object (if help (nth 0 help) "object"))
+				   (objects (if help (nth 1 help) "objects"))
+				   (action (if help (nth 2 help) "act on")))
+			       (concat
+				(format "Type SPC or `y' to %s the current %s;
+DEL or `n' to skip the current %s;
+RET or `q' to exit (skip all remaining %s);
+C-g to quit (cancel the operation);
+! to %s all remaining %s;\n"
+					action object object objects action
+					objects)
+				(mapconcat (function
+					    (lambda (elt)
+					      (format "%s to %s"
+						      (single-key-description
+						       (nth 0 elt))
+						      (nth 2 elt))))
+					   action-alist
+					   ";\n")
+				(if action-alist ";\n")
+				(format "or . (period) to %s \
+the current %s and exit."
+					action object))))
+			    (save-excursion
+			      (set-buffer standard-output)
+			      (help-mode)))
+
+			  (setq next `(lambda ()
+				       (setq next ',next)
+				       ',elt)))
+			 ((vectorp def)
+			  ;; A user-defined key.
+			  (if (funcall (aref def 0) elt) ;Call its function.
+			      ;; The function has eaten this object.
+			      (setq actions (1+ actions))
+			    ;; Regurgitated; try again.
+			    (setq next `(lambda ()
+					 (setq next ',next)
+					 ',elt))))
+			 ((and (consp char)
+			       (eq (car char) 'switch-frame))
+			  ;; switch-frame event.  Put it off until we're done.
+			  (setq delayed-switch-frame char)
+			  (setq next `(lambda ()
+				       (setq next ',next)
+				       ',elt)))
+			 (t
+			  ;; Random char.
+			  (message "Type %s for help."
+				   (key-description (vector help-char)))
+			  (beep)
+			  (sit-for 1)
+			  (setq next `(lambda ()
+				       (setq next ',next)
+				       ',elt)))))
+		  (prompt
+		   (funcall actor elt)
+		   (setq actions (1+ actions))))))
+      (if delayed-switch-frame
+	  (setq unread-command-events
+		(cons delayed-switch-frame unread-command-events))))
+    ;; Clear the last prompt from the minibuffer.
+    (let ((message-log-max nil))
+      (message ""))
+    ;; Return the number of actions that were taken.
+    actions))
+
+;;; map-ynp.el ends here
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/emacs-lisp/regi.el	Fri May 30 23:31:15 2003 +0000
@@ -0,0 +1,258 @@
+;;; regi.el --- REGular expression Interpreting engine
+
+;; Copyright (C) 1993 Free Software Foundation, Inc.
+
+;; Author: 1993 Barry A. Warsaw, Century Computing, Inc. <bwarsaw@cen.com>
+;; Maintainer:    bwarsaw@cen.com
+;; Created:       24-Feb-1993
+;; Version:       1.8
+;; Last Modified: 1993/06/01 21:33:00
+;; Keywords:      extensions, matching
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+
+(defun regi-pos (&optional position col-p)
+  "Return the character position at various buffer positions.
+Optional POSITION can be one of the following symbols:
+
+`bol'  == beginning of line
+`boi'  == beginning of indentation
+`eol'  == end of line [default]
+`bonl' == beginning of next line
+`bopl' == beginning of previous line
+
+Optional COL-P non-nil returns `current-column' instead of character position."
+  (save-excursion
+    (cond
+     ((eq position 'bol)  (beginning-of-line))
+     ((eq position 'boi)  (back-to-indentation))
+     ((eq position 'bonl) (forward-line 1))
+     ((eq position 'bopl) (forward-line -1))
+     (t (end-of-line)))
+    (if col-p (current-column) (point))))
+
+(defun regi-mapcar (predlist func &optional negate-p case-fold-search-p)
+  "Build a regi frame where each element of PREDLIST appears exactly once.
+The frame contains elements where each member of PREDLIST is
+associated with FUNC, and optionally NEGATE-P and CASE-FOLD-SEARCH-P."
+  (let (frame tail)
+    (if (or negate-p case-fold-search-p)
+	(setq tail (list negate-p)))
+    (if case-fold-search-p
+	(setq tail (append tail (list case-fold-search-p))))
+    (while predlist
+      (let ((element (list (car predlist) func)))
+	(if tail
+	    (setq element (append element tail)))
+	(setq frame (append frame (list element))
+	      predlist (cdr predlist))
+	))
+    frame))
+
+
+(defun regi-interpret (frame &optional start end)
+  "Interpret the regi frame FRAME.
+If optional START and END are supplied, they indicate the region of
+interest, and the buffer is narrowed to the beginning of the line
+containing START, and beginning of the line after the line containing
+END.  Otherwise, point and mark are not set and processing continues
+until your FUNC returns the `abort' symbol (see below).  Beware!  Not
+supplying a START or END could put you in an infinite loop.
+
+A regi frame is a list of entries of the form:
+
+     (PRED FUNC [NEGATE-P [CASE-FOLD-SEARCH]])
+
+PRED is a predicate against which each line in the region is tested,
+and if a match occurs, FUNC is `eval'd.  Point is then moved to the
+beginning of the next line, the frame is reset and checking continues.
+If a match doesn't occur, the next entry is checked against the
+current line until all entries in the frame are checked.  At this
+point, if no match occurred, the frame is reset and point is moved to
+the next line.  Checking continues until every line in the region is
+checked.  Optional NEGATE-P inverts the result of PRED before FUNC is
+called and `case-fold-search' is bound to the optional value of
+CASE-FOLD-SEARCH for the PRED check.
+
+PRED can be a string, variable, function or one of the following
+symbols: t, nil, `begin', `end', and `every'.  If PRED is a string, or
+a variable or list that evaluates to a string, it is interpreted as a
+regular expression and is matched against the current line (from the
+beginning) using `looking-at'.  If PRED does not evaluate to a string,
+it is interpreted as a binary value (nil or non-nil).
+
+PRED can also be one of the following symbols:
+
+t       -- always produces a true outcome
+`begin' -- always executes before anything else
+`end'   -- always executes after everything else
+`every' -- execute after frame is matched on a line
+
+Note that NEGATE-P and CASE-FOLD-SEARCH are meaningless if PRED is one
+of these special symbols.  Only the first occurrence of each symbol in
+a frame entry is used, the rest are ignored.
+
+Your FUNC can return values which control regi processing.  If a list
+is returned from your function, it can contain any combination of the
+following elements:
+
+the symbol `continue'
+     Tells regi to continue processing frame-entries after a match,
+     instead of resetting to the first entry and advancing to the next
+     line, as is the default behavior.  When returning this symbol,
+     you must take care not to enter an infinite loop.
+
+the symbol `abort'
+     Tells regi to terminate processing this frame.  any end
+     frame-entry is still processed.
+
+the list `(frame . NEWFRAME)'
+     Tells regi to use NEWFRAME as its current frame.  In other words,
+     your FUNC can modify the executing regi frame on the fly.
+
+the list `(step . STEP)'
+     Tells regi to move STEP number of lines forward during normal
+     processing.  By default, regi moves forward 1 line.  STEP can be
+     negative, but be careful of infinite loops.
+
+You should usually take care to explicitly return nil from your
+function if no action is to take place.  Your FUNC will always be
+`eval'ed.  The following variables will be temporarily bound to some
+useful information:
+
+`curline'
+     the current line in the buffer, as a string
+
+`curframe'
+     the full, current frame being executed
+
+`curentry'
+     the current frame entry being executed."
+
+  (save-excursion
+    (save-restriction
+      (let (begin-tag end-tag every-tag current-frame working-frame donep)
+
+	;; set up the narrowed region
+	(and start
+	     end
+	     (let* ((tstart start)
+		    (start (min start end))
+		    (end   (max start end)))
+	       (narrow-to-region
+		(progn (goto-char end) (regi-pos 'bonl))
+		(progn (goto-char start) (regi-pos 'bol)))))
+
+	;; lets find the special tags and remove them from the working
+	;; frame. note that only the last special tag is used.
+	(mapcar
+	 (function
+	  (lambda (entry)
+	    (let ((pred (car entry))
+		  (func (car (cdr entry))))
+	      (cond
+	       ((eq pred 'begin) (setq begin-tag func))
+	       ((eq pred 'end)   (setq end-tag func))
+	       ((eq pred 'every) (setq every-tag func))
+	       (t
+		(setq working-frame (append working-frame (list entry))))
+	       ) ; end-cond
+	      )))
+	 frame) ; end-mapcar
+
+	;; execute the begin entry
+	(eval begin-tag)
+
+	;; now process the frame
+	(setq current-frame working-frame)
+	(while (not (or donep (eobp)))
+	  (let* ((entry            (car current-frame))
+		 (pred             (nth 0 entry))
+		 (func             (nth 1 entry))
+		 (negate-p         (nth 2 entry))
+		 (case-fold-search (nth 3 entry))
+		 match-p)
+	    (catch 'regi-throw-top
+	      (cond
+	       ;; we are finished processing the frame for this line
+	       ((not current-frame)
+		(setq current-frame working-frame) ;reset frame
+		(forward-line 1)
+		(throw 'regi-throw-top t))
+	       ;; see if predicate evaluates to a string
+	       ((stringp (setq match-p (eval pred)))
+		(setq match-p (looking-at match-p)))
+	       ) ; end-cond
+
+	      ;; now that we've done the initial matching, check for
+	      ;; negation of match
+	      (and negate-p
+		   (setq match-p (not match-p)))
+
+	      ;; if the line matched, package up the argument list and
+	      ;; funcall the FUNC
+	      (if match-p
+		   (let* ((curline (buffer-substring
+				    (regi-pos 'bol)
+				    (regi-pos 'eol)))
+			  (curframe current-frame)
+			  (curentry entry)
+			  (result (eval func))
+			  (step (or (cdr (assq 'step result)) 1))
+			  )
+		     ;; changing frame on the fly?
+		     (if (assq 'frame result)
+			 (setq working-frame (cdr (assq 'frame result))))
+
+		     ;; continue processing current frame?
+		     (if (memq 'continue result)
+			 (setq current-frame (cdr current-frame))
+		       (forward-line step)
+		       (setq current-frame working-frame))
+
+		     ;; abort current frame?
+		     (if (memq 'abort result)
+			 (progn
+			   (setq donep t)
+			   (throw 'regi-throw-top t)))
+		     ) ; end-let
+
+		;; else if no match occurred, then process the next
+		;; frame-entry on the current line
+		(setq current-frame (cdr current-frame))
+
+		) ; end-if match-p
+	      ) ; end catch
+	    ) ; end let
+
+	  ;; after every cycle, evaluate every-tag
+	  (eval every-tag)
+	  ) ; end-while
+
+	;; now process the end entry
+	(eval end-tag)))))
+
+
+(provide 'regi)
+
+;;; regi.el ends here
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/emacs-lisp/timer.el	Fri May 30 23:31:15 2003 +0000
@@ -0,0 +1,479 @@
+;;; timer.el --- run a function with args at some time in future
+
+;; Copyright (C) 1996 Free Software Foundation, Inc.
+
+;; Maintainer: FSF
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; This package gives you the capability to run Emacs Lisp commands at
+;; specified times in the future, either as one-shots or periodically.
+
+;;; Code:
+
+;; Layout of a timer vector:
+;; [triggered-p high-seconds low-seconds usecs repeat-delay
+;;  function args idle-delay]
+
+(defun timer-create ()
+  "Create a timer object."
+  (let ((timer (make-vector 8 nil)))
+    (aset timer 0 t)
+    timer))
+
+(defun timerp (object)
+  "Return t if OBJECT is a timer."
+  (and (vectorp object) (= (length object) 8)))
+
+(defun timer-set-time (timer time &optional delta)
+  "Set the trigger time of TIMER to TIME.
+TIME must be in the internal format returned by, e.g., `current-time'.
+If optional third argument DELTA is a positive number, make the timer
+fire repeatedly that many seconds apart."
+  (or (timerp timer)
+      (error "Invalid timer"))
+  (aset timer 1 (car time))
+  (aset timer 2 (if (consp (cdr time)) (car (cdr time)) (cdr time)))
+  (aset timer 3 (or (and (consp (cdr time)) (consp (cdr (cdr time)))
+			 (nth 2 time))
+		    0))
+  (aset timer 4 (and (numberp delta) (> delta 0) delta))
+  timer)
+
+(defun timer-set-idle-time (timer secs &optional repeat)
+  "Set the trigger idle time of TIMER to SECS.
+If optional third argument REPEAT is non-nil, make the timer
+fire each time Emacs is idle for that many seconds."
+  (or (timerp timer)
+      (error "Invalid timer"))
+  (aset timer 1 0)
+  (aset timer 2 0)
+  (aset timer 3 0)
+  (timer-inc-time timer secs)
+  (aset timer 4 repeat)
+  timer)
+
+(defun timer-next-integral-multiple-of-time (time secs)
+  "Yield the next value after TIME that is an integral multiple of SECS.
+More precisely, the next value, after TIME, that is an integral multiple
+of SECS seconds since the epoch.  SECS may be a fraction."
+  (let ((time-base (ash 1 16)))
+    (if (fboundp 'atan)
+	;; Use floating point, taking care to not lose precision.
+	(let* ((float-time-base (float time-base))
+	       (million 1000000.0)
+	       (time-usec (+ (* million
+				(+ (* float-time-base (nth 0 time))
+				   (nth 1 time)))
+			     (nth 2 time)))
+	       (secs-usec (* million secs))
+	       (mod-usec (mod time-usec secs-usec))
+	       (next-usec (+ (- time-usec mod-usec) secs-usec))
+	       (time-base-million (* float-time-base million)))
+	  (list (floor next-usec time-base-million)
+		(floor (mod next-usec time-base-million) million)
+		(floor (mod next-usec million))))
+      ;; Floating point is not supported.
+      ;; Use integer arithmetic, avoiding overflow if possible.
+      (let* ((mod-sec (mod (+ (* (mod time-base secs)
+				 (mod (nth 0 time) secs))
+			      (nth 1 time))
+			   secs))
+	     (next-1-sec (+ (- (nth 1 time) mod-sec) secs)))
+	(list (+ (nth 0 time) (floor next-1-sec time-base))
+	      (mod next-1-sec time-base)
+	      0)))))
+
+(defun timer-relative-time (time secs &optional usecs)
+  "Advance TIME by SECS seconds and optionally USECS microseconds.
+SECS may be a fraction."
+  (let ((high (car time))
+	(low (if (consp (cdr time)) (nth 1 time) (cdr time)))
+	(micro (if (numberp (car-safe (cdr-safe (cdr time))))
+		   (nth 2 time)
+		 0)))
+    ;; Add
+    (if usecs (setq micro (+ micro usecs)))
+    (if (floatp secs)
+	(setq micro (+ micro (floor (* 1000000 (- secs (floor secs)))))))
+    (setq low (+ low (floor secs)))
+
+    ;; Normalize
+    ;; `/' rounds towards zero while `mod' returns a positive number,
+    ;; so we can't rely on (= a (+ (* 100 (/ a 100)) (mod a 100))).
+    (setq low (+ low (/ micro 1000000) (if (< micro 0) -1 0)))
+    (setq micro (mod micro 1000000))
+    (setq high (+ high (/ low 65536) (if (< low 0) -1 0)))
+    (setq low (logand low 65535))
+
+    (list high low (and (/= micro 0) micro))))
+
+(defun timer-inc-time (timer secs &optional usecs)
+  "Increment the time set in TIMER by SECS seconds and USECS microseconds.
+SECS may be a fraction.  If USECS is omitted, that means it is zero."
+  (let ((time (timer-relative-time
+	       (list (aref timer 1) (aref timer 2) (aref timer 3))
+	       secs
+	       usecs)))
+    (aset timer 1 (nth 0 time))
+    (aset timer 2 (nth 1 time))
+    (aset timer 3 (or (nth 2 time) 0))))
+
+(defun timer-set-time-with-usecs (timer time usecs &optional delta)
+  "Set the trigger time of TIMER to TIME plus USECS.
+TIME must be in the internal format returned by, e.g., `current-time'.
+The microsecond count from TIME is ignored, and USECS is used instead.
+If optional fourth argument DELTA is a positive number, make the timer
+fire repeatedly that many seconds apart."
+  (or (timerp timer)
+      (error "Invalid timer"))
+  (aset timer 1 (nth 0 time))
+  (aset timer 2 (nth 1 time))
+  (aset timer 3 usecs)
+  (aset timer 4 (and (numberp delta) (> delta 0) delta))
+  timer)
+(make-obsolete 'timer-set-time-with-usecs
+               "use `timer-set-time' and `timer-inc-time' instead."
+               "21.4")
+
+(defun timer-set-function (timer function &optional args)
+  "Make TIMER call FUNCTION with optional ARGS when triggering."
+  (or (timerp timer)
+      (error "Invalid timer"))
+  (aset timer 5 function)
+  (aset timer 6 args)
+  timer)
+
+(defun timer-activate (timer)
+  "Put TIMER on the list of active timers."
+  (if (and (timerp timer)
+	   (integerp (aref timer 1))
+	   (integerp (aref timer 2))
+	   (integerp (aref timer 3))
+	   (aref timer 5))
+      (let ((timers timer-list)
+	    last)
+	;; Skip all timers to trigger before the new one.
+	(while (and timers
+		    (or (> (aref timer 1) (aref (car timers) 1))
+			(and (= (aref timer 1) (aref (car timers) 1))
+			     (> (aref timer 2) (aref (car timers) 2)))
+			(and (= (aref timer 1) (aref (car timers) 1))
+			     (= (aref timer 2) (aref (car timers) 2))
+			     (> (aref timer 3) (aref (car timers) 3)))))
+	  (setq last timers
+		timers (cdr timers)))
+	;; Insert new timer after last which possibly means in front of queue.
+	(if last
+	    (setcdr last (cons timer timers))
+	  (setq timer-list (cons timer timers)))
+	(aset timer 0 nil)
+	(aset timer 7 nil)
+	nil)
+    (error "Invalid or uninitialized timer")))
+
+(defun timer-activate-when-idle (timer &optional dont-wait)
+  "Arrange to activate TIMER whenever Emacs is next idle.
+If optional argument DONT-WAIT is non-nil, then enable the
+timer to activate immediately, or at the right time, if Emacs
+is already idle."
+  (if (and (timerp timer)
+	   (integerp (aref timer 1))
+	   (integerp (aref timer 2))
+	   (integerp (aref timer 3))
+	   (aref timer 5))
+      (let ((timers timer-idle-list)
+	    last)
+	;; Skip all timers to trigger before the new one.
+	(while (and timers
+		    (or (> (aref timer 1) (aref (car timers) 1))
+			(and (= (aref timer 1) (aref (car timers) 1))
+			     (> (aref timer 2) (aref (car timers) 2)))
+			(and (= (aref timer 1) (aref (car timers) 1))
+			     (= (aref timer 2) (aref (car timers) 2))
+			     (> (aref timer 3) (aref (car timers) 3)))))
+	  (setq last timers
+		timers (cdr timers)))
+	;; Insert new timer after last which possibly means in front of queue.
+	(if last
+	    (setcdr last (cons timer timers))
+	  (setq timer-idle-list (cons timer timers)))
+	(aset timer 0 (not dont-wait))
+	(aset timer 7 t)
+	nil)
+    (error "Invalid or uninitialized timer")))
+
+;;;###autoload
+(defalias 'disable-timeout 'cancel-timer)
+;;;###autoload
+(defun cancel-timer (timer)
+  "Remove TIMER from the list of active timers."
+  (or (timerp timer)
+      (error "Invalid timer"))
+  (setq timer-list (delq timer timer-list))
+  (setq timer-idle-list (delq timer timer-idle-list))
+  nil)
+
+;;;###autoload
+(defun cancel-function-timers (function)
+  "Cancel all timers scheduled by `run-at-time' which would run FUNCTION."
+  (interactive "aCancel timers of function: ")
+  (let ((tail timer-list))
+    (while tail
+      (if (eq (aref (car tail) 5) function)
+          (setq timer-list (delq (car tail) timer-list)))
+      (setq tail (cdr tail))))
+  (let ((tail timer-idle-list))
+    (while tail
+      (if (eq (aref (car tail) 5) function)
+          (setq timer-idle-list (delq (car tail) timer-idle-list)))
+      (setq tail (cdr tail)))))
+
+;; Record the last few events, for debugging.
+(defvar timer-event-last-2 nil)
+(defvar timer-event-last-1 nil)
+(defvar timer-event-last nil)
+
+(defvar timer-max-repeats 10
+  "*Maximum number of times to repeat a timer, if real time jumps.")
+
+(defun timer-until (timer time)
+  "Calculate number of seconds from when TIMER will run, until TIME.
+TIMER is a timer, and stands for the time when its next repeat is scheduled.
+TIME is a time-list."
+  (let ((high (- (car time) (aref timer 1)))
+	(low (- (nth 1 time) (aref timer 2))))
+    (+ low (* high 65536))))
+
+(defun timer-event-handler (timer)
+  "Call the handler for the timer TIMER.
+This function is called, by name, directly by the C code."
+  (setq timer-event-last-2 timer-event-last-1)
+  (setq timer-event-last-1 timer-event-last)
+  (setq timer-event-last timer)
+  (let ((inhibit-quit t))
+    (if (timerp timer)
+	(progn
+	  ;; Delete from queue.
+	  (cancel-timer timer)
+	  ;; Re-schedule if requested.
+	  (if (aref timer 4)
+	      (if (aref timer 7)
+		  (timer-activate-when-idle timer)
+		(timer-inc-time timer (aref timer 4) 0)
+		;; If real time has jumped forward,
+		;; perhaps because Emacs was suspended for a long time,
+		;; limit how many times things get repeated.
+		(if (and (numberp timer-max-repeats)
+			 (< 0 (timer-until timer (current-time))))
+		    (let ((repeats (/ (timer-until timer (current-time))
+				      (aref timer 4))))
+		      (if (> repeats timer-max-repeats)
+			  (timer-inc-time timer (* (aref timer 4) repeats)))))
+		(timer-activate timer)))
+	  ;; Run handler.
+	  ;; We do this after rescheduling so that the handler function
+	  ;; can cancel its own timer successfully with cancel-timer.
+	  (condition-case nil
+	      (apply (aref timer 5) (aref timer 6))
+	    (error nil)))
+      (error "Bogus timer event"))))
+
+;; This function is incompatible with the one in levents.el.
+(defun timeout-event-p (event)
+  "Non-nil if EVENT is a timeout event."
+  (and (listp event) (eq (car event) 'timer-event)))
+
+;;;###autoload
+(defun run-at-time (time repeat function &rest args)
+  "Perform an action at time TIME.
+Repeat the action every REPEAT seconds, if REPEAT is non-nil.
+TIME should be a string like \"11:23pm\", nil meaning now, a number of seconds
+from now, a value from `current-time', or t (with non-nil REPEAT)
+meaning the next integral multiple of REPEAT.
+REPEAT may be an integer or floating point number.
+The action is to call FUNCTION with arguments ARGS.
+
+This function returns a timer object which you can use in `cancel-timer'."
+  (interactive "sRun at time: \nNRepeat interval: \naFunction: ")
+
+  (or (null repeat)
+      (and (numberp repeat) (< 0 repeat))
+      (error "Invalid repetition interval"))
+
+  ;; Special case: nil means "now" and is useful when repeating.
+  (if (null time)
+      (setq time (current-time)))
+
+  ;; Special case: t means the next integral multiple of REPEAT.
+  (if (and (eq time t) repeat)
+      (setq time (timer-next-integral-multiple-of-time (current-time) repeat)))
+
+  ;; Handle numbers as relative times in seconds.
+  (if (numberp time)
+      (setq time (timer-relative-time (current-time) time)))
+
+  ;; Handle relative times like "2 hours and 35 minutes"
+  (if (stringp time)
+      (let ((secs (timer-duration time)))
+	(if secs
+	    (setq time (timer-relative-time (current-time) secs)))))
+
+  ;; Handle "11:23pm" and the like.  Interpret it as meaning today
+  ;; which admittedly is rather stupid if we have passed that time
+  ;; already.  (Though only Emacs hackers hack Emacs at that time.)
+  (if (stringp time)
+      (progn
+	(require 'diary-lib)
+	(let ((hhmm (diary-entry-time time))
+	      (now (decode-time)))
+	  (if (>= hhmm 0)
+	      (setq time
+		    (encode-time 0 (% hhmm 100) (/ hhmm 100) (nth 3 now)
+				 (nth 4 now) (nth 5 now) (nth 8 now)))))))
+
+  (or (consp time)
+      (error "Invalid time format"))
+
+  (let ((timer (timer-create)))
+    (timer-set-time timer time repeat)
+    (timer-set-function timer function args)
+    (timer-activate timer)
+    timer))
+
+;;;###autoload
+(defun run-with-timer (secs repeat function &rest args)
+  "Perform an action after a delay of SECS seconds.
+Repeat the action every REPEAT seconds, if REPEAT is non-nil.
+SECS and REPEAT may be integers or floating point numbers.
+The action is to call FUNCTION with arguments ARGS.
+
+This function returns a timer object which you can use in `cancel-timer'."
+  (interactive "sRun after delay (seconds): \nNRepeat interval: \naFunction: ")
+  (apply 'run-at-time secs repeat function args))
+
+;;;###autoload
+(defun add-timeout (secs function object &optional repeat)
+  "Add a timer to run SECS seconds from now, to call FUNCTION on OBJECT.
+If REPEAT is non-nil, repeat the timer every REPEAT seconds.
+This function is for compatibility; see also `run-with-timer'."
+  (run-with-timer secs repeat function object))
+
+;;;###autoload
+(defun run-with-idle-timer (secs repeat function &rest args)
+  "Perform an action the next time Emacs is idle for SECS seconds.
+The action is to call FUNCTION with arguments ARGS.
+SECS may be an integer or a floating point number.
+
+If REPEAT is non-nil, do the action each time Emacs has been idle for
+exactly SECS seconds (that is, only once for each time Emacs becomes idle).
+
+This function returns a timer object which you can use in `cancel-timer'."
+  (interactive
+   (list (read-from-minibuffer "Run after idle (seconds): " nil nil t)
+	 (y-or-n-p "Repeat each time Emacs is idle? ")
+	 (intern (completing-read "Function: " obarray 'fboundp t))))
+  (let ((timer (timer-create)))
+    (timer-set-function timer function args)
+    (timer-set-idle-time timer secs repeat)
+    (timer-activate-when-idle timer)
+    timer))
+
+(defun with-timeout-handler (tag)
+  (throw tag 'timeout))
+
+;;;###autoload (put 'with-timeout 'lisp-indent-function 1)
+
+;;;###autoload
+(defmacro with-timeout (list &rest body)
+  "Run BODY, but if it doesn't finish in SECONDS seconds, give up.
+If we give up, we run the TIMEOUT-FORMS and return the value of the last one.
+The call should look like:
+ (with-timeout (SECONDS TIMEOUT-FORMS...) BODY...)
+The timeout is checked whenever Emacs waits for some kind of external
+event \(such as keyboard input, input from subprocesses, or a certain time);
+if the program loops without waiting in any way, the timeout will not
+be detected."
+  (let ((seconds (car list))
+	(timeout-forms (cdr list)))
+    `(let ((with-timeout-tag (cons nil nil))
+	   with-timeout-value with-timeout-timer)
+       (if (catch with-timeout-tag
+	     (progn
+	       (setq with-timeout-timer
+		     (run-with-timer ,seconds nil
+				      'with-timeout-handler
+				      with-timeout-tag))
+	       (setq with-timeout-value (progn . ,body))
+	       nil))
+	   (progn . ,timeout-forms)
+	 (cancel-timer with-timeout-timer)
+	 with-timeout-value))))
+
+(defun y-or-n-p-with-timeout (prompt seconds default-value)
+  "Like (y-or-n-p PROMPT), with a timeout.
+If the user does not answer after SECONDS seconds, return DEFAULT-VALUE."
+  (with-timeout (seconds default-value)
+    (y-or-n-p prompt)))
+
+(defvar timer-duration-words
+  (list (cons "microsec" 0.000001)
+	(cons "microsecond" 0.000001)
+        (cons "millisec" 0.001)
+	(cons "millisecond" 0.001)
+        (cons "sec" 1)
+	(cons "second" 1)
+	(cons "min" 60)
+	(cons "minute" 60)
+	(cons "hour" (* 60 60))
+	(cons "day" (* 24 60 60))
+	(cons "week" (* 7 24 60 60))
+	(cons "fortnight" (* 14 24 60 60))
+	(cons "month" (* 30 24 60 60))	  ; Approximation
+	(cons "year" (* 365.25 24 60 60)) ; Approximation
+	)
+  "Alist mapping temporal words to durations in seconds")
+
+(defun timer-duration (string)
+  "Return number of seconds specified by STRING, or nil if parsing fails."
+  (let ((secs 0)
+	(start 0)
+	(case-fold-search t))
+    (while (string-match
+	    "[ \t]*\\([0-9.]+\\)?[ \t]*\\([a-z]+[a-rt-z]\\)s?[ \t]*"
+	    string start)
+      (let ((count (if (match-beginning 1)
+		       (string-to-number (match-string 1 string))
+		     1))
+	    (itemsize (cdr (assoc (match-string 2 string)
+				  timer-duration-words))))
+	(if itemsize
+	    (setq start (match-end 0)
+		  secs (+ secs (* count itemsize)))
+	  (setq secs nil
+		start (length string)))))
+    (if (= start (length string))
+	secs
+      (if (string-match "\\`[0-9.]+\\'" string)
+	  (string-to-number string)))))
+
+(provide 'timer)
+
+;;; timer.el ends here
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/emacs-lisp/warnings.el	Fri May 30 23:31:15 2003 +0000
@@ -0,0 +1,311 @@
+;;; warnings.el --- log and display warnings
+
+;; Copyright (C) 2002 Free Software Foundation, Inc.
+
+;; Maintainer: FSF
+;; Keywords: internal
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; This file implements the entry points `warn', `lwarn'
+;; and `display-warnings'.
+
+;;; Code:
+
+(defgroup warnings nil
+  "Log and display warnings."
+  :version "21.4"
+  :group 'lisp)
+
+(defvar warning-levels
+  '((:emergency "Emergency%s: " ding)
+    (:error "Error%s: ")
+    (:warning "Warning%s: ")
+    (:debug "Debug%s: "))
+  "List of severity level definitions for `display-warning'.
+Each element looks like (LEVEL STRING FUNCTION) and
+defines LEVEL as a severity level.  STRING specifies the
+description of this level.  STRING should use `%s' to
+specify where to put the warning group information,
+or it can omit the `%s' so as not to include that information.
+
+The optional FUNCTION, if non-nil, is a function to call
+with no arguments, to get the user's attention.
+
+The standard levels are :emergency, :error, :warning and :debug.
+See `display-warning' for documentation of their meanings.
+Level :debug is ignored by default (see `warning-minimum-level').")
+(put 'warning-levels 'risky-local-variable t)
+
+;; These are for compatibility with XEmacs.
+;; I don't think there is any chance of designing meaningful criteria
+;; to distinguish so many levels.
+(defvar warning-level-aliases
+  '((emergency . :emergency)
+    (error . :error)
+    (warning . :warning)
+    (notice . :warning)
+    (info . :warning)
+    (critical . :emergency)
+    (alarm . :emergency))
+  "Alist of aliases for severity levels for `display-warning'.
+Each element looks like (ALIAS . LEVEL) and defines
+ALIAS as equivalent to LEVEL.  LEVEL must be defined in `warning-levels';
+it may not itself be an alias.")
+
+(defcustom warning-minimum-level :warning
+  "Minimum severity level for displaying the warning buffer.
+If a warning's severity level is lower than this,
+the warning is logged in the warnings buffer, but the buffer
+is not immediately displayed.  See also `warning-minimum-log-level'."
+  :group 'warnings
+  :type '(choice (const :emergency) (const :error) (const :warning))
+  :version "21.4")
+(defvaralias 'display-warning-minimum-level 'warning-minimum-level)
+
+(defcustom warning-minimum-log-level :warning
+  "Minimum severity level for logging a warning.
+If a warning severity level is lower than this,
+the warning is completely ignored."
+  :group 'warnings
+  :type '(choice (const :emergency) (const :error) (const :warning))
+  :version "21.4")
+(defvaralias 'log-warning-minimum-level 'warning-minimum-log-level)
+
+(defcustom warning-suppress-log-types nil
+  "List of warning types that should not be logged.
+If any element of this list matches the GROUP argument to `display-warning',
+the warning is completely ignored.
+The element must match the first elements of GROUP.
+Thus, (foo bar) as an element matches (foo bar)
+or (foo bar ANYTHING...) as GROUP.
+If GROUP is a symbol FOO, that is equivalent to the list (FOO),
+so only the element (FOO) will match it."
+  :group 'warnings
+  :type '(repeat (repeat symbol))
+  :version "21.4")
+
+(defcustom warning-suppress-types nil
+  "Custom groups for warnings not to display immediately.
+If any element of this list matches the GROUP argument to `display-warning',
+the warning is logged nonetheless, but the warnings buffer is
+not immediately displayed.
+The element must match an initial segment of the list GROUP.
+Thus, (foo bar) as an element matches (foo bar)
+or (foo bar ANYTHING...) as GROUP.
+If GROUP is a symbol FOO, that is equivalent to the list (FOO),
+so only the element (FOO) will match it.
+See also `warning-suppress-log-types'."
+  :group 'warnings
+  :type '(repeat (repeat symbol))
+  :version "21.4")
+
+;;; The autoload cookie is so that programs can bind this variable
+;;; safely, testing the existing value, before they call one of the
+;;; warnings functions.
+;;;###autoload
+(defvar warning-prefix-function nil
+  "Function to generate warning prefixes.
+This function, if non-nil, is called with two arguments,
+the severity level and its entry in `warning-levels',
+and should return the entry that should actually be used.
+The warnings buffer is current when this function is called
+and the function can insert text in it.  This text becomes
+the beginning of the warning.")
+
+;;; The autoload cookie is so that programs can bind this variable
+;;; safely, testing the existing value, before they call one of the
+;;; warnings functions.
+;;;###autoload
+(defvar warning-series nil
+  "Non-nil means treat multiple `display-warning' calls as a series.
+A marker indicates a position in the warnings buffer
+which is the start of the current series; it means that
+additional warnings in the same buffer should not move point.
+t means the next warning begins a series (and stores a marker here).
+A symbol with a function definition is like t, except
+also call that function before the next warning.")
+(put 'warning-series 'risky-local-variable t)
+
+;;; The autoload cookie is so that programs can bind this variable
+;;; safely, testing the existing value, before they call one of the
+;;; warnings functions.
+;;;###autoload
+(defvar warning-fill-prefix nil
+  "Non-nil means fill each warning text using this string as `fill-prefix'.")
+
+;;; The autoload cookie is so that programs can bind this variable
+;;; safely, testing the existing value, before they call one of the
+;;; warnings functions.
+;;;###autoload
+(defvar warning-group-format " (%s)"
+  "Format for displaying the warning group in the warning message.
+The result of formatting the group this way gets included in the
+message under the control of the string in `warning-levels'.")
+
+(defun warning-numeric-level (level)
+  "Return a numeric measure of the warning severity level LEVEL."
+  (let* ((elt (assq level warning-levels))
+	 (link (memq elt warning-levels)))
+    (length link)))
+
+(defun warning-suppress-p (group suppress-list)
+  "Non-nil if a warning with group GROUP should be suppressed.
+SUPPRESS-LIST is the list of kinds of warnings to suppress."
+  (let (some-match)
+    (dolist (elt suppress-list)
+      (if (symbolp group)
+	  ;; If GROUP is a symbol, the ELT must be (GROUP).
+	  (if (and (consp elt)
+		   (eq (car elt) group)
+		   (null (cdr elt)))
+	      (setq some-match t))
+	;; If GROUP is a list, ELT must match it or some initial segment of it.
+	(let ((tem1 group)
+	      (tem2 elt)
+	      (match t))
+	  ;; Check elements of ELT until we run out of them.
+	  (while tem2
+	    (if (not (equal (car tem1) (car tem2)))
+		(setq match nil))
+	    (setq tem1 (cdr tem1)
+		  tem2 (cdr tem2)))
+	  ;; If ELT is an initial segment of GROUP, MATCH is t now.
+	  ;; So set SOME-MATCH.
+	  (if match
+	      (setq some-match t)))))
+    ;; If some element of SUPPRESS-LIST matched,
+    ;; we return t.
+    some-match))
+
+;;;###autoload
+(defun display-warning (group message &optional level buffer-name)
+  "Display a warning message, MESSAGE.
+GROUP should be a custom group name (a symbol),
+or else a list of symbols whose first element is a custom group name.
+\(The rest of the symbols represent subcategories, for warning purposes
+only, and you can use whatever symbols you like.)
+
+LEVEL should be either :warning, :error, or :emergency.
+:emergency -- a problem that will seriously impair Emacs operation soon
+	      if you do not attend to it promptly.
+:error     -- data or circumstances that are inherently wrong.
+:warning   -- data or circumstances that are not inherently wrong,
+	      but raise suspicion of a possible problem.
+:debug     -- info for debugging only.
+
+BUFFER-NAME, if specified, is the name of the buffer for logging the
+warning.  By default, it is `*Warnings*'.
+
+See the `warnings' custom group for user customization features.
+
+See also `warning-series', `warning-prefix-function' and
+`warning-fill-prefix' for additional programming features."
+  (unless level
+    (setq level :warning))
+  (if (assq level warning-level-aliases)
+      (setq level (cdr (assq level warning-level-aliases))))
+  (or (< (warning-numeric-level level)
+	 (warning-numeric-level warning-minimum-log-level))
+      (warning-suppress-p group warning-suppress-log-types)
+      (let* ((groupname (if (consp group) (car group) group))
+	     (buffer (get-buffer-create (or buffer-name "*Warnings*")))
+	     (level-info (assq level warning-levels))
+	     start end)
+	(with-current-buffer buffer
+	  (goto-char (point-max))
+	  (when (and warning-series (symbolp warning-series))
+	    (setq warning-series
+		  (prog1 (point-marker)
+		    (unless (eq warning-series t)
+		      (funcall warning-series)))))
+	  (unless (bolp)
+	    (newline))
+	  (setq start (point))
+	  (if warning-prefix-function
+	      (setq level-info (funcall warning-prefix-function
+					level level-info)))
+	  (insert (format (nth 1 level-info)
+                          (format warning-group-format groupname))
+		  message)
+	  (newline)
+	  (when (and warning-fill-prefix (not (string-match "\n" message)))
+	    (let ((fill-prefix warning-fill-prefix)
+		  (fill-column 78))
+	      (fill-region start (point))))
+	  (setq end (point))
+	  (when (and (markerp warning-series)
+		     (eq (marker-buffer warning-series) buffer))
+	    (goto-char warning-series)))
+	(if (nth 2 level-info)
+	    (funcall (nth 2 level-info)))
+	(if noninteractive
+	    ;; Noninteractively, take the text we inserted
+	    ;; in the warnings buffer and print it.
+	    ;; Do this unconditionally, since there is no way
+	    ;; to view logged messages unless we output them.
+	    (with-current-buffer buffer
+	      (save-excursion
+		;; Don't include the final newline in the arg
+		;; to `message', because it adds a newline.
+		(goto-char end)
+		(if (bolp)
+		    (forward-char -1))
+		(message "%s" (buffer-substring start (point)))))
+	  ;; Interactively, decide whether the warning merits
+	  ;; immediate display.
+	  (or (< (warning-numeric-level level)
+		 (warning-numeric-level warning-minimum-level))
+	      (warning-suppress-p group warning-suppress-types)
+	      (let ((window (display-buffer buffer)))
+		(when (and (markerp warning-series)
+			   (eq (marker-buffer warning-series) buffer))
+		  (set-window-start window warning-series))
+		(sit-for 0)))))))
+
+;;;###autoload
+(defun lwarn (group level message &rest args)
+  "Display a warning message made from (format MESSAGE ARGS...).
+Aside from generating the message with `format',
+this is equivalent to `display-warning'.
+
+GROUP should be a custom group name (a symbol).
+or else a list of symbols whose first element is a custom group name.
+\(The rest of the symbols represent subcategories and
+can be whatever you like.)
+
+LEVEL should be either :warning, :error, or :emergency.
+:emergency -- a problem that will seriously impair Emacs operation soon
+	      if you do not attend to it promptly.
+:error     -- invalid data or circumstances.
+:warning   -- suspicious data or circumstances."
+  (display-warning group (apply 'format message args) level))
+
+;;;###autoload
+(defun warn (message &rest args)
+  "Display a warning message made from (format MESSAGE ARGS...).
+Aside from generating the message with `format',
+this is equivalent to `display-warning', using
+`emacs' as the group and `:warning' as the level."
+  (display-warning 'emacs (apply 'format message args)))
+
+(provide 'warnings)
+
+;;; warnings.el ends here
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/progmodes/which-func.el	Fri May 30 23:31:15 2003 +0000
@@ -0,0 +1,256 @@
+;;; which-func.el --- print current function in mode line
+
+;; Copyright (C) 1994, 1997, 1998, 2001, 2003 Free Software Foundation, Inc.
+
+;; Author:   Alex Rezinsky <alexr@msil.sps.mot.com>
+;;           (doesn't seem to be responsive any more)
+;; Keywords: mode-line, imenu, tools
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; This package prints name of function where your current point is
+;; located in mode line. It assumes that you work with imenu package
+;; and imenu--index-alist is up to date.
+
+;; KNOWN BUGS
+;; ----------
+;; Really this package shows not "function where the current point is
+;; located now", but "nearest function which defined above the current
+;; point". So if your current point is located after end of function
+;; FOO but before begin of function BAR, FOO will be displayed in mode
+;; line.
+;; - if two windows display the same buffer, both windows
+;;   show the same `which-func' information.
+
+;; TODO LIST
+;; ---------
+;;     1. Dependence on imenu package should be removed.  Separate
+;; function determination mechanism should be used to determine the end
+;; of a function as well as the beginning of a function.
+;;     2. This package should be realized with the help of overlay
+;; properties instead of imenu--index-alist variable.
+
+;;; History:
+
+;; THANKS TO
+;; ---------
+;; Per Abrahamsen   <abraham@iesd.auc.dk>
+;;     Some ideas (inserting  in mode-line,  using of post-command  hook
+;;     and toggling this  mode) have  been   borrowed from  his  package
+;;     column.el
+;; Peter Eisenhauer <pipe@fzi.de>
+;;     Bug fixing in case nested indexes.
+;; Terry Tateyama   <ttt@ursa0.cs.utah.edu>
+;;     Suggestion to use find-file-hook for first imenu
+;;     index building.
+
+;;; Code:
+
+;; Variables for customization
+;; ---------------------------
+;;
+(defvar which-func-unknown "???"
+  "String to display in the mode line when current function is unknown.")
+
+(defgroup which-func nil
+  "Mode to display the current function name in the modeline."
+  :group 'tools
+  :version "20.3")
+
+(defcustom which-func-modes
+  '(emacs-lisp-mode c-mode c++-mode perl-mode cperl-mode makefile-mode
+		    sh-mode fortran-mode f90-mode)
+  "List of major modes for which Which Function mode should be used.
+For other modes it is disabled.  If this is equal to t,
+then Which Function mode is enabled in any major mode that supports it."
+  :group 'which-func
+  :type '(choice (const :tag "All modes" t)
+		 (repeat (symbol :tag "Major mode"))))
+
+(defcustom which-func-non-auto-modes nil
+  "List of major modes where Which Function mode is inactive till Imenu is used.
+This means that Which Function mode won't really do anything
+until you use Imenu, in these modes.  Note that files
+larger than `which-func-maxout' behave in this way too;
+Which Function mode doesn't do anything until you use Imenu."
+  :group 'which-func
+  :type '(repeat (symbol :tag "Major mode")))
+
+(defcustom which-func-maxout 500000
+  "Don't automatically compute the Imenu menu if buffer is this big or bigger.
+Zero means compute the Imenu menu regardless of size."
+  :group 'which-func
+  :type 'integer)
+
+(defcustom which-func-format '("[" which-func-current "]")
+  "Format for displaying the function in the mode line."
+  :group 'which-func
+  :type 'sexp)
+;;;###autoload (put 'which-func-format 'risky-local-variable t)
+
+(defvar which-func-cleanup-function nil
+  "Function to transform a string before displaying it in the mode line.
+The function is called with one argument, the string to display.
+Its return value is displayed in the modeline.
+If nil, no function is called.  The default value is nil.
+
+This feature can be useful if Imenu is set up to make more
+detailed entries (e.g., containing the argument list of a function),
+and you want to simplify them for the mode line
+\(e.g., removing the parameter list to just have the function name.)")
+
+;;; Code, nothing to customize below here
+;;; -------------------------------------
+;;;
+(require 'imenu)
+
+(defvar which-func-table (make-hash-table :test 'eq :weakness 'key))
+
+(defconst which-func-current
+  '(:eval (gethash (selected-window) which-func-table which-func-unknown)))
+;;;###autoload (put 'which-func-current 'risky-local-variable t)
+
+(defvar which-func-mode nil
+  "Non-nil means display current function name in mode line.
+This makes a difference only if `which-function-mode' is non-nil.")
+(make-variable-buffer-local 'which-func-mode)
+;;(put 'which-func-mode 'permanent-local t)
+
+(add-hook 'find-file-hook 'which-func-ff-hook t)
+
+(defun which-func-ff-hook ()
+  "File find hook for Which Function mode.
+It creates the Imenu index for the buffer, if necessary."
+  (setq which-func-mode
+	(and which-function-mode
+	     (or (eq which-func-modes t)
+		 (member major-mode which-func-modes))))
+
+  (condition-case nil
+      (if (and which-func-mode
+	       (not (member major-mode which-func-non-auto-modes))
+	       (or (null which-func-maxout)
+		   (< buffer-saved-size which-func-maxout)
+		   (= which-func-maxout 0)))
+	  (setq imenu--index-alist
+		(save-excursion (funcall imenu-create-index-function))))
+    (error
+     (setq which-func-mode nil))))
+
+(defun which-func-update ()
+  ;; "Update the Which-Function mode display for all windows."
+  ;; (walk-windows 'which-func-update-1 nil 'visible))
+  (which-func-update-1 (selected-window)))
+
+(defun which-func-update-1 (window)
+  "Update the Which-Function mode display for window WINDOW."
+  (with-selected-window window
+    (when which-func-mode
+      (condition-case info
+	  (let ((current (which-function)))
+	    (unless (equal current (gethash window which-func-table))
+	      (puthash window current which-func-table)
+	      (force-mode-line-update)))
+	(error
+	 (which-func-mode -1)
+	 (error "Error in which-func-update: %s" info))))))
+
+;;;###autoload
+(defalias 'which-func-mode 'which-function-mode)
+
+(defvar which-func-update-timer nil)
+
+;; This is the name people would normally expect.
+;;;###autoload
+(define-minor-mode which-function-mode
+  "Toggle Which Function mode, globally.
+When Which Function mode is enabled, the current function name is
+continuously displayed in the mode line, in certain major modes.
+
+With prefix ARG, turn Which Function mode on iff arg is positive,
+and off otherwise."
+  :global t :group 'which-func
+  (if which-function-mode
+      ;;Turn it on
+      (progn
+        (setq which-func-update-timer
+              (run-with-idle-timer idle-update-delay t 'which-func-update))
+        (dolist (buf (buffer-list))
+          (with-current-buffer buf
+            (setq which-func-mode
+                  (or (eq which-func-modes t)
+                      (member major-mode which-func-modes))))))
+    ;; Turn it off
+    (cancel-timer which-func-update-timer)
+    (setq which-func-update-timer nil)
+    (dolist (buf (buffer-list))
+      (with-current-buffer buf (setq which-func-mode nil)))))
+
+(defvar which-function-imenu-failed nil
+  "Locally t in a buffer if `imenu--make-index-alist' found nothing there.")
+
+(defun which-function ()
+  "Return current function name based on point.
+Uses `imenu--index-alist' or `add-log-current-defun-function'.
+If no function name is found, return nil."
+  (let (name)
+    ;; If Imenu is loaded, try to make an index alist with it.
+    (when (and (boundp 'imenu--index-alist) (null imenu--index-alist)
+	       (null which-function-imenu-failed))
+      (imenu--make-index-alist)
+      (unless imenu--index-alist
+	(make-local-variable 'which-function-imenu-failed)
+	(setq which-function-imenu-failed t)))
+    ;; If we have an index alist, use it.
+    (when (and (boundp 'imenu--index-alist) imenu--index-alist)
+      (let ((alist imenu--index-alist)
+            (minoffset (point-max))
+            offset elem pair mark)
+        (while alist
+          (setq elem  (car-safe alist)
+                alist (cdr-safe alist))
+          ;; Elements of alist are either ("name" . marker), or
+          ;; ("submenu" ("name" . marker) ... ).
+          (unless (listp (cdr elem))
+              (setq elem (list elem)))
+          (while elem
+            (setq pair (car elem)
+                  elem (cdr elem))
+            (and (consp pair)
+                 (number-or-marker-p (setq mark (cdr pair)))
+                 (if (>= (setq offset (- (point) mark)) 0)
+                     (if (< offset minoffset) ; find the closest item
+                         (setq minoffset offset
+                               name (car pair)))
+                   ;; Entries in order, so can skip all those after point.
+                   (setq elem nil)))))))
+    ;; Try using add-log support.
+    (when (and (null name) (boundp 'add-log-current-defun-function)
+	       add-log-current-defun-function)
+      (setq name (funcall add-log-current-defun-function)))
+    ;; Filter the name if requested.
+    (when name
+      (if which-func-cleanup-function
+	  (funcall which-func-cleanup-function name)
+	name))))
+
+(provide 'which-func)
+
+;;; which-func.el ends here
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/textmodes/enriched.el	Fri May 30 23:31:15 2003 +0000
@@ -0,0 +1,474 @@
+;;; enriched.el --- read and save files in text/enriched format
+
+;; Copyright (c) 1994, 1995, 1996, 2002 Free Software Foundation, Inc.
+
+;; Author: Boris Goldowsky <boris@gnu.org>
+;; Keywords: wp, faces
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; 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, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; This file implements reading, editing, and saving files with
+;; text-properties such as faces, levels of indentation, and true line
+;; breaks distinguished from newlines just used to fit text into the window.
+
+;; The file format used is the MIME text/enriched format, which is a
+;; standard format defined in internet RFC 1563.  All standard annotations
+;; are supported except for <smaller> and <bigger>, which are currently not
+;; possible to display.
+
+;; A separate file, enriched.doc, contains further documentation and other
+;; important information about this code.  It also serves as an example
+;; file in text/enriched format.  It should be in the etc directory of your
+;; emacs distribution.
+
+;;; Code:
+
+(provide 'enriched)
+
+;;;
+;;; Variables controlling the display
+;;;
+
+(defgroup enriched nil
+  "Read and save files in text/enriched format"
+  :group 'wp)
+
+(defcustom enriched-verbose t
+  "*If non-nil, give status messages when reading and writing files."
+  :type 'boolean
+  :group 'enriched)
+
+;;;
+;;; Set up faces & display table
+;;;
+
+;; Emacs doesn't have a "fixed" face by default, since all faces currently
+;; have to be fixed-width.  So we just pick one that looks different from the
+;; default.
+(defface fixed
+  '((t (:weight bold)))
+  "Face used for text that must be shown in fixed width.
+Currently, emacs can only display fixed-width fonts, but this may change.
+This face is used for text specifically marked as fixed-width, for example
+in text/enriched files."
+  :group 'enriched)
+
+(defface excerpt
+  '((t (:slant italic)))
+  "Face used for text that is an excerpt from another document.
+This is used in Enriched mode for text explicitly marked as an excerpt."
+  :group 'enriched)
+
+(defconst enriched-display-table (or (copy-sequence standard-display-table)
+				     (make-display-table)))
+(aset enriched-display-table ?\f (make-vector (1- (frame-width)) ?-))
+
+(defconst enriched-par-props '(left-margin right-margin justification)
+  "Text-properties that usually apply to whole paragraphs.
+These are set front-sticky everywhere except at hard newlines.")
+
+;;;
+;;; Variables controlling the file format
+;;;   (bidirectional)
+
+(defconst enriched-initial-annotation
+  (lambda ()
+    (format "Content-Type: text/enriched\nText-Width: %d\n\n"
+	    fill-column))
+  "What to insert at the start of a text/enriched file.
+If this is a string, it is inserted.  If it is a list, it should be a lambda
+expression, which is evaluated to get the string to insert.")
+
+(defconst enriched-annotation-format "<%s%s>"
+  "General format of enriched-text annotations.")
+
+(defconst enriched-annotation-regexp "<\\(/\\)?\\([-A-Za-z0-9]+\\)>"
+  "Regular expression matching enriched-text annotations.")
+
+(defconst enriched-translations
+  '((face          (bold-italic "bold" "italic")
+		   (bold        "bold")
+		   (italic      "italic")
+		   (underline   "underline")
+		   (fixed       "fixed")
+		   (excerpt     "excerpt")
+		   (default     )
+		   (nil         enriched-encode-other-face))
+    (left-margin   (4           "indent"))
+    (right-margin  (4           "indentright"))
+    (justification (none        "nofill")
+		   (right       "flushright")
+		   (left        "flushleft")
+		   (full        "flushboth")
+		   (center      "center"))
+    (PARAMETER     (t           "param")) ; Argument of preceding annotation
+    ;; The following are not part of the standard:
+    (FUNCTION      (enriched-decode-foreground "x-color")
+		   (enriched-decode-background "x-bg-color")
+		   (enriched-decode-display-prop "x-display"))
+    (read-only     (t           "x-read-only"))
+    (display	   (nil		enriched-handle-display-prop))
+    (unknown       (nil         format-annotate-value))
+;   (font-size     (2           "bigger")       ; unimplemented
+;		   (-2          "smaller"))
+)
+  "List of definitions of text/enriched annotations.
+See `format-annotate-region' and `format-deannotate-region' for the definition
+of this structure.")
+
+(defconst enriched-ignore
+  '(front-sticky rear-nonsticky hard)
+  "Properties that are OK to ignore when saving text/enriched files.
+Any property that is neither on this list nor dealt with by
+`enriched-translations' will generate a warning.")
+
+;;; Internal variables
+
+
+(defcustom enriched-mode-hook nil
+  "Hook run after entering/leaving Enriched mode.
+If you set variables in this hook, you should arrange for them to be restored
+to their old values if you leave Enriched mode.  One way to do this is to add
+them and their old values to `enriched-old-bindings'."
+  :type 'hook
+  :group 'enriched)
+
+(defvar enriched-old-bindings nil
+  "Store old variable values that we change when entering mode.
+The value is a list of \(VAR VALUE VAR VALUE...).")
+(make-variable-buffer-local 'enriched-old-bindings)
+
+;;;
+;;; Define the mode
+;;;
+
+(put 'enriched-mode 'permanent-local t)
+;;;###autoload
+(define-minor-mode enriched-mode
+  "Minor mode for editing text/enriched files.
+These are files with embedded formatting information in the MIME standard
+text/enriched format.
+Turning the mode on runs `enriched-mode-hook'.
+
+More information about Enriched mode is available in the file
+etc/enriched.doc in the Emacs distribution directory.
+
+Commands:
+
+\\{enriched-mode-map}"
+  nil " Enriched" nil
+  (cond ((null enriched-mode)
+	 ;; Turn mode off
+	 (setq buffer-file-format (delq 'text/enriched buffer-file-format))
+	 ;; restore old variable values
+	 (while enriched-old-bindings
+	   (set (pop enriched-old-bindings) (pop enriched-old-bindings))))
+
+	((memq 'text/enriched buffer-file-format)
+	 ;; Mode already on; do nothing.
+	 nil)
+
+	(t				; Turn mode on
+	 (push 'text/enriched buffer-file-format)
+	 ;; Save old variable values before we change them.
+	 ;; These will be restored if we exit Enriched mode.
+	 (setq enriched-old-bindings
+	       (list 'buffer-display-table buffer-display-table
+		     'indent-line-function indent-line-function
+		     'default-text-properties default-text-properties))
+	 (make-local-variable 'indent-line-function)
+	 (make-local-variable 'default-text-properties)
+	 (setq indent-line-function 'indent-to-left-margin ;WHY??  -sm
+	       buffer-display-table  enriched-display-table)
+	 (use-hard-newlines 1 nil)
+	 (let ((sticky (plist-get default-text-properties 'front-sticky))
+	       (p enriched-par-props))
+	   (dolist (x p)
+	     (add-to-list 'sticky x))
+	   (if sticky
+	       (setq default-text-properties
+		     (plist-put default-text-properties
+				'front-sticky sticky)))))))
+
+;;;
+;;; Keybindings
+;;;
+
+(defvar enriched-mode-map nil
+  "Keymap for Enriched mode.")
+
+(if (null enriched-mode-map)
+    (fset 'enriched-mode-map (setq enriched-mode-map (make-sparse-keymap))))
+
+(if (not (assq 'enriched-mode minor-mode-map-alist))
+    (setq minor-mode-map-alist
+	  (cons (cons 'enriched-mode enriched-mode-map)
+		minor-mode-map-alist)))
+
+(define-key enriched-mode-map "\C-a" 'beginning-of-line-text)
+(define-key enriched-mode-map "\C-m" 'reindent-then-newline-and-indent)
+(define-key enriched-mode-map "\C-j" 'reindent-then-newline-and-indent)
+(define-key enriched-mode-map "\M-j" 'facemenu-justification-menu)
+(define-key enriched-mode-map "\M-S" 'set-justification-center)
+(define-key enriched-mode-map "\C-x\t" 'increase-left-margin)
+(define-key enriched-mode-map "\C-c\C-l" 'set-left-margin)
+(define-key enriched-mode-map "\C-c\C-r" 'set-right-margin)
+
+;;;
+;;; Some functions dealing with text-properties, especially indentation
+;;;
+
+(defun enriched-map-property-regions (prop func &optional from to)
+  "Apply a function to regions of the buffer based on a text property.
+For each contiguous region of the buffer for which the value of PROPERTY is
+eq, the FUNCTION will be called.  Optional arguments FROM and TO specify the
+region over which to scan.
+
+The specified function receives three arguments: the VALUE of the property in
+the region, and the START and END of each region."
+  (save-excursion
+    (save-restriction
+      (if to (narrow-to-region (point-min) to))
+      (goto-char (or from (point-min)))
+      (let ((begin (point))
+	    end
+	    (marker (make-marker))
+	    (val (get-text-property (point) prop)))
+	(while (setq end (text-property-not-all begin (point-max) prop val))
+	  (move-marker marker end)
+	  (funcall func val begin (marker-position marker))
+	  (setq begin (marker-position marker)
+		val (get-text-property marker prop)))
+	(if (< begin (point-max))
+	    (funcall func val begin (point-max)))))))
+
+(put 'enriched-map-property-regions 'lisp-indent-hook 1)
+
+(defun enriched-insert-indentation (&optional from to)
+  "Indent and justify each line in the region."
+  (save-excursion
+    (save-restriction
+      (if to (narrow-to-region (point-min) to))
+      (goto-char (or from (point-min)))
+      (if (not (bolp)) (forward-line 1))
+      (while (not (eobp))
+	(if (eolp)
+	    nil ; skip blank lines
+	  (indent-to (current-left-margin))
+	  (justify-current-line t nil t))
+	(forward-line 1)))))
+
+;;;
+;;; Encoding Files
+;;;
+
+;;;###autoload
+(defun enriched-encode (from to orig-buf)
+  (if enriched-verbose (message "Enriched: encoding document..."))
+  (save-restriction
+    (narrow-to-region from to)
+    (delete-to-left-margin)
+    (unjustify-region)
+    (goto-char from)
+    (format-replace-strings '(("<" . "<<")))
+    (format-insert-annotations
+     (format-annotate-region from (point-max) enriched-translations
+			     'enriched-make-annotation enriched-ignore))
+    (goto-char from)
+    (insert (if (stringp enriched-initial-annotation)
+		enriched-initial-annotation
+	      (save-excursion
+		;; Eval this in the buffer we are annotating.  This
+		;; fixes a bug which was saving incorrect File-Width
+		;; information, since we were looking at local
+		;; variables in the wrong buffer.
+		(if orig-buf (set-buffer orig-buf))
+		(funcall enriched-initial-annotation))))
+    (enriched-map-property-regions 'hard
+      (lambda (v b e)
+	(if (and v (= ?\n (char-after b)))
+	    (progn (goto-char b) (insert "\n"))))
+      (point) nil)
+    (if enriched-verbose (message nil))
+    ;; Return new end.
+    (point-max)))
+
+(defun enriched-make-annotation (internal-ann positive)
+  "Format an annotation INTERNAL-ANN.
+INTERNAL-ANN may be a string, for a flag, or a list of the form (PARAM VALUE).
+If POSITIVE is non-nil, this is the opening annotation;
+if nil, the matching close."
+  (cond ((stringp internal-ann)
+	 (format enriched-annotation-format (if positive "" "/") internal-ann))
+	;; Otherwise it is an annotation with parameters, represented as a list
+	(positive
+	 (let ((item (car internal-ann))
+	       (params (cdr internal-ann)))
+	   (concat (format enriched-annotation-format "" item)
+		   (mapconcat (lambda (i) (concat "<param>" i "</param>"))
+			      params ""))))
+	(t (format enriched-annotation-format "/" (car internal-ann)))))
+
+(defun enriched-encode-other-face (old new)
+  "Generate annotations for random face change.
+One annotation each for foreground color, background color, italic, etc."
+  (cons (and old (enriched-face-ans old))
+	(and new (enriched-face-ans new))))
+
+(defun enriched-face-ans (face)
+  "Return annotations specifying FACE.
+FACE may be a list of faces instead of a single face;
+it can also be anything allowed as an element of a list
+which can be the value of the `face' text property."
+  (cond ((and (consp face) (eq (car face) 'foreground-color))
+	 (list (list "x-color" (cdr face))))
+	((and (consp face) (eq (car face) 'background-color))
+	 (list (list "x-bg-color" (cdr face))))
+	((and (listp face) (eq (car face) :foreground))
+	 (list (list "x-color" (cadr face))))
+	((and (listp face) (eq (car face) :background))
+	 (list (list "x-bg-color" (cadr face))))
+	((listp face)
+	 (apply 'append (mapcar 'enriched-face-ans face)))
+	((let* ((fg (face-attribute face :foreground))
+		(bg (face-attribute face :background))
+		(props (face-font face t))
+		(ans (cdr (format-annotate-single-property-change
+			   'face nil props enriched-translations))))
+	   (unless (eq fg 'unspecified)
+	     (setq ans (cons (list "x-color" fg) ans)))
+	   (unless (eq bg 'unspecified)
+	     (setq ans (cons (list "x-bg-color" bg) ans)))
+	   ans))))
+
+;;;
+;;; Decoding files
+;;;
+
+;;;###autoload
+(defun enriched-decode (from to)
+  (if enriched-verbose (message "Enriched: decoding document..."))
+  (use-hard-newlines 1 'never)
+  (save-excursion
+    (save-restriction
+      (narrow-to-region from to)
+      (goto-char from)
+
+      ;; Deal with header
+      (let ((file-width (enriched-get-file-width)))
+	(enriched-remove-header)
+
+	;; Deal with newlines
+	(while (search-forward-regexp "\n\n+" nil t)
+	  (if (current-justification)
+	      (delete-char -1))
+	  (set-hard-newline-properties (match-beginning 0) (point)))
+
+	;; Translate annotations
+	(format-deannotate-region from (point-max) enriched-translations
+				  'enriched-next-annotation)
+
+	;; Indent or fill the buffer
+	(cond (file-width		; File was filled to this width
+	       (setq fill-column file-width)
+	       (if enriched-verbose (message "Indenting..."))
+	       (enriched-insert-indentation))
+	      (t			; File was not filled.
+	       (if enriched-verbose (message "Filling paragraphs..."))
+	       (fill-region (point-min) (point-max))))
+	(if enriched-verbose (message nil)))
+      (point-max))))
+
+(defun enriched-next-annotation ()
+  "Find and return next text/enriched annotation.
+Any \"<<\" strings encountered are converted to \"<\".
+Return value is \(begin end name positive-p), or nil if none was found."
+  (while (and (search-forward "<" nil 1)
+	      (progn (goto-char (match-beginning 0))
+		     (not (looking-at enriched-annotation-regexp))))
+    (forward-char 1)
+    (if (= ?< (char-after (point)))
+	(delete-char 1)
+      ;; A single < that does not start an annotation is an error,
+      ;; which we note and then ignore.
+      (message "Warning: malformed annotation in file at %s"
+	       (1- (point)))))
+  (if (not (eobp))
+      (let* ((beg (match-beginning 0))
+	     (end (match-end 0))
+	     (name (downcase (buffer-substring
+			      (match-beginning 2) (match-end 2))))
+	     (pos (not (match-beginning 1))))
+	(list beg end name pos))))
+
+(defun enriched-get-file-width ()
+  "Look for file width information on this line."
+  (save-excursion
+    (if (search-forward "Text-Width: " (+ (point) 1000) t)
+	(read (current-buffer)))))
+
+(defun enriched-remove-header ()
+  "Remove file-format header at point."
+  (while (looking-at "^[-A-Za-z]+: .*\n")
+    (delete-region (point) (match-end 0)))
+  (if (looking-at "^\n")
+      (delete-char 1)))
+
+(defun enriched-decode-foreground (from to &optional color)
+  (if color
+      (list from to 'face (list ':foreground color))
+    (message "Warning: no color specified for <x-color>")
+    nil))
+
+(defun enriched-decode-background (from to &optional color)
+  (if color
+      (list from to 'face (list ':background color))
+    (message "Warning: no color specified for <x-bg-color>")
+    nil))
+
+;;; Handling the `display' property.
+
+
+(defun enriched-handle-display-prop (old new)
+  "Return a list of annotations for a change in the `display' property.
+OLD is the old value of the property, NEW is the new value.  Value
+is a list `(CLOSE OPEN)', where CLOSE is a list of annotations to
+close and OPEN a list of annotations to open.  Each of these lists
+has the form `(ANNOTATION PARAM ...)'."
+  (let ((annotation "x-display")
+	(param (prin1-to-string (or old new))))
+    (if (null old)
+        (cons nil (list (list annotation param)))
+      (cons (list (list annotation param)) nil))))
+
+(defun enriched-decode-display-prop (start end &optional param)
+  "Decode a `display' property for text between START and END.
+PARAM is a `<param>' found for the property.
+Value is a list `(START END SYMBOL VALUE)' with START and END denoting
+the range of text to assign text property SYMBOL with value VALUE "
+  (let ((prop (when (stringp param)
+		(condition-case ()
+		    (car (read-from-string param))
+		  (error nil)))))
+    (unless prop
+      (message "Warning: invalid <x-display> parameter %s" param))
+    (list start end 'display prop)))
+
+;;; enriched.el ends here