changeset 83150:cf8f0a3b5cb4

Merged in changes from CVS trunk. Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-376 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-377 (Fdisplay_supports_face_attributes_p): Work around bootstrapping problem * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-378 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-379 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-380 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-381 Face merging cleanups git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-190
author Karoly Lorentey <lorentey@elte.hu>
date Mon, 07 Jun 2004 08:00:27 +0000
parents f004099bad61 (current diff) b9f354f2c61f (diff)
children 2c7da91ab69b
files lisp/ChangeLog lisp/bindings.el man/ChangeLog src/coding.c src/keymap.c src/minibuf.c src/process.c src/xfaces.c
diffstat 53 files changed, 912 insertions(+), 495 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS	Mon Jun 07 07:10:59 2004 +0000
+++ b/etc/NEWS	Mon Jun 07 08:00:27 2004 +0000
@@ -105,7 +105,7 @@
 ** Commands winner-redo and winner-undo, from winner.el, are now bound to
 C-c <left> and C-c <right>, respectively.  This is an incompatible change.
 
-** Help commands `describe-funcion' and `describe-key' now show function
+** Help commands `describe-function' and `describe-key' now show function
 arguments in lowercase italics on displays that support it.  To change the
 default, customize face `help-argument-name' or redefine the function
 `help-default-arg-highlight'.
@@ -2043,6 +2043,12 @@
 
 * Lisp Changes in Emacs 21.4
 
+** The sentinel is now called whan a network process is deleted with
+delete-process.  The status message passed to the sentinel for a
+deleted network process is "deleted".  The message passed to the
+sentinel when the connection is closed by the remote peer has been
+changed to "connection broken by remote peer".
+
 ** If the buffer's undo list for the current command gets longer than
 undo-outer-limit, garbage collection empties it.  This is to prevent
 it from using up the available memory and choking Emacs.
@@ -3046,6 +3052,13 @@
 ** New functions face-attribute-relative-p and merge-face-attribute
 help with handling relative face attributes.
 
+** The priority of faces in an :inherit attribute face-list is reversed.
+If a face contains an :inherit attribute with a list of faces, earlier
+faces in the list override later faces in the list; in previous releases
+of Emacs, the order was the opposite.  This change was made so that
+:inherit face-lists operate identically to face-lists in text `face'
+properties.
+
 +++
 ** Enhancements to process support
 
--- a/leim/ChangeLog	Mon Jun 07 07:10:59 2004 +0000
+++ b/leim/ChangeLog	Mon Jun 07 08:00:27 2004 +0000
@@ -1,3 +1,10 @@
+2004-06-05  Kenichi Handa  <handa@m17n.org>
+
+	* Makefile.in (leim-list.el): Depend on leim-ext.el.  Append the
+	contents of leim-ext.el to leim-list.el.
+
+	* leim-ext.el: New file.
+
 2004-05-17  Werner Lemberg  <wl@gnu.org>
 
 	* quail/sisheng.el: New file.
--- a/leim/Makefile.in	Mon Jun 07 07:10:59 2004 +0000
+++ b/leim/Makefile.in	Mon Jun 07 08:00:27 2004 +0000
@@ -192,7 +192,7 @@
 	  -f batch-miscdic-convert -dir quail ${srcdir}/MISC-DIC; \
 	  echo "changed" > $@
 
-leim-list.el: ${SUBDIRS} ${NON-TIT-MISC} changed.tit changed.misc
+leim-list.el: ${SUBDIRS} ${NON-TIT-MISC} changed.tit changed.misc ${srcdir}/leim-ext.el
 	${RUN-EMACS}  -l ${buildlisppath}/international/quail \
 	  -f batch-byte-compile-if-not-done ${TIT-MISC:.elc=.el}
 	if [ x`(cd ${srcdir} && /bin/pwd)` = x`(/bin/pwd)` ] ; then \
@@ -202,6 +202,7 @@
 	  ${RUN-EMACS} -l ${buildlisppath}/international/quail \
 	    --eval "(update-leim-list-file \".\" \"${srcdir}\")" ; \
 	fi
+	sed -n '/^[^;]/ p' < ${srcdir}/leim-ext.el >> $@
 
 install: all
 	if [ x`(cd ${INSTALLDIR} && /bin/pwd)` != x`(/bin/pwd)` ] ; then \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leim/leim-ext.el	Mon Jun 07 08:00:27 2004 +0000
@@ -0,0 +1,37 @@
+;; leim-ext.el -- extra leim configulation	-*- coding:iso-2022-7bit; -*-
+
+;; Copyright (C) 2004
+;;   Free Software Foundation, Inc.
+;; Copyright (C) 2004
+;;   National Institute of Advanced Industrial Science and Technology (AIST)
+;;   Registration Number H13PRO009
+
+;; 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:
+
+;; Makefile in this directory appends the contents of this file (only
+;; such non-empty lines that don't begin with ';') to the generated
+;; file leim-list.el.
+
+;;; Code:
+
+(eval-after-load "quail/PY-b5"
+  '(quail-defrule "ling2" ?$(0!r(B nil t))
+
+;; arch-tag: 75cfdfc7-de85-44f9-b408-ff67d1ec664e
--- a/lisp/ChangeLog	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/ChangeLog	Mon Jun 07 08:00:27 2004 +0000
@@ -1,3 +1,89 @@
+2004-06-06  Juanma Barranquero  <lektu@terra.es>
+
+	* help-fns.el (help-argument-name): Inherit from italic face only
+	if the frame supports it.
+
+2004-06-06  Jan Dj,Ad(Brv  <jan.h.d@swipnet.se>
+
+	* toolbar/alias.pbm, toolbar/close.pbm, toolbar/copy.pbm,
+	* toolbar/cut.pbm, toolbar/help.pbm, toolbar/home.pbm
+	* toolbar/index.pbm, toolbar/jump_to.pbm, toolbar/left_arrow.pbm
+	* toolbar/new.pbm, toolbar/open.pbm, toolbar/paste.pbm
+	* toolbar/preferences.pbm, toolbar/print.pbm, toolbar/right_arrow.pbm
+	* toolbar/save.pbm, toolbar/saveas.pbm, toolbar/search.pbm
+	* toolbar/spell.pbm, toolbar/undo.pbm, toolbar/up_arrow.pbm:
+	New conversions from xpm files.
+
+	* toolbar/README: New file.
+
+2004-06-06  Richard M. Stallman  <rms@gnu.org>
+
+	* isearch.el (isearch-mode-map): Undo previous change.
+
+2004-06-05  Juri Linkov  <juri@jurta.org>
+
+	* bindings.el (debug-ignored-errors): Add regexps for history
+	related messages.  Remove $ from "No further undo information".
+	Move Ediff's messages to ediff.el.
+
+	* ediff.el: Move Ediff's debug-ignored-errors from bindings.el.
+
+	* cus-edit.el (custom-display): Add `min-colors'.
+
+	* custom.el (defface): Add `supports' to docstring.
+
+	* help-fns.el (help-argument-name): Add :group 'help.
+
+2004-06-05  Luc Teirlinck  <teirllm@auburn.edu>
+
+	* find-dired.el (find-ls-subdir-switches): New user option.
+	(find-dired): No longer call `abbreviate-file-name' on DIR.
+	Set `dired-subdir-switches' buffer-locally.
+
+	* locate.el: Merge the two `Commentary' sections.
+	(locate-ls-subdir-switches): New user option.
+	(locate): Update for other changes.
+	(locate-mode-map): Restore Dired binding for mouse-2.
+	Bind `locate-mouse-view-file' to M-mouse-2.
+	Bind `l' to `locate-do-redisplay'.
+	(locate-main-listing-line-p, locate-do-redisplay): New functions.
+	(locate-mouse-view-file, locate-tags, locate-find-directory):
+	Print message if used outside main listing.
+	(locate-mode): Update docstring.  Make `*Locate*' buffer read-only.
+	Various changes to support inserted subdirectories.
+	(locate-insert-header): Change header of *Locate* buffer.
+
+	* dired-aux.el (dired-do-redisplay, dired-maybe-insert-subdir):
+	Change interactive default switches.
+	(dired-rename-subdir-2): Update `dired-switches-alist'.
+	(dired-insert-subdir, dired-kill-subdir):
+	Handle `dired-switches-alist'.  Do not mark buffer modified.
+	(dired-insert-subdir-validate): Handle `dired-subdir-switches'.
+	(dired-insert-subdir-doinsert): Omit messages.
+	Handle `dired-subdir-switches'.
+	(dired-hide-subdir, dired-hide-all): Do not mark buffer modified.
+
+	* dired.el (dired-subdir-switches, dired-switches-alist):
+	New vars.
+	(dired-insert-old-subdirs): Do not repeatedly delete and reinsert
+	subdirs if -R switch is used for a subdir.
+	(dired-mode): Set `dired-switches-alist'.
+	(dired-build-subdir-alist): Only print number of directories in
+	echo area when invoked interactively.
+
+2004-06-05  Lars Hansen  <larsh@math.ku.dk>
+
+	* dired-x.el (dired-omit-mode): Rename from
+	dired-omit-files-p.  Use define-minor-mode to define it.
+	(dired-omit-files-p): Add as alias for dired-omit-mode.
+	(dired-omit-toggle): Delete.  Replaced by dired-omit-mode and
+	dired-mark-omitted.
+	(dired-mark-omitted): Add.  Bind to M-O.
+
+2004-06-05  Kenichi Handa  <handa@m17n.org>
+
+	* ps-print.el: Fix typos (kein'ichi -> ken'ichi)
+
 2004-06-05  Juanma Barranquero  <lektu@terra.es>
 
 	* help-fns.el (help-argument-name): Reintroduce face.
@@ -660,28 +746,20 @@
 
 2004-05-15  Jan Dj,Ad(Brv  <jan.h.d@swipnet.se>
 
-	* toolbar/close.pbm, toolbar/close.xpm
-	* toolbar/copy.pbm, toolbar/copy.xpm
-	* toolbar/cut.pbm, toolbar/cut.xpm
-	* toolbar/help.pbm, toolbar/help.xpm
-	* toolbar/home.pbm, toolbar/home.xpm
-	* toolbar/index.pbm, toolbar/index.xpm
-	* toolbar/jump_to.pbm, toolbar/jump_to.xpm
-	* toolbar/left_arrow.pbm, toolbar/left_arrow.xpm
-	* toolbar/new.pbm, toolbar/new.xpm
-	* toolbar/open.pbm, toolbar/open.xpm
-	* toolbar/paste.pbm, toolbar/paste.xpm
-	* toolbar/preferences.pbm, toolbar/preferences.xpm
-	* toolbar/print.pbm, toolbar/print.xpm
-	* toolbar/right_arrow.pbm, toolbar/right_arrow.xpm
-	* toolbar/save.pbm, toolbar/save.xpm
-	* toolbar/saveas.pbm, toolbar/saveas.xpm
-	* toolbar/search.pbm, toolbar/search.xpm
-	* toolbar/spell.pbm, toolbar/spell.xpm
-	* toolbar/undo.pbm, toolbar/undo.xpm
-	* toolbar/up_arrow.pbm, toolbar/up_arrow.xpm: New icons from
-	GTK+ version 2.
-
+	* toolbar/close.pbm, toolbar/close.xpm, toolbar/copy.pbm
+	* toolbar/copy.xpm, toolbar/cut.pbm, toolbar/cut.xpm
+	* toolbar/help.pbm, toolbar/help.xpm, toolbar/home.pbm
+	* toolbar/home.xpm, toolbar/index.pbm, toolbar/index.xpm
+	* toolbar/jump_to.pbm, toolbar/jump_to.xpm, toolbar/left_arrow.pbm
+	* toolbar/left_arrow.xpm, toolbar/new.pbm, toolbar/new.xpm
+	* toolbar/open.pbm, toolbar/open.xpm, toolbar/paste.pbm
+	* toolbar/paste.xpm, toolbar/preferences.pbm, toolbar/preferences.xpm
+	* toolbar/print.pbm, toolbar/print.xpm, toolbar/right_arrow.pbm
+	* toolbar/right_arrow.xpm, toolbar/save.pbm, toolbar/save.xpm
+	* toolbar/saveas.pbm, toolbar/saveas.xpm, toolbar/search.pbm
+	* toolbar/search.xpm, toolbar/spell.pbm, toolbar/spell.xpm
+	* toolbar/undo.pbm, toolbar/undo.xpm, toolbar/up_arrow.pbm
+	* toolbar/up_arrow.xpm: New icons from GTK+ version 2.
 
 2004-05-15  Kim F. Storm  <storm@cua.dk>
 
@@ -3216,7 +3294,7 @@
 	if the source location can't be found.
 	(edebug-compute-previous-result): Use prin1-char.
 
-	* emacs-lisp/checkdoc.el (checkdoc-error): Dont' assume point-min == 1.
+	* emacs-lisp/checkdoc.el (checkdoc-error): Don't assume point-min == 1.
 	(debug-ignored-errors): Add an entry.
 
 	* emacs-lisp/bytecomp.el (byte-recompile-directory): Ignore hidden dir.
--- a/lisp/bindings.el	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/bindings.el	Mon Jun 07 08:00:27 2004 +0000
@@ -542,63 +542,20 @@
 	file-supersession
       	"^Previous command was not a yank$"
 	"^Minibuffer window is not active$"
+	"^No previous history search regexp$"
+	"^No later matching history item$"
+	"^No earlier matching history item$"
+	"^End of history; no default available$"
 	"^End of history; no next item$"
 	"^Beginning of history; no preceding item$"
 	"^No recursive edit is in progress$"
 	"^Changes to be undone are outside visible portion of buffer$"
 	"^No undo information in this buffer$"
-	"^No further undo information$"
+	"^No further undo information"
 	"^Save not confirmed$"
 	"^Recover-file cancelled\\.$"
 	"^Cannot switch buffers in a dedicated window$"
-
-	;; ediff
-	"^Errors in diff output. Diff output is in "
-	"^Hmm... I don't see an Ediff command around here...$"
-	"^Undocumented command! Type `G' in Ediff Control Panel to drop a note to the Ediff maintainer$"
-	": This command runs in Ediff Control Buffer only!$"
-	": Invalid op in ediff-check-version$"
-	"^ediff-shrink-window-C can be used only for merging jobs$"
-	"^Lost difference info on these directories$"
-	"^This command is inapplicable in the present context$"
-	"^This session group has no parent$"
-	"^Can't hide active session, $"
-	"^Ediff: something wrong--no multiple diffs buffer$"
-	"^Can't make context diff for Session $"
-	"^The patch buffer wasn't found$"
-	"^Aborted$"
-	"^This Ediff session is not part of a session group$"
-	"^No active Ediff sessions or corrupted session registry$"
-	"^No session info in this line$"
-	"^`.*' is not an ordinary file$"
-	"^Patch appears to have failed$"
-	"^Recomputation of differences cancelled$"
-	"^No fine differences in this mode$"
-	"^Lost connection to ancestor buffer...sorry$"
-	"^Not merging with ancestor$"
-	"^Don't know how to toggle read-only in buffer "
-	"Emacs is not running as a window application$"
-	"^This command makes sense only when merging with an ancestor$"
-	"^At end of the difference list$"
-	"^At beginning of the difference list$"
-	"^Nothing saved for diff .* in buffer "
-	"^Buffer is out of sync for file "
-	"^Buffer out of sync for file "
-	"^Output from `diff' not found$"
-	"^You forgot to specify a region in buffer "
-	"^All right. Make up your mind and come back...$"
-	"^Current buffer is not visiting any file$"
-	"^Failed to retrieve revision: $"
-	"^Can't determine display width.$"
-	"^File `.*' does not exist or is not readable$"
-	"^File `.*' is a directory$"
-	"^Buffer .* doesn't exist$"
-	"^Directories . and . are the same: "
-	"^Directory merge aborted$"
-	"^Merge of directory revisions aborted$"
-	"^Buffer .* doesn't exist$"
-	"^There is no file to merge$"
-	"^Version control package .*.el not found. Use vc.el instead$"))
+        ))
 
 
 (make-variable-buffer-local 'indent-tabs-mode)
--- a/lisp/cus-edit.el	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/cus-edit.el	Mon Jun 07 08:00:27 2004 +0000
@@ -2729,6 +2729,10 @@
 Match frames with no color support.")
 					   mono)))
 		  (group :sibling-args (:help-echo "\
+The minimum number of colors the frame should support.")
+			 (const :format "" min-colors)
+			 (integer :tag "Minimum number of colors" ))
+		  (group :sibling-args (:help-echo "\
 Only match frames with the specified intensity.")
 			 (const :format "\
 Background brightness: "
--- a/lisp/custom.el	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/custom.el	Mon Jun 07 08:00:27 2004 +0000
@@ -311,6 +311,11 @@
   Should be an integer, it is compared with the result of
   `display-color-cells'.
 
+`supports' (only match frames that support the specified face attributes)
+  Should be a list of face attributes.  See the documentation for
+  the function `display-supports-face-attributes-p' for more
+  information on exactly how testing is done.
+
 Read the section about customization in the Emacs Lisp manual for more
 information."
   ;; It is better not to use backquote in this file,
--- a/lisp/dired-aux.el	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/dired-aux.el	Mon Jun 07 08:00:27 2004 +0000
@@ -895,9 +895,15 @@
   ;; Moves point if the next ARG files are redisplayed.
   (interactive "P\np")
   (if (and test-for-subdir (dired-get-subdir))
-      (dired-insert-subdir
-       (dired-get-subdir)
-       (if arg (read-string "Switches for listing: " dired-actual-switches)))
+      (let* ((dir (dired-get-subdir))
+	     (switches (cdr (assoc-string dir dired-switches-alist))))
+	(dired-insert-subdir
+	 dir
+	 (when arg
+	   (read-string "Switches for listing: "
+			(or switches
+			    dired-subdir-switches
+			    dired-actual-switches)))))
     (message "Redisplaying...")
     ;; message much faster than making dired-map-over-marks show progress
     (dired-uncache
@@ -1207,9 +1213,10 @@
 	  (dired-advertise)))))
 
 (defun dired-rename-subdir-2 (elt dir to)
-  ;; Update the headerline and dired-subdir-alist element of directory
-  ;; described by alist-element ELT to reflect the moving of DIR to TO.
-  ;; Thus, ELT describes either DIR itself or a subdir of DIR.
+  ;; Update the headerline and dired-subdir-alist element, as well as
+  ;; dired-switches-alist element, of directory described by
+  ;; alist-element ELT to reflect the moving of DIR to TO.  Thus, ELT
+  ;; describes either DIR itself or a subdir of DIR.
   (save-excursion
     (let ((regexp (regexp-quote (directory-file-name dir)))
 	  (newtext (directory-file-name to))
@@ -1223,10 +1230,12 @@
 	(if (re-search-forward regexp (match-end 1) t)
 	    (replace-match newtext t t)
 	  (error "Expected to find `%s' in headerline of %s" dir (car elt))))
-      ;; Update buffer-local dired-subdir-alist
-      (setcar elt
-	      (dired-normalize-subdir
-	       (dired-replace-in-string regexp newtext (car elt)))))))
+      ;; Update buffer-local dired-subdir-alist and dired-switches-alist
+      (let ((cons (assoc-string (car elt) dired-switches-alist))
+	    (cur-dir (dired-normalize-subdir
+		      (dired-replace-in-string regexp newtext (car elt)))))
+	(setcar elt cur-dir)
+	(when cons (setcar cons cur-dir))))))
 
 ;; The basic function for half a dozen variations on cp/mv/ln/ln -s.
 (defun dired-create-files (file-creator operation fn-list name-constructor
@@ -1722,7 +1731,8 @@
   (interactive
    (list (dired-get-filename)
 	 (if current-prefix-arg
-	     (read-string "Switches for listing: " dired-actual-switches))))
+	     (read-string "Switches for listing: "
+			  (or dired-subdir-switches dired-actual-switches)))))
   (let ((opoint (point)))
     ;; We don't need a marker for opoint as the subdir is always
     ;; inserted *after* opoint.
@@ -1749,14 +1759,19 @@
   (interactive
    (list (dired-get-filename)
 	 (if current-prefix-arg
-	     (read-string "Switches for listing: " dired-actual-switches))))
+	     (read-string "Switches for listing: "
+			  (or dired-subdir-switches dired-actual-switches)))))
   (setq dirname (file-name-as-directory (expand-file-name dirname)))
-  (dired-insert-subdir-validate dirname switches)
   (or no-error-if-not-dir-p
       (file-directory-p dirname)
       (error  "Attempt to insert a non-directory: %s" dirname))
   (let ((elt (assoc dirname dired-subdir-alist))
-	 switches-have-R mark-alist case-fold-search buffer-read-only)
+	(cons (assoc-string dirname dired-switches-alist))
+	(modflag (buffer-modified-p))
+	(old-switches switches)
+	switches-have-R mark-alist case-fold-search buffer-read-only)
+    (and (not switches) cons (setq switches (cdr cons)))
+    (dired-insert-subdir-validate dirname switches)
     ;; case-fold-search is nil now, so we can test for capital `R':
     (if (setq switches-have-R (and switches (string-match "R" switches)))
 	;; avoid duplicated subdirs
@@ -1767,9 +1782,23 @@
       (dired-insert-subdir-newpos dirname)) ; else compute new position
     (dired-insert-subdir-doupdate
      dirname elt (dired-insert-subdir-doinsert dirname switches))
-    (if switches-have-R (dired-build-subdir-alist switches))
+    (when old-switches
+      (if cons
+	  (setcdr cons switches)
+	(push (cons dirname switches) dired-switches-alist)))
+    (when switches-have-R
+      (dired-build-subdir-alist switches)
+      (dolist (cur-ass dired-subdir-alist)
+	(let ((cur-dir (car cur-ass)))
+	  (and (dired-in-this-tree cur-dir dirname)
+	       (not (string= cur-dir dirname))
+	       (let ((cur-cons (assoc-string cur-dir dired-switches-alist)))
+		 (if cur-cons
+		     (setcdr cur-cons switches)
+		   (push (cons cur-dir switches) dired-switches-alist)))))))
     (dired-initial-position dirname)
-    (save-excursion (dired-mark-remembered mark-alist))))
+    (save-excursion (dired-mark-remembered mark-alist))
+    (restore-buffer-modified-p modflag)))
 
 ;; This is a separate function for dired-vms.
 (defun dired-insert-subdir-validate (dirname &optional switches)
@@ -1777,17 +1806,18 @@
   ;; Signal an error if invalid (e.g. user typed `i' on `..').
   (or (dired-in-this-tree dirname (expand-file-name default-directory))
       (error  "%s: not in this directory tree" dirname))
-  (if switches
+  (let ((real-switches (or switches dired-subdir-switches)))
+    (when real-switches
       (let (case-fold-search)
 	(mapcar
 	 (function
 	  (lambda (x)
-	    (or (eq (null (string-match x switches))
+	    (or (eq (null (string-match x real-switches))
 		    (null (string-match x dired-actual-switches)))
-		(error "Can't have dirs with and without -%s switches together"
-		       x))))
+		(error
+		 "Can't have dirs with and without -%s switches together" x))))
 	 ;; all switches that make a difference to dired-get-filename:
-	 '("F" "b")))))
+	 '("F" "b"))))))
 
 (defun dired-alist-add (dir new-marker)
   ;; Add new DIR at NEW-MARKER.  Sort alist.
@@ -1855,16 +1885,15 @@
   ;; Return the boundary of the inserted text (as list of BEG and END).
   (save-excursion
     (let ((begin (point)))
-      (message "Reading directory %s..." dirname)
       (let ((dired-actual-switches
 	     (or switches
+		 dired-subdir-switches
 		 (dired-replace-in-string "R" "" dired-actual-switches))))
 	(if (equal dirname (car (car (last dired-subdir-alist))))
 	    ;; If doing the top level directory of the buffer,
 	    ;; redo it as specified in dired-directory.
 	    (dired-readin-insert)
 	  (dired-insert-directory dirname dired-actual-switches nil nil t)))
-      (message "Reading directory %s...done" dirname)
       (list begin (point)))))
 
 (defun dired-insert-subdir-doupdate (dirname elt beg-end)
@@ -2007,10 +2036,12 @@
 Lower levels are unaffected."
   ;; With optional REMEMBER-MARKS, return a mark-alist.
   (interactive)
-  (let ((beg (dired-subdir-min))
-	(end (dired-subdir-max))
-	buffer-read-only cur-dir)
-    (setq cur-dir (dired-current-directory))
+  (let* ((beg (dired-subdir-min))
+	 (end (dired-subdir-max))
+	 (modflag (buffer-modified-p))
+	 (cur-dir (dired-current-directory))
+	 (cons (assoc-string cur-dir dired-switches-alist))
+	 buffer-read-only)
     (if (equal cur-dir default-directory)
 	(error "Attempt to kill top level directory"))
     (prog1
@@ -2018,7 +2049,10 @@
       (delete-region beg end)
       (if (eobp)			; don't leave final blank line
 	  (delete-char -1))
-      (dired-unsubdir cur-dir))))
+      (dired-unsubdir cur-dir)
+      (when cons
+	(setq dired-switches-alist (delete cons dired-switches-alist)))
+      (restore-buffer-modified-p modflag))))
 
 (defun dired-unsubdir (dir)
   ;; Remove DIR from the alist
@@ -2077,19 +2111,21 @@
 Use \\[dired-hide-all] to (un)hide all directories."
   (interactive "p")
   (dired-hide-check)
-  (while (>=  (setq arg (1- arg)) 0)
-    (let* ((cur-dir (dired-current-directory))
-	   (hidden-p (dired-subdir-hidden-p cur-dir))
-	   (elt (assoc cur-dir dired-subdir-alist))
-	   (end-pos (1- (dired-get-subdir-max elt)))
-	   buffer-read-only)
-      ;; keep header line visible, hide rest
-      (goto-char (dired-get-subdir-min elt))
-      (skip-chars-forward "^\n\r")
-      (if hidden-p
-	  (subst-char-in-region (point) end-pos ?\r ?\n)
-	(subst-char-in-region (point) end-pos ?\n ?\r)))
-    (dired-next-subdir 1 t)))
+  (let ((modflag (buffer-modified-p)))
+    (while (>=  (setq arg (1- arg)) 0)
+      (let* ((cur-dir (dired-current-directory))
+	     (hidden-p (dired-subdir-hidden-p cur-dir))
+	     (elt (assoc cur-dir dired-subdir-alist))
+	     (end-pos (1- (dired-get-subdir-max elt)))
+	     buffer-read-only)
+	;; keep header line visible, hide rest
+	(goto-char (dired-get-subdir-min elt))
+	(skip-chars-forward "^\n\r")
+	(if hidden-p
+	    (subst-char-in-region (point) end-pos ?\r ?\n)
+	  (subst-char-in-region (point) end-pos ?\n ?\r)))
+      (dired-next-subdir 1 t))
+    (restore-buffer-modified-p modflag)))
 
 ;;;###autoload
 (defun dired-hide-all (arg)
@@ -2098,7 +2134,8 @@
 Use \\[dired-hide-subdir] to (un)hide a particular subdirectory."
   (interactive "P")
   (dired-hide-check)
-  (let (buffer-read-only)
+  (let ((modflag (buffer-modified-p))
+	buffer-read-only)
     (if (save-excursion
 	  (goto-char (point-min))
 	  (search-forward "\r" nil t))
@@ -2107,7 +2144,7 @@
       ;; hide
       (let ((pos (point-max))		; pos of end of last directory
 	    (alist dired-subdir-alist))
-	(while alist			; while there are dirs before pos
+	(while alist		        ; while there are dirs before pos
 	  (subst-char-in-region (dired-get-subdir-min (car alist)) ; pos of prev dir
 				(save-excursion
 				  (goto-char pos) ; current dir
@@ -2116,7 +2153,8 @@
 				  (point))
 				?\n ?\r)
 	  (setq pos (dired-get-subdir-min (car alist)))	; prev dir gets current dir
-	  (setq alist (cdr alist)))))))
+	  (setq alist (cdr alist)))))
+    (restore-buffer-modified-p modflag)))
 
 ;;;###end dired-ins.el
 
--- a/lisp/dired-x.el	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/dired-x.el	Mon Jun 07 08:00:27 2004 +0000
@@ -50,7 +50,7 @@
 ;; (add-hook 'dired-mode-hook
 ;;           (function (lambda ()
 ;;                       ;; Set buffer-local variables here.  For example:
-;;                       ;; (setq dired-omit-files-p t)
+;;                       ;; (dired-omit-mode 1)
 ;;                       )))
 ;;
 ;; At load time dired-x.el will install itself, redefine some functions, and
@@ -74,7 +74,7 @@
 ;;      dired-guess-shell-znew-switches
 ;;      dired-guess-shell-alist-user
 ;;      dired-clean-up-buffers-too
-;;      dired-omit-files-p
+;;      dired-omit-mode
 ;;      dired-omit-files
 ;;      dired-omit-extensions
 ;;      dired-omit-size-limit
@@ -154,19 +154,27 @@
 		 (other :tag "non-writable only" if-file-read-only))
   :group 'dired-x)
 
-(defcustom dired-omit-files-p nil
-  "*If non-nil, \"uninteresting\" files are not listed (buffer-local).
-Use \\[dired-omit-toggle] to toggle its value.
+(define-minor-mode dired-omit-mode
+  "Toggle Dired-Omit mode.
+With numeric ARG, enable Dired-Omit mode if ARG is positive, disable
+otherwise. Enabling and disabling is buffer-local.
+If enabled, \"uninteresting\" files are not listed.
 Uninteresting files are those whose filenames match regexp `dired-omit-files',
 plus those ending with extensions in `dired-omit-extensions'."
-  :type 'boolean
-  :group 'dired-x)
-(make-variable-buffer-local 'dired-omit-files-p)
+  :group 'dired-x
+  (if dired-omit-mode
+      ;; This will mention how many lines were omitted:
+      (let ((dired-omit-size-limit nil)) (dired-omit-expunge))
+    (revert-buffer)))
+
+;; For backward compatibility
+(defvaralias 'dired-omit-files-p 'dired-omit-mode)
+(make-obsolete-variable 'dired-omit-files-p 'dired-omit-mode)
 
 (defcustom dired-omit-files "^\\.?#\\|^\\.$\\|^\\.\\.$"
   "*Filenames matching this regexp will not be displayed.
-This only has effect when `dired-omit-files-p' is t.  See interactive function
-`dired-omit-toggle' \(\\[dired-omit-toggle]\) and variable
+This only has effect when `dired-omit-mode' is t.  See interactive function
+`dired-omit-mode' \(\\[dired-omit-mode]\) and variable
 `dired-omit-extensions'.  The default is to omit  `.', `..', auto-save
 files and lock files."
   :type 'regexp
@@ -230,7 +238,8 @@
 
 ;;; KEY BINDINGS.
 
-(define-key dired-mode-map "\M-o" 'dired-omit-toggle)
+(define-key dired-mode-map "\M-o" 'dired-omit-mode)
+(define-key dired-mode-map "\M-O" 'dired-mark-omitted)
 (define-key dired-mode-map "\M-(" 'dired-mark-sexp)
 (define-key dired-mode-map "*(" 'dired-mark-sexp)
 (define-key dired-mode-map "*." 'dired-mark-extension)
@@ -268,7 +277,7 @@
   \\[dired-info]\t-- run info on file
   \\[dired-man]\t-- run man on file
   \\[dired-do-find-marked-files]\t-- visit all marked files simultaneously
-  \\[dired-omit-toggle]\t-- toggle omitting of files
+  \\[dired-omit-mode]\t-- toggle omitting of files
   \\[dired-mark-sexp]\t-- mark by Lisp expression
   \\[dired-copy-filename-as-kill]\t-- copy the file or subdir names into the kill ring.
   \t   You can feed it to other commands using \\[yank].
@@ -280,7 +289,7 @@
   `dired-bind-info'
   `dired-bind-man'
   `dired-vm-read-only-folders'
-  `dired-omit-files-p'
+  `dired-omit-mode'
   `dired-omit-files'
   `dired-omit-extensions'
   `dired-omit-size-limit'
@@ -450,9 +459,9 @@
                 (dired-insert-subdir (file-name-directory file))
                 (dired-goto-file file))
               ;; Toggle omitting, if it is on, and try again.
-	      (if dired-omit-files-p
+	      (if dired-omit-mode
 		  (progn
-		    (dired-omit-toggle)
+		    (dired-omit-mode)
 		    (dired-goto-file file))))))))
 
 (defun dired-jump-other-window ()
@@ -479,31 +488,18 @@
 Should never be used as marker by the user or other packages.")
 
 (defun dired-omit-startup ()
-  (or (assq 'dired-omit-files-p minor-mode-alist)
+  (or (assq 'dired-omit-mode minor-mode-alist)
       (setq minor-mode-alist
-            (append '((dired-omit-files-p
+            (append '((dired-omit-mode
 		       (:eval (if (eq major-mode 'dired-mode)
 				  " Omit" ""))))
 		    minor-mode-alist))))
 
-(defun dired-omit-toggle (&optional flag)
-  "Toggle omitting files matching `dired-omit-files' and `dired-omit-extensions'.
-With an arg, and if omitting was off, don't toggle and just mark the
-  files but don't actually omit them.
-With an arg, and if omitting was on, turn it off but don't refresh the buffer."
-  (interactive "P")
-  (if flag
-      (if dired-omit-files-p
-          (setq dired-omit-files-p (not dired-omit-files-p))
-        (dired-mark-unmarked-files (dired-omit-regexp) nil nil
-                                   dired-omit-localp))
-    ;; no FLAG
-    (setq dired-omit-files-p (not dired-omit-files-p))
-    (if (not dired-omit-files-p)
-        (revert-buffer)
-      ;; this will mention how many were omitted:
-      (let ((dired-omit-size-limit nil))
-        (dired-omit-expunge)))))
+(defun dired-mark-omitted ()
+  "Mark files matching `dired-omit-files' and `dired-omit-extensions'."
+  (interactive)
+  (let ((dired-omit-mode nil)) (revert-buffer)) ;; Show omitted files
+  (dired-mark-unmarked-files (dired-omit-regexp) nil nil dired-omit-localp))
 
 (defvar dired-omit-extensions
   (append completion-ignored-extensions
@@ -515,12 +511,12 @@
 `dired-latex-unclean-extensions', `dired-bibtex-unclean-extensions', and
 `dired-texinfo-unclean-extensions'.
 
-See interactive function `dired-omit-toggle' \(\\[dired-omit-toggle]\) and
-variables `dired-omit-files-p' and `dired-omit-files'.")
+See interactive function `dired-omit-mode' \(\\[dired-omit-mode]\) and
+variables `dired-omit-mode' and `dired-omit-files'.")
 
 (defun dired-omit-expunge (&optional regexp)
   "Erases all unmarked files matching REGEXP.
-Does nothing if global variable `dired-omit-files-p' is nil, or if called
+Does nothing if global variable `dired-omit-mode' is nil, or if called
   non-interactively and buffer is bigger than `dired-omit-size-limit'.
 If REGEXP is nil or not specified, uses `dired-omit-files', and also omits
   filenames ending in `dired-omit-extensions'.
@@ -529,14 +525,14 @@
 This functions works by temporarily binding `dired-marker-char' to
 `dired-omit-marker-char' and calling `dired-do-kill-lines'."
   (interactive "sOmit files (regexp): ")
-  (if (and dired-omit-files-p
+  (if (and dired-omit-mode
            (or (interactive-p)
                (not dired-omit-size-limit)
                (< (buffer-size) dired-omit-size-limit)
 	       (progn
 		 (message "Not omitting: directory larger than %d characters."
 			  dired-omit-size-limit)
-		 (setq dired-omit-files-p nil)
+		 (setq dired-omit-mode nil)
 		 nil)))
       (let ((omit-re (or regexp (dired-omit-regexp)))
             (old-modified-p (buffer-modified-p))
@@ -589,7 +585,7 @@
 (defun dired-omit-new-add-entry (filename &optional marker-char relative)
   ;; This redefines dired-aux.el's dired-add-entry to avoid calling ls for
   ;; files that are going to be omitted anyway.
-  (if dired-omit-files-p
+  (if dired-omit-mode
       ;; perhaps return t without calling ls
       (let ((omit-re (dired-omit-regexp)))
         (if (or (string= omit-re "")
@@ -842,7 +838,7 @@
     (save-excursion
       (set-buffer (get-buffer-create " *dot-dired*"))
       (erase-buffer)
-      (insert "Local Variables:\ndired-omit-files-p: t\nEnd:\n")
+      (insert "Local Variables:\ndired-omit-mode: t\nEnd:\n")
       (write-file dired-local-variables-file)
       (kill-buffer (current-buffer)))
 
@@ -1692,7 +1688,7 @@
    'dired-guess-shell-znew-switches
    'dired-guess-shell-alist-user
    'dired-clean-up-buffers-too
-   'dired-omit-files-p
+   'dired-omit-mode
    'dired-omit-files
    'dired-omit-extensions
    )
--- a/lisp/dired.el	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/dired.el	Mon Jun 07 08:00:27 2004 +0000
@@ -60,6 +60,10 @@
   :type 'string
   :group 'dired)
 
+(defvar dired-subdir-switches nil
+  "If non-nil, switches passed to `ls' for inserting subdirectories.
+If nil, `dired-listing-switches' is used.")
+
 ; Don't use absolute file names as /bin should be in any PATH and people
 ; may prefer /usr/local/gnu/bin or whatever.  However, chown is
 ; usually not in PATH.
@@ -274,13 +278,18 @@
 (defvar dired-re-perms "[-bcdlps][-r][-w].[-r][-w].[-r][-w].")
 (defvar dired-re-dot "^.* \\.\\.?/?$")
 
-;; The subdirectory names in this list are expanded.
+;; The subdirectory names in the next two lists are expanded.
 (defvar dired-subdir-alist nil
   "Association list of subdirectories and their buffer positions.
 Each subdirectory has an element: (DIRNAME . STARTMARKER).
 The order of elements is the reverse of the order in the buffer.
 In simple cases, this list contains one element.")
 
+(defvar dired-switches-alist nil
+  "Keeps track of which switches to use for inserted subdirectories.
+This is an alist of the form (SUBDIR . SWITCHES).")
+(make-variable-buffer-local 'dired-switches-alist)
+
 (defvar dired-subdir-regexp "^. \\([^\n\r]+\\)\\(:\\)[\n\r]"
   "Regexp matching a maybe hidden subdirectory line in `ls -lR' output.
 Subexpression 1 is the subdirectory proper, no trailing colon.
@@ -961,7 +970,14 @@
 	  (condition-case ()
 	      (progn
 		(dired-uncache dir)
-		(dired-insert-subdir dir))
+		(dired-insert-subdir dir)
+		(let ((switches (cdr (assoc-string dir dired-switches-alist))))
+		  (and switches
+		       (string-match "R" switches)
+		       (dolist (cur-ass (copy-sequence old-subdir-alist))
+			 (when (dired-in-this-tree (car cur-ass) dir)
+			   (setq old-subdir-alist
+				 (delete cur-ass old-subdir-alist)))))))
 	    (error nil))))))
 
 (defun dired-uncache (dir)
@@ -1406,6 +1422,7 @@
        '(dired-font-lock-keywords t nil nil beginning-of-line))
   (set (make-local-variable 'desktop-save-buffer)
        'dired-desktop-buffer-misc-data)
+  (setq dired-switches-alist nil)
   (dired-sort-other dired-actual-switches t)
   (run-mode-hooks 'dired-mode-hook)
   (when (featurep 'x-dnd)
@@ -2073,7 +2090,7 @@
 			     (goto-char (match-beginning 0))
 			     (beginning-of-line)
 			     (point-marker))))
-      (if (> count 1)
+      (if (and (> count 1) (interactive-p))
 	  (message "Buffer includes %d directories" count))
       ;; We don't need to sort it because it is in buffer order per
       ;; constructionem.  Return new alist:
@@ -3274,16 +3291,16 @@
       nil)))
 
 (defun dired-dnd-popup-notice ()
-  (x-popup-dialog 
+  (x-popup-dialog
    t
-   '("Recursive copies not enabled.\nSee variable dired-recursive-copies." 
+   '("Recursive copies not enabled.\nSee variable dired-recursive-copies."
      ("Ok" . nil))))
 
 
 (defun dired-dnd-do-ask-action (uri)
   ;; No need to get actions and descriptions from the source,
   ;; we only have three actions anyway.
-  (let ((action (x-popup-menu 
+  (let ((action (x-popup-menu
 		 t
 		 (list "What action?"
 		       (cons ""
--- a/lisp/ediff.el	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/ediff.el	Mon Jun 07 08:00:27 2004 +0000
@@ -1474,6 +1474,53 @@
 		   (set-window-buffer ctl-window ctl-buf)))))))
 
 
+(dolist (mess '("^Errors in diff output. Diff output is in "
+                "^Hmm... I don't see an Ediff command around here...$"
+                "^Undocumented command! Type `G' in Ediff Control Panel to drop a note to the Ediff maintainer$"
+                ": This command runs in Ediff Control Buffer only!$"
+                ": Invalid op in ediff-check-version$"
+                "^ediff-shrink-window-C can be used only for merging jobs$"
+                "^Lost difference info on these directories$"
+                "^This command is inapplicable in the present context$"
+                "^This session group has no parent$"
+                "^Can't hide active session, $"
+                "^Ediff: something wrong--no multiple diffs buffer$"
+                "^Can't make context diff for Session $"
+                "^The patch buffer wasn't found$"
+                "^Aborted$"
+                "^This Ediff session is not part of a session group$"
+                "^No active Ediff sessions or corrupted session registry$"
+                "^No session info in this line$"
+                "^`.*' is not an ordinary file$"
+                "^Patch appears to have failed$"
+                "^Recomputation of differences cancelled$"
+                "^No fine differences in this mode$"
+                "^Lost connection to ancestor buffer...sorry$"
+                "^Not merging with ancestor$"
+                "^Don't know how to toggle read-only in buffer "
+                "Emacs is not running as a window application$"
+                "^This command makes sense only when merging with an ancestor$"
+                "^At end of the difference list$"
+                "^At beginning of the difference list$"
+                "^Nothing saved for diff .* in buffer "
+                "^Buffer is out of sync for file "
+                "^Buffer out of sync for file "
+                "^Output from `diff' not found$"
+                "^You forgot to specify a region in buffer "
+                "^All right. Make up your mind and come back...$"
+                "^Current buffer is not visiting any file$"
+                "^Failed to retrieve revision: $"
+                "^Can't determine display width.$"
+                "^File `.*' does not exist or is not readable$"
+                "^File `.*' is a directory$"
+                "^Buffer .* doesn't exist$"
+                "^Directories . and . are the same: "
+                "^Directory merge aborted$"
+                "^Merge of directory revisions aborted$"
+                "^Buffer .* doesn't exist$"
+                "^There is no file to merge$"
+                "^Version control package .*.el not found. Use vc.el instead$"))
+  (add-to-list 'debug-ignored-errors mess))
 
 
 ;;; Local Variables:
--- a/lisp/find-dired.el	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/find-dired.el	Mon Jun 07 08:00:27 2004 +0000
@@ -55,6 +55,16 @@
   :group 'find-dired)
 
 ;;;###autoload
+(defcustom find-ls-subdir-switches "-al"
+  "`ls' switches for inserting subdirectories in `*Find*' buffers.
+This should contain the \"-l\" switch.
+Use the \"-F\" or \"-b\" switches if and only if you also use
+them for `find-ls-option'."
+  :type 'string
+  :group 'find-dired
+  :version "21.4")
+
+;;;###autoload
 (defcustom find-grep-options
   (if (or (eq system-type 'berkeley-unix)
 	  (string-match "solaris2" system-configuration)
@@ -89,8 +99,7 @@
   (let ((dired-buffers dired-buffers))
     ;; Expand DIR ("" means default-directory), and make sure it has a
     ;; trailing slash.
-    (setq dir (abbreviate-file-name
-	       (file-name-as-directory (expand-file-name dir))))
+    (setq dir (file-name-as-directory (expand-file-name dir)))
     ;; Check that it's really a directory.
     (or (file-directory-p dir)
 	(error "find-dired needs a directory: %s" dir))
@@ -115,7 +124,7 @@
     (setq buffer-read-only nil)
     (erase-buffer)
     (setq default-directory dir
-	  find-args args		; save for next interactive call
+	  find-args args	      ; save for next interactive call
 	  args (concat find-dired-find-program " . "
 		       (if (string= args "")
 			   ""
@@ -143,6 +152,7 @@
       ;; this does no harm)
       (set (make-local-variable 'dired-subdir-alist)
 	   (list (cons default-directory (point-min-marker)))))
+    (set (make-local-variable 'dired-subdir-switches) find-ls-subdir-switches)
     (setq buffer-read-only nil)
     ;; Subdir headlerline must come first because the first marker in
     ;; subdir-alist points there.
@@ -267,6 +277,7 @@
 	      (delete-process proc)
 	      (force-mode-line-update)))
 	  (message "find-dired %s finished." (current-buffer))))))
+
 
 (provide 'find-dired)
 
--- a/lisp/help-fns.el	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/help-fns.el	Mon Jun 07 08:00:27 2004 +0000
@@ -239,7 +239,8 @@
 
 ;;;###autoload
 (defface help-argument-name '((((supports :slant italic)) :inherit italic))
-  "Face to highlight argument names in *Help* buffers.")
+  "Face to highlight argument names in *Help* buffers."
+  :group 'help)
 
 (defun help-default-arg-highlight (arg)
   "Default function to highlight arguments in *Help* buffers.
--- a/lisp/isearch.el	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/isearch.el	Mon Jun 07 08:00:27 2004 +0000
@@ -294,9 +294,7 @@
     (define-key map " " 'isearch-whitespace-chars)
     (define-key map [?\S-\ ] 'isearch-whitespace-chars)
 
-    (define-key map "\C-b" 'isearch-del-char)
-    (define-key map "\C-f" 'isearch-yank-char)
-    (define-key map "\C-w" 'isearch-yank-word)
+    (define-key map "\C-w" 'isearch-yank-word-or-char)
     (define-key map "\C-y" 'isearch-yank-line)
 
     ;; Define keys for regexp chars * ? |.
--- a/lisp/locate.el	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/locate.el	Mon Jun 07 08:00:27 2004 +0000
@@ -24,42 +24,7 @@
 
 ;;; Commentary:
 
-;; Search a database of files and use dired commands on
-;; the result.
-;;
-
-;;;;; Building a database of files ;;;;;;;;;
-;;
-;; You can create a simple files database with a port of the Unix find command
-;; and one of the various Windows NT various scheduling utilities,
-;; for example the AT command from the NT Resource Kit, WinCron which is
-;; included with Microsoft FrontPage, or the shareware NTCron program.
-;;
-;; To set up a function which searches the files database, do something
-;; like this:
-;;
-;; (defvar locate-fcodes-file       "c:/users/peter/fcodes")
-;; (defvar locate-make-command-line 'nt-locate-make-command-line)
-;;
-;; (defun nt-locate-make-command-line (arg)
-;;  (list "grep" "-i" arg locate-fcodes-file))
-;;
-;;;;;;;; ADVICE For dired-make-relative: ;;;;;;;;;
-;;
-;; For certain dired commands to work right, you should also include the
-;; following in your _emacs/.emacs:
-;;
-;; (defadvice dired-make-relative (before set-no-error activate)
-;;   "For locate mode and Windows, don't return errors"
-;;   (if (and (eq   major-mode  'locate-mode)
-;; 	   (memq system-type (list 'windows-nt 'ms-dos)))
-;;       (ad-set-arg 2 t)
-;;     ))
-;;
-;; Otherwise, `dired-make-relative' will give error messages like
-;; "FILENAME: not in directory tree growing at /"
-
-;;; Commentary:
+;; Search a database of files and use dired commands on the result.
 ;;
 ;; Locate.el provides an interface to a program which searches a
 ;; database of file names. By default, this program is the GNU locate
@@ -109,6 +74,38 @@
 ;; regular expression; this is often useful to constrain a big search.
 ;;
 
+;;;;; Building a database of files ;;;;;;;;;
+;;
+;; You can create a simple files database with a port of the Unix find command
+;; and one of the various Windows NT various scheduling utilities,
+;; for example the AT command from the NT Resource Kit, WinCron which is
+;; included with Microsoft FrontPage, or the shareware NTCron program.
+;;
+;; To set up a function which searches the files database, do something
+;; like this:
+;;
+;; (defvar locate-fcodes-file       "c:/users/peter/fcodes")
+;; (defvar locate-make-command-line 'nt-locate-make-command-line)
+;;
+;; (defun nt-locate-make-command-line (arg)
+;;  (list "grep" "-i" arg locate-fcodes-file))
+;;
+;;;;;;;; ADVICE For dired-make-relative: ;;;;;;;;;
+;;
+;; For certain dired commands to work right, you should also include the
+;; following in your _emacs/.emacs:
+;;
+;; (defadvice dired-make-relative (before set-no-error activate)
+;;   "For locate mode and Windows, don't return errors"
+;;   (if (and (eq   major-mode  'locate-mode)
+;; 	   (memq system-type (list 'windows-nt 'ms-dos)))
+;;       (ad-set-arg 2 t)
+;;     ))
+;;
+;; Otherwise, `dired-make-relative' will give error messages like
+;; "FILENAME: not in directory tree growing at /"
+
+
 ;;; Code:
 
 (eval-when-compile
@@ -154,6 +151,14 @@
   :type 'face
   :group 'locate)
 
+;;;###autoload
+(defcustom locate-ls-subdir-switches "-al"
+  "`ls' switches for inserting subdirectories in `*Locate*' buffers.
+This should contain the \"-l\" switch, but not the \"-F\" or \"-b\" switches."
+  :type 'string
+  :group 'locate
+  :version "21.4")
+
 (defcustom locate-update-command "updatedb"
   "The command used to update the locate database."
   :type 'string
@@ -223,24 +228,25 @@
     (save-window-excursion
       (set-buffer (get-buffer-create locate-buffer-name))
       (locate-mode)
-      (erase-buffer)
+      (let ((inhibit-read-only t))
+	(erase-buffer)
 
-      (setq locate-current-filter filter)
+	(setq locate-current-filter filter)
 
-      (if run-locate-command
-	  (shell-command search-string locate-buffer-name)
-	(apply 'call-process locate-cmd nil t nil locate-cmd-args))
+	(if run-locate-command
+	    (shell-command search-string locate-buffer-name)
+	  (apply 'call-process locate-cmd nil t nil locate-cmd-args))
 
-      (and filter
-	  (locate-filter-output filter))
+	(and filter
+	     (locate-filter-output filter))
 
-      (locate-do-setup search-string)
-      )
+	(locate-do-setup search-string)
+	))
     (and (not (string-equal (buffer-name) locate-buffer-name))
 	(switch-to-buffer-other-window locate-buffer-name))
 
     (run-hooks 'dired-mode-hook)
-    (dired-next-line 2)			;move to first matching file.
+    (dired-next-line 3)			;move to first matching file.
     (run-hooks 'locate-post-command-hook)
     )
   )
@@ -281,9 +287,10 @@
    (define-key locate-mode-map [menu-bar mark directories] 'undefined)
    (define-key locate-mode-map [menu-bar mark symlinks]    'undefined)
 
-   (define-key locate-mode-map [mouse-2]   'locate-mouse-view-file)
+   (define-key locate-mode-map [M-mouse-2] 'locate-mouse-view-file)
    (define-key locate-mode-map "\C-c\C-t"  'locate-tags)
 
+   (define-key locate-mode-map "l"       'locate-do-redisplay)
    (define-key locate-mode-map "U"       'dired-unmark-all-files)
    (define-key locate-mode-map "V"       'locate-find-directory)
 )
@@ -318,45 +325,74 @@
 	 (not (eq lineno 2))
 	 (buffer-substring (elt pos 0) (elt pos 1)))))
 
+(defun locate-main-listing-line-p ()
+  "Return t if current line contains a file name listed by locate.
+This function returns nil if the current line either contains no
+file name or is inside a subdirectory."
+  (save-excursion
+    (forward-line 0)
+    (looking-at (concat "."
+			(make-string (1- locate-filename-indentation) ?\ )
+			"\\(/\\|[A-Za-z]:\\)"))))
+
 (defun locate-mouse-view-file (event)
   "In Locate mode, view a file, using the mouse."
   (interactive "@e")
   (save-excursion
     (goto-char (posn-point (event-start event)))
-    (view-file (locate-get-filename))))
+    (if (locate-main-listing-line-p)
+	(view-file (locate-get-filename))
+      (message "This command only works inside main listing."))))
 
 ;; Define a mode for locate
 ;; Default directory is set to "/" so that dired commands, which
 ;; expect to be in a tree, will work properly
 (defun locate-mode ()
   "Major mode for the `*Locate*' buffer made by \\[locate].
+\\<locate-mode-map>\
 In that buffer, you can use almost all the usual dired bindings.
 \\[locate-find-directory] visits the directory of the file on the current line.
 
+Operating on listed files works, but does not always
+automatically update the buffer as in ordinary Dired.
+This is true both for the main listing and for subdirectories.
+Reverting the buffer using \\[revert-buffer] deletes all subdirectories.
+Specific `locate-mode' commands, such as \\[locate-find-directory],
+do not work in subdirectories.
+
 \\{locate-mode-map}"
+  ;; Not to be called interactively.
   (kill-all-local-variables)
-  ;; Avoid clobbering this variables
+  ;; Avoid clobbering this variable
   (make-local-variable 'dired-subdir-alist)
   (use-local-map             locate-mode-map)
   (setq major-mode          'locate-mode
         mode-name           "Locate"
-        default-directory   "/")
+        default-directory   "/"
+	buffer-read-only    t
+	selective-display   t)
   (dired-alist-add-1 default-directory (point-min-marker))
+  (set (make-local-variable 'dired-directory) "/")
+  (set (make-local-variable 'dired-subdir-switches) locate-ls-subdir-switches)
+  (setq dired-switches-alist nil)
   (make-local-variable 'dired-move-to-filename-regexp)
   ;; This should support both Unix and Windoze style names
   (setq dired-move-to-filename-regexp
-	(concat "."
+	(concat "^."
 		(make-string (1- locate-filename-indentation) ?\ )
-		"\\(/\\|[A-Za-z]:\\)"))
+		"\\(/\\|[A-Za-z]:\\)\\|"
+		(default-value 'dired-move-to-filename-regexp)))
   (make-local-variable 'dired-actual-switches)
   (setq dired-actual-switches "")
   (make-local-variable 'dired-permission-flags-regexp)
   (setq dired-permission-flags-regexp
 	(concat "^.\\("
 		(make-string (1- locate-filename-indentation) ?\ )
-		"\\)"))
+		"\\)\\|"
+		(default-value 'dired-permission-flags-regexp)))
   (make-local-variable 'revert-buffer-function)
   (setq revert-buffer-function 'locate-update)
+  (set (make-local-variable 'page-delimiter) "\n\n")
   (run-hooks 'locate-mode-hook))
 
 (defun locate-do-setup (search-string)
@@ -386,7 +422,10 @@
       (dired-insert-set-properties (elt pos 0) (elt pos 1)))))
 
 (defun locate-insert-header (search-string)
-  (let ((locate-format-string "Matches for %s")
+  ;; There needs to be a space before `Matches, because otherwise,
+  ;; `*!" would erase the `M'.  We can not use two spaces, or the line
+  ;; would mistakenly fit `dired-subdir-regexp'.
+  (let ((locate-format-string "  /:\n Matches for %s")
 	(locate-regexp-match
 	 (concat " *Matches for \\(" (regexp-quote search-string) "\\)"))
 	(locate-format-args (list search-string))
@@ -424,6 +463,7 @@
 
     (save-excursion
       (goto-char (point-min))
+      (forward-line 1)
       (if (not (looking-at locate-regexp-match))
 	  nil
 	(add-text-properties (match-beginning 1) (match-end 1)
@@ -439,9 +479,11 @@
 (defun locate-tags ()
   "Visit a tags table in `*Locate*' mode."
   (interactive)
-  (let ((tags-table (locate-get-filename)))
-    (and (y-or-n-p (format "Visit tags table %s? " tags-table))
-	 (visit-tags-table tags-table))))
+  (if (locate-main-listing-line-p)
+      (let ((tags-table (locate-get-filename)))
+	(and (y-or-n-p (format "Visit tags table %s? " tags-table))
+	     (visit-tags-table tags-table)))
+    (message "This command only works inside main listing.")))
 
 ;; From Stephen Eglen <stephen@cns.ed.ac.uk>
 (defun locate-update (ignore1 ignore2)
@@ -460,12 +502,14 @@
 (defun locate-find-directory ()
   "Visit the directory of the file mentioned on this line."
   (interactive)
-  (let ((directory-name (locate-get-dirname)))
-    (if (file-directory-p directory-name)
-	(find-file directory-name)
-      (if (file-symlink-p directory-name)
-	  (error "Directory is a symlink to a nonexistent target")
-	(error "Directory no longer exists; run `updatedb' to update database")))))
+  (if (locate-main-listing-line-p)
+      (let ((directory-name (locate-get-dirname)))
+	(if (file-directory-p directory-name)
+	    (find-file directory-name)
+	  (if (file-symlink-p directory-name)
+	      (error "Directory is a symlink to a nonexistent target")
+	    (error "Directory no longer exists; run `updatedb' to update database"))))
+    (message "This command only works inside main listing.")))
 
 (defun locate-find-directory-other-window ()
   "Visit the directory of the file named on this line in other window."
@@ -518,6 +562,14 @@
 				 string))))))
     (locate search-string)))
 
+(defun locate-do-redisplay (&optional arg test-for-subdir)
+  "Like `dired-do-redisplay', but adapted for `*Locate*' buffers."
+  (interactive "P\np")
+  (if (string= (dired-current-directory) "/")
+      (message "This command only works in subdirectories.")
+    (let ((dired-actual-switches locate-ls-subdir-switches))
+      (dired-do-redisplay arg test-for-subdir))))
+
 (provide 'locate)
 
 ;;; arch-tag: 60c4d098-b5d5-4b3c-a3e0-51a2e9f43898
--- a/lisp/ps-print.el	Mon Jun 07 07:10:59 2004 +0000
+++ b/lisp/ps-print.el	Mon Jun 07 08:00:27 2004 +0000
@@ -1262,7 +1262,7 @@
 ;;	 N-up printing.
 ;;	 Hook: `ps-print-begin-sheet-hook'.
 ;;
-;; [keinichi] 19990509 Kein'ichi Handa <handa@etl.go.jp>
+;; [kenichi] 19990509 Ken'ichi Handa <handa@m17n.org>
 ;;
 ;;    `ps-print-region-function'
 ;;
@@ -1275,7 +1275,7 @@
 ;;	 PostScript prologue header comment insertion.
 ;;	 Skip invisible text better.
 ;;
-;; [keinichi] 19980819 Kein'ichi Handa <handa@etl.go.jp>
+;; [kenichi] 19980819 Ken'ichi Handa <handa@m17n.org>
 ;;
 ;;    Multi-byte buffer handling.
 ;;
@@ -1383,7 +1383,7 @@
 ;; prologue code suggestion, for odd/even printing suggestion and for
 ;; `ps-prologue-file' enhancement.
 ;;
-;; Thanks to Kein'ichi Handa <handa@etl.go.jp> for multi-byte buffer handling.
+;; Thanks to Ken'ichi Handa <handa@m17n.org> for multi-byte buffer handling.
 ;;
 ;; Thanks to Matthew O Persico <Matthew.Persico@lazard.com> for line number on
 ;; empty columns.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/toolbar/README	Mon Jun 07 08:00:27 2004 +0000
@@ -0,0 +1,8 @@
+The following icons are from GTK+ 2.x:
+
+    close.xpm copy.xpm cut.xpm help.xpm home.xpm
+    index.xpm jump_to.xpm left_arrow.xpm new.xpm open.xpm
+    paste.xpm preferences.xpm print.xpm right_arrow.xpm save.xpm
+    saveas.xpm search.xpm spell.xpm undo.xpm up_arrow.xpm
+
+They are not part of Emacs, but distributed and used by Emacs.
Binary file lisp/toolbar/alias.pbm has changed
Binary file lisp/toolbar/close.pbm has changed
Binary file lisp/toolbar/copy.pbm has changed
Binary file lisp/toolbar/cut.pbm has changed
Binary file lisp/toolbar/help.pbm has changed
Binary file lisp/toolbar/home.pbm has changed
Binary file lisp/toolbar/index.pbm has changed
Binary file lisp/toolbar/jump_to.pbm has changed
Binary file lisp/toolbar/left_arrow.pbm has changed
Binary file lisp/toolbar/new.pbm has changed
Binary file lisp/toolbar/open.pbm has changed
Binary file lisp/toolbar/paste.pbm has changed
Binary file lisp/toolbar/preferences.pbm has changed
Binary file lisp/toolbar/print.pbm has changed
Binary file lisp/toolbar/right_arrow.pbm has changed
Binary file lisp/toolbar/save.pbm has changed
Binary file lisp/toolbar/saveas.pbm has changed
Binary file lisp/toolbar/search.pbm has changed
Binary file lisp/toolbar/spell.pbm has changed
Binary file lisp/toolbar/undo.pbm has changed
Binary file lisp/toolbar/up_arrow.pbm has changed
--- a/lispref/ChangeLog	Mon Jun 07 07:10:59 2004 +0000
+++ b/lispref/ChangeLog	Mon Jun 07 08:00:27 2004 +0000
@@ -1,3 +1,11 @@
+2004-06-05  Richard M. Stallman  <rms@gnu.org>
+
+	* minibuf.texi (Minibuffer Completion): For INITIAL arg,
+	refer the user to the Initial Input node.
+	(Text from Minibuffer): Likewise.
+	(Initial Input): New node.  Document this feature
+	and say it is mostly deprecated.
+
 2004-05-30  Richard M. Stallman  <rms@gnu.org>
 
 	* loading.texi (Named Features): Clarify return value
--- a/lispref/minibuf.texi	Mon Jun 07 07:10:59 2004 +0000
+++ b/lispref/minibuf.texi	Mon Jun 07 08:00:27 2004 +0000
@@ -23,6 +23,7 @@
 * Object from Minibuffer::    How to read a Lisp object or expression.
 * Minibuffer History::	      Recording previous minibuffer inputs
 				so the user can reuse them.
+* Initial Input::             Specifying initial contents for the minibuffer.
 * Completion::                How to invoke and customize completion.
 * Yes-or-No Queries::         Asking a question with a simple answer.
 * Multiple Queries::	      Asking a series of similar questions.
@@ -168,25 +169,9 @@
 Representations}) from whichever buffer was current before entering the
 minibuffer.
 
-If @var{initial-contents} is a string, @code{read-from-minibuffer}
-inserts it into the minibuffer, leaving point at the end, before the
-user starts to edit the text.  The minibuffer appears with this text as
-its initial contents.
-
-Alternatively, @var{initial-contents} can be a cons cell of the form
-@code{(@var{string} . @var{position})}.  This means to insert
-@var{string} in the minibuffer but put point at @emph{one-indexed}
-@var{position} in the minibuffer, rather than at the end.  Any integer
-value less or equal to one puts point at the beginning of the string.
-
-@strong{Usage note:} The @var{initial-contents} argument and the
-@var{default} argument are two alternative features for more or less the
-same job.  It does not make sense to use both features in a single call
-to @code{read-from-minibuffer}.  In general, we recommend using
-@var{default}, since this permits the user to insert the default value
-when it is wanted, but does not burden the user with deleting it from
-the minibuffer on other occasions.  For an exception to this rule,
-see @ref{Minibuffer History}.
+Use of @var{initial-contents} is mostly deprecated; we recommend using
+a non-@code{nil} value only in conjunction with specifying a cons cell
+for @var{hist}.  @xref{Initial Input}.
 @end defun
 
 @defun read-string prompt &optional initial history default inherit-input-method
@@ -440,9 +425,11 @@
 the most recent element of the history list in the minibuffer.  If you
 specify a positive @var{startpos}, the minibuffer history functions
 behave as if @code{(elt @var{variable} (1- @var{STARTPOS}))} were the
-history element currently shown in the minibuffer.  For consistency,
-you should also specify that element of the history as the initial
-minibuffer contents.
+history element currently shown in the minibuffer.
+
+For consistency, you should also specify that element of the history
+as the initial minibuffer contents, using the @var{initial} argument
+to the minibuffer input function (@pxref{Initial Input}).
 @end table
 
   If you don't specify @var{hist}, then the default history list
@@ -506,6 +493,45 @@
 A history list for arguments that are Lisp expressions to evaluate.
 @end defvar
 
+@node Initial Input
+@section Initial Input
+
+Several of the functions for minibuffer input have an argument called
+@var{initial} or @var{initial-contents}.  This is a mostly-deprecated
+feature for specifiying that the minibuffer should start out with
+certain text, instead of empty as usual.
+
+If @var{initial} is a string, the minibuffer starts out containing the
+text of the string, with point at the end, when the user starts to
+edit the text.  If the user simply types @key{RET} to exit the
+minibuffer, it will use the initial input string to determine the
+value to return.
+
+@strong{We discourage use of a non-@code{nil} value for
+@var{initial}}, because initial input is an intrusive interface.
+History lists and default values provide a much more convenient method
+to offer useful default inputs to the user.
+
+There is just one situation where you should specify a string for an
+@var{initial} argument.  This is when you specify a cons cell for the
+@var{hist} or @var{history} argument.  @xref{Minibuffer History}.
+
+@var{initial} can also be a cons cell of the form @code{(@var{string}
+. @var{position})}.  This means to insert @var{string} in the
+minibuffer but put point at @var{position} within the string's text.
+
+As a historical accident, @var{position} was implemented
+inconsistently in different functions.  In @code{completing-read},
+@var{position}'s value is interpreted as origin-zero; that is, a value
+of 0 means the beginning of the string, 1 means after the first
+character, etc.  In @code{read-minibuffer}, and the other
+non-completion minibuffer input functions that support this argument,
+1 means the beginning of the string 2 means after the first character,
+etc.
+
+Use of a cons cell as the value for @var{initial} arguments is
+deprecated in user code.
+ 
 @node Completion
 @section Completion
 @cindex completion
@@ -797,22 +823,10 @@
 saving the input and for minibuffer history commands.  It defaults to
 @code{minibuffer-history}.  @xref{Minibuffer History}.
 
-If @var{initial} is non-@code{nil}, @code{completing-read} inserts it
-into the minibuffer as part of the input, with point at the end.  Then
-it allows the user to edit the input, providing several commands to
-attempt completion.  @var{initial} can also be a cons cell of the form
-@code{(@var{string} .  @var{position})}.  In that case, point is put at
-@emph{zero-indexed} position @var{position} in @var{string}.  Note
-that this is different from @code{read-from-minibuffer} and related
-functions, which use a one-indexed position.  In most cases, we
-recommend using @var{default}, and not @var{initial}.
-
-@strong{We discourage use of a non-@code{nil} value for
-@var{initial}}, because it is an intrusive interface.  The history
-list feature (which did not exist when we introduced @var{initial})
-offers a far more convenient and general way for the user to get the
-default and edit it, and it is always available.  For an exception to
-this rule, see @ref{Minibuffer History}.
+The argument @var{initial} is mostly deprecated; we recommend using a
+non-@code{nil} value only in conjunction with specifying a cons cell
+for @var{hist}.  @xref{Initial Input}.  For default input, use
+@var{default} instead.
 
 If the argument @var{inherit-input-method} is non-@code{nil}, then the
 minibuffer inherits the current input method (@pxref{Input
--- a/man/ChangeLog	Mon Jun 07 07:10:59 2004 +0000
+++ b/man/ChangeLog	Mon Jun 07 08:00:27 2004 +0000
@@ -1,3 +1,11 @@
+2004-06-05  Lars Hansen  <larsh@math.ku.dk>
+
+	* dired-x.texi (variable dired-omit-mode): Rename from
+	dired-omit-files-p.
+	(function dired-omit-mode): Rename from dired-omit-toggle.
+	Call dired-omit-mode rather than set dired-omit-files-p.
+	(dired-mark-omitted): Describe command.
+
 2004-05-29  Michael Albinus  <michael.albinus@gmx.de>
 
 	Version 2.0.41 of Tramp released.
--- a/man/dired-x.texi	Mon Jun 07 07:10:59 2004 +0000
+++ b/man/dired-x.texi	Mon Jun 07 08:00:27 2004 +0000
@@ -270,7 +270,7 @@
 (add-hook 'dired-mode-hook
           (lambda ()
             ;; Set dired-x buffer-local variables here.  For example:
-            ;; (setq dired-omit-files-p t)
+            ;; (dired-omit-mode 1)
             ))
 @end example
 
@@ -394,16 +394,19 @@
 @table @kbd
 @item M-o
 @kindex M-o
-@findex dired-omit-toggle
-(@code{dired-omit-toggle}) Toggle between displaying and omitting
-``uninteresting'' files.  With a prefix argument, just mark
-the files, but don't actually omit them.
+@findex dired-omit-mode
+(@code{dired-omit-mode}) Toggle between displaying and omitting
+``uninteresting'' files.
+@item M-O
+@kindex M-O
+@findex dired-mark-omitted
+(@code{dired-mark-omitted}) Mark ``uninteresting'' files.
 @end table
 
 @noindent
 In order to make Dired Omit work you first need to load @file{dired-x.el}
-inside @code{dired-load-hook} (@pxref{Installation}) and then set
-@code{dired-omit-files-p} in some way (@pxref{Omitting Variables}).
+inside @code{dired-load-hook} (@pxref{Installation}) and then evaluate
+@code{(dired-omit-mode 1)} in some way (@pxref{Omitting Variables}).
 
 @ifinfo
 @menu
@@ -423,8 +426,8 @@
 
 @table @code
 
-@vindex dired-omit-files-p
-@item dired-omit-files-p
+@vindex dired-omit-mode
+@item dired-omit-mode
 
 Default: @code{nil}
 
@@ -432,11 +435,11 @@
 If non-@code{nil}, ``uninteresting'' files are not listed.
 Uninteresting files are those whose files whose names match regexp
 @code{dired-omit-files}, plus those ending with extensions in
-@code{dired-omit-extensions}.  @kbd{M-o} (@code{dired-omit-toggle})
+@code{dired-omit-extensions}.  @kbd{M-o} (@code{dired-omit-mode})
 toggles its value, which is buffer-local.  Put
 
 @example
-(setq dired-omit-files-p t)
+(dired-omit-mode 1)
 @end example
 
 @noindent
@@ -449,7 +452,7 @@
 
 @example
 Local Variables:
-dired-omit-files-p: t
+dired-omit-mode: t
 End:
 @end example
 
@@ -473,7 +476,7 @@
 Default: @code{"^#\\|\\.$"}
 
 Files whose names match this buffer-local regexp will not be displayed.
-This only has effect when @code{dired-omit-files-p}'s value is @code{t}.
+This only has effect when @code{dired-omit-mode}'s value is @code{t}.
 
 The default value omits the special directories @file{.} and @file{..}  and
 autosave files (plus other files ending in @file{.}) (@pxref{Omitting Examples}).
@@ -604,7 +607,7 @@
 @example
 Local Variables:
 dired-actual-switches: "-lat"
-dired-omit-files-p: t
+dired-omit-mode: t
 End:
 @end example
 
--- a/nt/ChangeLog	Mon Jun 07 07:10:59 2004 +0000
+++ b/nt/ChangeLog	Mon Jun 07 08:00:27 2004 +0000
@@ -1,3 +1,12 @@
+2004-06-06  Juanma Barranquero  <lektu@terra.es>
+
+	* makefile.w32-in (bootstrap-nmake): When nmake'ing bootstrap on
+	the lisp/ directory, set SHELL to $(SHELLTYPE); this avoids
+	calling non-existent cmdproxy.exe on boostrappings after a
+	previous install followed by realclean.
+
+	* nmake.defs: Add quote in comment to resync font-locking.
+
 2004-06-04  Juanma Barranquero  <lektu@terra.es>
 
 	* INSTALL: Reword the section on image support.  Add reference to
@@ -14,7 +23,7 @@
 	* makefile.nt, ebuild.bat, install.bat, fast-install.bat:
 	* makefile.def: Remove.
 
-	* nmake.defs (SYS_LDFLAGS): Add -nologo
+	* nmake.defs (SYS_LDFLAGS): Add -nologo.
 
 	* makefile.w32-in (info-gmake, info-nmake): New targets.
 	(info): Use them.
@@ -29,7 +38,7 @@
 
 2004-04-10  Benjamin Riefenstahl  <Benjamin.Riefenstahl@epost.de>
 
-	* runemacs.c (WinMain): Let emacs environment default to parent.
+	* runemacs.c (WinMain): Let Emacs environment default to parent.
 
 2004-03-11  Jason Rumney  <jasonr@gnu.org>
 
@@ -50,7 +59,7 @@
 
 2003-11-22  Lars Hansen  <larsh@math.ku.dk>
 
-	* inc/grp.h: Added.
+	* inc/grp.h: New file.
 
 2003-09-03  Peter Runestig  <peter@runestig.com>
 
@@ -186,7 +195,7 @@
 	* INSTALL: Update table of versions of make that are suitable
 	for building Emacs, based on recent feedback.
 
-	* TODO, _emacs, emacs.bat.in, debug.bat.in: Removed.
+	* TODO, _emacs, emacs.bat.in, debug.bat.in: Remove.
 
 2001-11-19  Andrew Innes  <andrewi@gnu.org>
 
--- a/nt/makefile.w32-in	Mon Jun 07 07:10:59 2004 +0000
+++ b/nt/makefile.w32-in	Mon Jun 07 08:00:27 2004 +0000
@@ -139,7 +139,7 @@
 	$(MAKE) $(MFLAGS) bootstrap
 	$(MAKE) $(MFLAGS) bootstrap-clean
 	cd ..\lisp
-	$(MAKE) $(MFLAGS) bootstrap
+	$(MAKE) $(MFLAGS) SHELL=$(SHELLTYPE) bootstrap
 	cd ..\lib-src
 	$(MAKE) $(MFLAGS) DOC
 	cd ..\nt
--- a/nt/nmake.defs	Mon Jun 07 07:10:59 2004 +0000
+++ b/nt/nmake.defs	Mon Jun 07 08:00:27 2004 +0000
@@ -161,6 +161,7 @@
 FORDO		= ) do
 ENDFOR		=
 ARGQUOTE	= "
+# "
 DQUOTE		= \"
 DEL		= rm
 DEL_TREE	= rm -r
--- a/src/ChangeLog	Mon Jun 07 07:10:59 2004 +0000
+++ b/src/ChangeLog	Mon Jun 07 08:00:27 2004 +0000
@@ -1,3 +1,62 @@
+2004-06-07  Miles Bader  <miles@gnu.org>
+
+	* (struct named_merge_point): New type.
+	(push_named_merge_point): New function.
+	(merge_named_face): New function.
+	(merge_face_ref, face_at_buffer_position, face_at_string_position):
+	Use `merge_named_face'.
+	(merge_face_inheritance): Function removed.
+	(merge_face_ref): Renamed from `merge_face_vector_with_property'.
+	Add new `err_msgs' and `named_merge_points' args.  Return error
+	status.  Only print error messages if ERR_MSGS is true.  Don't try to
+	do :inherit attribute validation.
+	(merge_face_heights): Handle `unspecified' in both directions.
+	(merge_face_vectors): Rename `cycle_check' arg to `named_merge_points'.
+	Call `merge_face_ref' instead of `merge_face_inheritance'.
+	(Fdisplay_supports_face_attributes_p, Fface_attributes_as_vector)
+	(compute_char_face, face_at_buffer_position)
+	(face_at_string_position): Call `merge_face_ref' instead of
+	`merge_face_vector_with_property'.
+
+2004-06-07  Kenichi Handa  <handa@m17n.org>
+
+	* coding.c (find_safe_codings): Check NILP (safe_codings) only at
+	the necessary places.
+
+2004-06-07  Kim F. Storm  <storm@cua.dk>
+
+	* process.c (Fdelete_process): Undo 2004-05-28 change.
+	Instead, call status_notify also for network process.
+	(status_message): Use process instead of status as arg.
+	Give messages "deleted" or "connection broken by remote peer" for
+	an exited network process.
+	(status_notify): Change call to status_message.
+	(read_process_output): Increase readmax to 4096.  Do not increase
+	buffer size for datagram channels (default is now large enough).
+
+2004-06-06  Steven Tamm  <tamm@Steven-Tamms-Computer.local>
+
+	* macfns.c (x_create_tip_frame): Fix Mac OS X 10.1 compilation
+	problem due to newly defined variable.
+
+2004-06-06  Miles Bader  <miles@gnu.org>
+
+	* xfaces.c (Fdisplay_supports_face_attributes_p): Give up
+	immediately if non-interactive or not initialized.
+
+2004-06-05  Richard M. Stallman  <rms@gnu.org>
+
+	* minibuf.c (Fcompleting_read): Doc fix.
+
+2004-06-05  Andreas Schwab  <schwab@suse.de>
+
+	* macfns.c (x_create_tip_frame): Fix declaration after statement.
+
+2004-06-05  Juanma Barranquero  <lektu@terra.es>
+
+	* keymap.c (Fdescribe_vector): Fix docstring.
+	(Fkey_description, Fglobal_key_binding): Fix typo in docstring.
+
 2004-06-05  Miles Bader  <miles@gnu.org>
 
 	* xfaces.c (tty_supports_face_attributes_p): Make sure the specified
@@ -18,7 +77,7 @@
 	(Ftty_supports_face_attributes_p): Function deleted.
 	(Fdisplay_supports_face_attributes_p): New function.
 	(syms_of_xfaces): Initialize Sdisplay_supports_face_attributes_p.
-	(face_attr_equal_p): New function
+	(face_attr_equal_p): New function.
 	(lface_equal_p): Use it.
 
 2004-06-03  Juanma Barranquero  <lektu@terra.es>
@@ -3828,7 +3887,7 @@
 
 2003-07-09  Kim F. Storm  <storm@cua.dk>
 
-	* xterm.c (use_xim) [!USE_XIM]: Default to disable XIM if emacs
+	* xterm.c (use_xim) [!USE_XIM]: Default to disable XIM if Emacs
 	was configured with --without-xim.
 	(x_term_init) [!USE_XIM]: Use `useXIM' resource to turn on XIM.
 
@@ -4685,7 +4744,7 @@
 	window to only preserve the display margins in one of the windows.
 	When splitting horizontally, call adjust_window_margins	on both
 	windows to ensure that the text area of the new windows is non too
-	narrow.  This fixes a bug which could cause emacs to trap if the
+	narrow.  This fixes a bug which could cause Emacs to trap if the
 	width of the split window was less than the width of the display
 	margins.
 	(window_box_text_cols): Renamed from window_internal_width.
@@ -4716,7 +4775,7 @@
 	(Fset_window_margins): Do nothing if display margins are not
 	really changed.  Otherwise, call adjust_window_margins to ensure
 	the text area doesn't get too narrow.  This fixes a bug which
-	could cause emacs to trap if setting display margins wider than
+	could cause Emacs to trap if setting display margins wider than
 	the width of the window.
 	(Fset_window_fringes): New defun to allow user to specifically set
 	this window's fringe widths and position vs. display margins.
@@ -7990,7 +8049,7 @@
 	* process.c (Fformat_network_address): New function.
 	(syms_of_process): Defsubr it.
 	(list_processes_1): Use it to format :local/:remote address if
-	service/host is not set; before emacs would crash in that case.
+	service/host is not set; before Emacs would crash in that case.
 	(Fmake_network_process): Don't use Ffind_operation_coding_system
 	to setup coding system if host or service is not set.
 
@@ -9288,11 +9347,11 @@
 2002-07-11  Juanma Barranquero  <lektu@terra.es>
 
 	* alloc.c, buffer.c, bytecode.c, callint.c, callproc.c, coding.c,
-	composite.c, dired.c, dispnew.c, editfns.c, emacs.c, eval.c,
-	fileio.c, fns.c, insdel.c, keyboard.c, keymap.c, lread.c, macfns.c,
-	macmenu.c, macros.c, minibuf.c, print.c, process.c, sound.c,
-	textprop.c, w32fns.c, w32menu.c, window.c, xfaces.c, xfns.c,
-	xmenu.c, xselect.c, xterm.c: Use SPECPDL_INDEX wherever makes sense.
+	* composite.c, dired.c, dispnew.c, editfns.c, emacs.c, eval.c,
+	* fileio.c, fns.c, insdel.c, keyboard.c, keymap.c, lread.c, macfns.c,
+	* macmenu.c, macros.c, minibuf.c, print.c, process.c, sound.c,
+	* textprop.c, w32fns.c, w32menu.c, window.c, xfaces.c, xfns.c,
+	* xmenu.c, xselect.c, xterm.c: Use SPECPDL_INDEX wherever makes sense.
 
 2002-07-10  Juanma Barranquero  <lektu@terra.es>
 
@@ -12315,7 +12374,7 @@
 2001-12-14  Andrew Innes  <andrewi@gnu.org>
 
 	* makefile.w32-in (EMACSLOADPATH): Define.
-	($(EMACS)): Run `list-load-path-shadows' after dumping emacs.
+	($(EMACS)): Run `list-load-path-shadows' after dumping Emacs.
 	(bootstrap-temacs): Remove dependency on bootstrap-clean.
 
 2001-12-13  Eli Zaretskii  <eliz@is.elta.co.il>
@@ -13612,7 +13671,7 @@
 
 2001-10-28  Pavel Jan,Am(Bk  <Pavel@Janik.cz>
 
-	* emacs.c: Use argv[0] instead of emacs when -t was specified.
+	* emacs.c: Use argv[0] instead of "emacs" when -t was specified.
 
 	* keyboard.c: Change doc-string comments to `new style' [w/`doc:'
 	keyword].
--- a/src/coding.c	Mon Jun 07 07:10:59 2004 +0000
+++ b/src/coding.c	Mon Jun 07 08:00:27 2004 +0000
@@ -6566,8 +6566,8 @@
     possible coding systems.  If it is nil, it means that we have not
     yet found any coding systems.
 
-    WORK_TABLE is a copy of the char-table Vchar_coding_system_table.  An
-    element of WORK_TABLE is set to t once the element is looked up.
+    WORK_TABLE a char-table of which element is set to t once the
+    element is looked up.
 
     If a non-ASCII single byte char is found, set
     *single_byte_char_found to 1.  */
@@ -6582,6 +6582,8 @@
   Lisp_Object val, ch;
   Lisp_Object prev, tail;
 
+  if (NILP (safe_codings))
+    goto done_safe_codings;
   while (p < pend)
     {
       c = STRING_CHAR_AND_LENGTH (p, pend - p, len);
@@ -6591,11 +6593,6 @@
 	continue;
       if (SINGLE_BYTE_CHAR_P (c))
 	*single_byte_char_found = 1;
-      if (NILP (safe_codings))
-	/* Already all coding systems are excluded.  But, we can't
-	   terminate the loop here because non-ASCII single-byte char
-	   must be found.  */
-	continue;
       /* Check the safe coding systems for C.  */
       ch = make_number (c);
       val = Faref (work_table, ch);
@@ -6673,12 +6670,33 @@
 	    {
 	      /* Exclude this coding system from SAFE_CODINGS.  */
 	      if (EQ (tail, safe_codings))
-		safe_codings = XCDR (safe_codings);
+		{
+		  safe_codings = XCDR (safe_codings);
+		  if (NILP (safe_codings))
+		    goto done_safe_codings;
+		}
 	      else
 		XSETCDR (prev, XCDR (tail));
 	    }
 	}
     }
+
+ done_safe_codings:
+  /* If the above loop was terminated before P reaches PEND, it means
+     SAFE_CODINGS was set to nil.  If we have not yet found an
+     non-ASCII single-byte char, check it now.  */
+  if (! *single_byte_char_found)
+    while (p < pend)
+      {
+	c = STRING_CHAR_AND_LENGTH (p, pend - p, len);
+	p += len;
+	if (! ASCII_BYTE_P (c)
+	    && SINGLE_BYTE_CHAR_P (c))
+	  {
+	    *single_byte_char_found = 1;
+	    break;
+	  }
+      }
   return safe_codings;
 }
 
--- a/src/keymap.c	Mon Jun 07 07:10:59 2004 +0000
+++ b/src/keymap.c	Mon Jun 07 08:00:27 2004 +0000
@@ -1624,7 +1624,7 @@
        doc: /* Return the binding for command KEYS in current global keymap only.
 KEYS is a string, a sequence of keystrokes.
 The binding is probably a symbol with a function definition.
-This function's return values are the same as those of lookup-key
+This function's return values are the same as those of `lookup-key'
 \(which see).
 
 If optional argument ACCEPT-DEFAULT is non-nil, recognize default
@@ -1951,7 +1951,7 @@
 DEFUN ("key-description", Fkey_description, Skey_description, 1, 2, 0,
        doc: /* Return a pretty description of key-sequence KEYS.
 Optional arg PREFIX is the sequence of keys leading up to KEYS.
-Control characters turn into "C-foo" sequences, meta into "M-foo"
+Control characters turn into "C-foo" sequences, meta into "M-foo",
 spaces are put between sequence elements, etc.  */)
   (keys, prefix)
      Lisp_Object keys, prefix;
@@ -3226,7 +3226,8 @@
 
 DEFUN ("describe-vector", Fdescribe_vector, Sdescribe_vector, 1, 2, 0,
        doc: /* Insert a description of contents of VECTOR.
-This is text showing the elements of vector matched against indices.  */)
+This is text showing the elements of vector matched against indices.
+DESCRIBER is the output function used; nil means use `princ'.  */)
      (vector, describer)
      Lisp_Object vector, describer;
 {
--- a/src/macfns.c	Mon Jun 07 07:10:59 2004 +0000
+++ b/src/macfns.c	Mon Jun 07 08:00:27 2004 +0000
@@ -1,5 +1,5 @@
 /* Graphical user interface functions for Mac OS.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -3803,13 +3803,15 @@
   window_prompting = x_figure_window_size (f, parms, 0);
 
   {
+    Rect r;
+
     BLOCK_INPUT;
-    Rect r;
-
     SetRect (&r, 0, 0, 1, 1);
     if (CreateNewWindow (kHelpWindowClass,
-			 kWindowNoActivatesAttribute
-			 | kWindowIgnoreClicksAttribute,
+#ifdef MAC_OS_X_VERSION_10_2
+			 kWindowIgnoreClicksAttribute |
+#endif
+			 kWindowNoActivatesAttribute,
 			 &r, &tip_window) == noErr)
       {
 	FRAME_MAC_WINDOW (f) = tip_window;
--- a/src/minibuf.c	Mon Jun 07 07:10:59 2004 +0000
+++ b/src/minibuf.c	Mon Jun 07 08:00:27 2004 +0000
@@ -1619,7 +1619,7 @@
   is the initial position (the position in the list used by the
   minibuffer history commands).  For consistency, you should also
   specify that element of the history as the value of
-  INITIAL-CONTENTS.  (This is the only case in which you should use
+  INITIAL-INPUT.  (This is the only case in which you should use
   INITIAL-INPUT instead of DEF.)  Positions are counted starting from
   1 at the beginning of the list.  The variable `history-length'
   controls the maximum length of a history list.
--- a/src/process.c	Mon Jun 07 07:10:59 2004 +0000
+++ b/src/process.c	Mon Jun 07 08:00:27 2004 +0000
@@ -445,10 +445,11 @@
 
 /* Return a string describing a process status list.  */
 
-Lisp_Object
-status_message (status)
-     Lisp_Object status;
+static Lisp_Object
+status_message (p)
+     struct Lisp_Process *p;
 {
+  Lisp_Object status = p->status;
   Lisp_Object symbol;
   int code, coredump;
   Lisp_Object string, string2;
@@ -469,6 +470,8 @@
     }
   else if (EQ (symbol, Qexit))
     {
+      if (NETCONN1_P (p))
+	return build_string (code == 0 ? "deleted\n" : "connection broken by remote peer\n");
       if (code == 0)
 	return build_string ("finished\n");
       string = Fnumber_to_string (make_number (code));
@@ -764,6 +767,7 @@
     {
       XPROCESS (process)->status = Fcons (Qexit, Fcons (make_number (0), Qnil));
       XSETINT (XPROCESS (process)->tick, ++process_tick);
+      status_notify ();
     }
   else if (XINT (XPROCESS (process)->infd) >= 0)
     {
@@ -774,18 +778,7 @@
       XSETINT (XPROCESS (process)->tick, ++process_tick);
       status_notify ();
     }
-  /* Do not call remove_process here; either status_notify has already done
-     it, or will do so the next time emacs polls for input.  Thus network
-     processes are not immediately removed, and their sentinel will be
-     called.
-
-     Since Fdelete_process is called by kill_buffer_processes, this also
-     means that a network process sentinel will run after the buffer is
-     dead, which would not be the case if status_notify() were called
-     unconditionally here.  This way process sentinels observe consistent
-     behavior with regard to buffer-live-p.
-  */
-  /* remove_process (process); */
+  remove_process (process);
   return Qnil;
 }
 
@@ -4703,7 +4696,7 @@
    starting with our buffered-ahead character if we have one.
    Yield number of decoded characters read.
 
-   This function reads at most 1024 characters.
+   This function reads at most 4096 characters.
    If you want to read all available subprocess output,
    you must call it repeatedly until it returns zero.
 
@@ -4723,7 +4716,7 @@
   register int opoint;
   struct coding_system *coding = proc_decode_coding_system[channel];
   int carryover = XINT (p->decoding_carryover);
-  int readmax = 1024;
+  int readmax = 4096;
 
 #ifdef VMS
   VMS_PROC_STUFF *vs, *get_vms_process_pointer();
@@ -4756,16 +4749,6 @@
     }
 #else /* not VMS */
 
-#ifdef DATAGRAM_SOCKETS
-  /* A datagram is one packet; allow at least 1500+ bytes of data
-     corresponding to the typical Ethernet frame size.  */
-  if (DATAGRAM_CHAN_P (channel))
-    {
-      /* carryover = 0; */  /* Does carryover make sense for datagrams? */
-      readmax += 1024;
-    }
-#endif
-
   chars = (char *) alloca (carryover + readmax);
   if (carryover)
     /* See the comment above.  */
@@ -6399,7 +6382,7 @@
 	  /* Get the text to use for the message.  */
 	  if (!NILP (p->raw_status_low))
 	    update_status (p);
-	  msg = status_message (p->status);
+	  msg = status_message (p);
 
 	  /* If process is terminated, deactivate it or delete it.  */
 	  symbol = p->status;
--- a/src/xfaces.c	Mon Jun 07 07:10:59 2004 +0000
+++ b/src/xfaces.c	Mon Jun 07 08:00:27 2004 +0000
@@ -463,6 +463,7 @@
 
 struct font_name;
 struct table_entry;
+struct named_merge_point;
 
 static void map_tty_color P_ ((struct frame *, struct face *,
 			       enum lface_attribute_index, int *));
@@ -521,11 +522,10 @@
 static int face_numeric_swidth P_ ((Lisp_Object));
 static int face_fontset P_ ((Lisp_Object *));
 static char *choose_face_font P_ ((struct frame *, Lisp_Object *, int, int, int*));
-static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*, Lisp_Object));
-static void merge_face_inheritance P_ ((struct frame *f, Lisp_Object,
-					Lisp_Object *, Lisp_Object));
-static void merge_face_vector_with_property P_ ((struct frame *, Lisp_Object *,
-						 Lisp_Object));
+static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*,
+				    struct named_merge_point *));
+static int merge_face_ref P_ ((struct frame *, Lisp_Object, Lisp_Object *,
+			       int, struct named_merge_point *));
 static int set_lface_from_font_name P_ ((struct frame *, Lisp_Object,
 					 Lisp_Object, int, int));
 static Lisp_Object lface_from_face_name P_ ((struct frame *, Lisp_Object, int));
@@ -3154,6 +3154,49 @@
 #endif /* GLYPH_DEBUG == 0 */
 
 
+
+/* Face-merge cycle checking.  */
+
+/* A `named merge point' is simply a point during face-merging where we
+   look up a face by name.  We keep a stack of which named lookups we're
+   currently processing so that we can easily detect cycles, using a
+   linked- list of struct named_merge_point structures, typically
+   allocated on the stack frame of the named lookup functions which are
+   active (so no consing is required).  */
+struct named_merge_point
+{
+  Lisp_Object face_name;
+  struct named_merge_point *prev;
+};
+
+
+/* If a face merging cycle is detected for FACE_NAME, return 0,
+   otherwise add NEW_NAMED_MERGE_POINT, which is initialized using
+   FACE_NAME, as the head of the linked list
+   pointed to by NAMED_MERGE_POINTS, and return 1.  */
+
+static INLINE int
+push_named_merge_point (struct named_merge_point *new_named_merge_point,
+			Lisp_Object face_name,
+			struct named_merge_point **named_merge_points)
+{
+  struct named_merge_point *prev;
+
+  for (prev = *named_merge_points; prev; prev = prev->prev)
+    if (EQ (face_name, prev->face_name))
+	break;
+
+  new_named_merge_point->face_name = face_name;
+  new_named_merge_point->prev = *named_merge_points;
+
+  *named_merge_points = new_named_merge_point;
+
+  return 1;
+}
+
+
+
+
 /* Resolve face name FACE_NAME.  If FACE_NAME is a string, intern it
    to make it a symvol.  If FACE_NAME is an alias for another face,
    return that face's name.  */
@@ -3404,6 +3447,8 @@
       else if (FLOATP (to))
 	/* relative X relative => relative */
 	result = make_float (XFLOAT_DATA (from) * XFLOAT_DATA (to));
+      else if (UNSPECIFIEDP (to))
+	result = from;
     }
   else if (FUNCTIONP (from))
     /* FROM is a function, which use to adjust TO.  */
@@ -3435,14 +3480,15 @@
    completely specified and contain only absolute attributes.  Every
    specified attribute of FROM overrides the corresponding attribute of
    TO; relative attributes in FROM are merged with the absolute value in
-   TO and replace it.  CYCLE_CHECK is used internally to detect loops in
-   face inheritance; it should be Qnil when called from other places.  */
+   TO and replace it.  NAMED_MERGE_POINTS is used internally to detect
+   loops in face inheritance; it should be 0 when called from other
+   places.  */
 
 static INLINE void
-merge_face_vectors (f, from, to, cycle_check)
+merge_face_vectors (f, from, to, named_merge_points)
      struct frame *f;
      Lisp_Object *from, *to;
-     Lisp_Object cycle_check;
+     struct named_merge_point *named_merge_points;
 {
   int i;
 
@@ -3453,7 +3499,7 @@
      other code uses `unspecified' as a generic value for face attributes. */
   if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
       && !NILP (from[LFACE_INHERIT_INDEX]))
-    merge_face_inheritance (f, from[LFACE_INHERIT_INDEX], to, cycle_check);
+    merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, 0, named_merge_points);
 
   /* If TO specifies a :font attribute, and FROM specifies some
      font-related attribute, we need to clear TO's :font attribute
@@ -3472,7 +3518,8 @@
     if (!UNSPECIFIEDP (from[i]))
       {
 	if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i]))
-	  to[i] = merge_face_heights (from[i], to[i], to[i], cycle_check);
+	  to[i] = merge_face_heights (from[i], to[i], to[i],
+				      named_merge_points);
 	else
 	  to[i] = from[i];
       }
@@ -3482,61 +3529,45 @@
   to[LFACE_INHERIT_INDEX] = Qnil;
 }
 
-/* Merge face attributes from the face on frame F whose name is
-   INHERITS, into the vector of face attributes TO; INHERITS may also be
-   a list of face names, in which case they are applied in order.
-   CYCLE_CHECK is used to detect loops in face inheritance.
-   Returns true if any of the inherited attributes are `font-related'.  */
-
-static void
-merge_face_inheritance (f, inherit, to, cycle_check)
+/* Merge the named face FACE_NAME on frame F, into the vector of face
+   attributes TO.  NAMED_MERGE_POINTS is used to detect loops in face
+   inheritance.  Returns true if FACE_NAME is a valid face name and
+   merging succeeded.  */
+
+static int
+merge_named_face (f, face_name, to, named_merge_points)
      struct frame *f;
-     Lisp_Object inherit;
+     Lisp_Object face_name;
      Lisp_Object *to;
-     Lisp_Object cycle_check;
-{
-  if (SYMBOLP (inherit) && !EQ (inherit, Qunspecified))
-    /* Inherit from the named face INHERIT.  */
-    {
-      Lisp_Object lface;
-
-      /* Make sure we're not in an inheritance loop.  */
-      cycle_check = CYCLE_CHECK (cycle_check, inherit, 15);
-      if (NILP (cycle_check))
-	/* Cycle detected, ignore any further inheritance.  */
-	return;
-
-      lface = lface_from_face_name (f, inherit, 0);
-      if (!NILP (lface))
-	merge_face_vectors (f, XVECTOR (lface)->contents, to, cycle_check);
-    }
-  else if (CONSP (inherit))
-    /* Handle a list of inherited faces by calling ourselves recursively
-       on each element.  Note that we only do so for symbol elements, so
-       it's not possible to infinitely recurse.  */
-    {
-      while (CONSP (inherit))
-	{
-	  if (SYMBOLP (XCAR (inherit)))
-	    merge_face_inheritance (f, XCAR (inherit), to, cycle_check);
-
-	  /* Check for a circular inheritance list.  */
-	  cycle_check = CYCLE_CHECK (cycle_check, inherit, 15);
-	  if (NILP (cycle_check))
-	    /* Cycle detected.  */
-	    break;
-
-	  inherit = XCDR (inherit);
-	}
-    }
-}
-
-
-/* Given a Lisp face attribute vector TO and a Lisp object PROP that
-   is a face property, determine the resulting face attributes on
-   frame F, and store them in TO.  PROP may be a single face
-   specification or a list of such specifications.  Each face
-   specification can be
+     struct named_merge_point *named_merge_points;
+{
+  struct named_merge_point named_merge_point;
+
+  if (push_named_merge_point (&named_merge_point,
+			      face_name, &named_merge_points))
+    {
+      Lisp_Object from[LFACE_VECTOR_SIZE];
+      int ok = get_lface_attributes (f, face_name, from, 0);
+
+      if (ok)
+	merge_face_vectors (f, from, to, named_merge_points);
+
+      return ok;
+    }
+  else
+    return 0;
+}
+
+
+/* Merge face attributes from the lisp `face reference' FACE_REF on
+   frame F into the face attribute vector TO.  If ERR_MSGS is non-zero,
+   problems with FACE_REF cause an error message to be shown.  Return
+   non-zero if no errors occurred (regardless of the value of ERR_MSGS).
+   NAMED_MERGE_POINTS is used to detect loops in face inheritance or
+   list structure; it may be 0 for most callers.
+
+   FACE_REF may be a single face specification or a list of such
+   specifications.  Each face specification can be:
 
    1. A symbol or string naming a Lisp face.
 
@@ -3551,22 +3582,26 @@
    Face specifications earlier in lists take precedence over later
    specifications.  */
 
-static void
-merge_face_vector_with_property (f, to, prop)
+static int
+merge_face_ref (f, face_ref, to, err_msgs, named_merge_points)
      struct frame *f;
+     Lisp_Object face_ref;
      Lisp_Object *to;
-     Lisp_Object prop;
-{
-  if (CONSP (prop))
-    {
-      Lisp_Object first = XCAR (prop);
+     int err_msgs;
+     struct named_merge_point *named_merge_points;
+{
+  int ok = 1;			/* Succeed without an error? */
+
+  if (CONSP (face_ref))
+    {
+      Lisp_Object first = XCAR (face_ref);
 
       if (EQ (first, Qforeground_color)
 	  || EQ (first, Qbackground_color))
 	{
 	  /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR
 	     . COLOR).  COLOR must be a string.  */
-	  Lisp_Object color_name = XCDR (prop);
+	  Lisp_Object color_name = XCDR (face_ref);
 	  Lisp_Object color = first;
 
 	  if (STRINGP (color_name))
@@ -3577,23 +3612,28 @@
 		to[LFACE_BACKGROUND_INDEX] = color_name;
 	    }
 	  else
-	    add_to_log ("Invalid face color", color_name, Qnil);
+	    {
+	      if (err_msgs)
+		add_to_log ("Invalid face color", color_name, Qnil);
+	      ok = 0;
+	    }
 	}
       else if (SYMBOLP (first)
 	       && *SDATA (SYMBOL_NAME (first)) == ':')
 	{
 	  /* Assume this is the property list form.  */
-	  while (CONSP (prop) && CONSP (XCDR (prop)))
+	  while (CONSP (face_ref) && CONSP (XCDR (face_ref)))
 	    {
-	      Lisp_Object keyword = XCAR (prop);
-	      Lisp_Object value = XCAR (XCDR (prop));
+	      Lisp_Object keyword = XCAR (face_ref);
+	      Lisp_Object value = XCAR (XCDR (face_ref));
+	      int err = 0;
 
 	      if (EQ (keyword, QCfamily))
 		{
 		  if (STRINGP (value))
 		    to[LFACE_FAMILY_INDEX] = value;
 		  else
-		    add_to_log ("Invalid face font family", value, Qnil);
+		    err = 1;
 		}
 	      else if (EQ (keyword, QCheight))
 		{
@@ -3601,10 +3641,10 @@
 		    merge_face_heights (value, to[LFACE_HEIGHT_INDEX],
 					Qnil, Qnil);
 
-		  if (NILP (new_height))
-		    add_to_log ("Invalid face font height", value, Qnil);
+		  if (! NILP (new_height))
+		    to[LFACE_HEIGHT_INDEX] = new_height;
 		  else
-		    to[LFACE_HEIGHT_INDEX] = new_height;
+		    err = 1;
 		}
 	      else if (EQ (keyword, QCweight))
 		{
@@ -3612,7 +3652,7 @@
 		      && face_numeric_weight (value) >= 0)
 		    to[LFACE_WEIGHT_INDEX] = value;
 		  else
-		    add_to_log ("Invalid face weight", value, Qnil);
+		    err = 1;
 		}
 	      else if (EQ (keyword, QCslant))
 		{
@@ -3620,7 +3660,7 @@
 		      && face_numeric_slant (value) >= 0)
 		    to[LFACE_SLANT_INDEX] = value;
 		  else
-		    add_to_log ("Invalid face slant", value, Qnil);
+		    err = 1;
 		}
 	      else if (EQ (keyword, QCunderline))
 		{
@@ -3629,7 +3669,7 @@
 		      || STRINGP (value))
 		    to[LFACE_UNDERLINE_INDEX] = value;
 		  else
-		    add_to_log ("Invalid face underline", value, Qnil);
+		    err = 1;
 		}
 	      else if (EQ (keyword, QCoverline))
 		{
@@ -3638,7 +3678,7 @@
 		      || STRINGP (value))
 		    to[LFACE_OVERLINE_INDEX] = value;
 		  else
-		    add_to_log ("Invalid face overline", value, Qnil);
+		    err = 1;
 		}
 	      else if (EQ (keyword, QCstrike_through))
 		{
@@ -3647,7 +3687,7 @@
 		      || STRINGP (value))
 		    to[LFACE_STRIKE_THROUGH_INDEX] = value;
 		  else
-		    add_to_log ("Invalid face strike-through", value, Qnil);
+		    err = 1;
 		}
 	      else if (EQ (keyword, QCbox))
 		{
@@ -3659,7 +3699,7 @@
 		      || NILP (value))
 		    to[LFACE_BOX_INDEX] = value;
 		  else
-		    add_to_log ("Invalid face box", value, Qnil);
+		    err = 1;
 		}
 	      else if (EQ (keyword, QCinverse_video)
 		       || EQ (keyword, QCreverse_video))
@@ -3667,21 +3707,21 @@
 		  if (EQ (value, Qt) || NILP (value))
 		    to[LFACE_INVERSE_INDEX] = value;
 		  else
-		    add_to_log ("Invalid face inverse-video", value, Qnil);
+		    err = 1;
 		}
 	      else if (EQ (keyword, QCforeground))
 		{
 		  if (STRINGP (value))
 		    to[LFACE_FOREGROUND_INDEX] = value;
 		  else
-		    add_to_log ("Invalid face foreground", value, Qnil);
+		    err = 1;
 		}
 	      else if (EQ (keyword, QCbackground))
 		{
 		  if (STRINGP (value))
 		    to[LFACE_BACKGROUND_INDEX] = value;
 		  else
-		    add_to_log ("Invalid face background", value, Qnil);
+		    err = 1;
 		}
 	      else if (EQ (keyword, QCstipple))
 		{
@@ -3690,7 +3730,7 @@
 		  if (!NILP (pixmap_p))
 		    to[LFACE_STIPPLE_INDEX] = value;
 		  else
-		    add_to_log ("Invalid face stipple", value, Qnil);
+		    err = 1;
 #endif
 		}
 	      else if (EQ (keyword, QCwidth))
@@ -3699,52 +3739,51 @@
 		      && face_numeric_swidth (value) >= 0)
 		    to[LFACE_SWIDTH_INDEX] = value;
 		  else
-		    add_to_log ("Invalid face width", value, Qnil);
+		    err = 1;
 		}
 	      else if (EQ (keyword, QCinherit))
 		{
-		  if (SYMBOLP (value))
-		    to[LFACE_INHERIT_INDEX] = value;
-		  else
-		    {
-		      Lisp_Object tail;
-		      for (tail = value; CONSP (tail); tail = XCDR (tail))
-			if (!SYMBOLP (XCAR (tail)))
-			  break;
-		      if (NILP (tail))
-			to[LFACE_INHERIT_INDEX] = value;
-		      else
-			add_to_log ("Invalid face inherit", value, Qnil);
-		    }
+		  /* This is not really very useful; it's just like a
+		     normal face reference.  */
+		  if (! merge_face_ref (f, value, to,
+					err_msgs, named_merge_points))
+		    err = 1;
 		}
 	      else
-		add_to_log ("Invalid attribute %s in face property",
-			    keyword, Qnil);
-
-	      prop = XCDR (XCDR (prop));
+		err = 1;
+
+	      if (err)
+		{
+		  add_to_log ("Invalid face attribute %S %S", keyword, value);
+		  ok = 0;
+		}
+
+	      face_ref = XCDR (XCDR (face_ref));
 	    }
 	}
       else
 	{
-	  /* This is a list of face specs.  Specifications at the
-	     beginning of the list take precedence over later
-	     specifications, so we have to merge starting with the
-	     last specification.  */
-	  Lisp_Object next = XCDR (prop);
-	  if (!NILP (next))
-	    merge_face_vector_with_property (f, to, next);
-	  merge_face_vector_with_property (f, to, first);
+	  /* This is a list of face refs.  Those at the beginning of the
+	     list take precedence over what follows, so we have to merge
+	     from the end backwards.  */
+	  Lisp_Object next = XCDR (face_ref);
+
+	  if (! NILP (next))
+	    ok = merge_face_ref (f, next, to, err_msgs, named_merge_points);
+
+	  if (! merge_face_ref (f, first, to, err_msgs, named_merge_points))
+	    ok = 0;
 	}
     }
   else
     {
-      /* PROP ought to be a face name.  */
-      Lisp_Object lface = lface_from_face_name (f, prop, 0);
-      if (NILP (lface))
-	add_to_log ("Invalid face text property value: %s", prop, Qnil);
-      else
-	merge_face_vectors (f, XVECTOR (lface)->contents, to, Qnil);
-    }
+      /* FACE_REF ought to be a face name.  */
+      ok = merge_named_face (f, face_ref, to, named_merge_points);
+      if (!ok && err_msgs)
+	add_to_log ("Invalid face reference: %s", face_ref, Qnil);
+    }
+
+  return ok;
 }
 
 
@@ -5572,7 +5611,8 @@
 
   get_lface_attributes (f, symbol, symbol_attrs, 1);
   bcopy (default_face->lface, attrs, sizeof attrs);
-  merge_face_vectors (f, symbol_attrs, attrs, Qnil);
+  merge_face_vectors (f, symbol_attrs, attrs, 0);
+
   return lookup_face (f, attrs, c, NULL);
 }
 
@@ -5711,7 +5751,7 @@
 
   get_lface_attributes (f, symbol, symbol_attrs, 1);
   bcopy (default_face->lface, attrs, sizeof attrs);
-  merge_face_vectors (f, symbol_attrs, attrs, Qnil);
+  merge_face_vectors (f, symbol_attrs, attrs, 0);
   return lookup_face (f, attrs, c, default_face);
 }
 
@@ -5724,9 +5764,8 @@
   Lisp_Object lface;
   lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
 			Qunspecified);
-  merge_face_vector_with_property (XFRAME (selected_frame),
-				   XVECTOR (lface)->contents,
-				   plist);
+  merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->contents,
+		  1, 0);
   return lface;
 }
 
@@ -5805,7 +5844,7 @@
 
       bcopy (def_attrs, merged_attrs, sizeof merged_attrs);
 
-      merge_face_vectors (f, attrs, merged_attrs, Qnil);
+      merge_face_vectors (f, attrs, merged_attrs, 0);
 
       face = FACE_FROM_ID (f, lookup_face (f, merged_attrs, 0, 0));
 
@@ -6030,6 +6069,12 @@
   struct face *def_face;
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
 
+  if (noninteractive || !initialized)
+    /* We may not be able to access low-level face information in batch
+       mode, or before being dumped, and this function is not going to
+       be very useful in those cases anyway, so just give up.  */
+    return Qnil;
+
   if (NILP (display))
     frame = selected_frame;
   else if (FRAMEP (display))
@@ -6055,7 +6100,7 @@
 
   for (i = 0; i < LFACE_VECTOR_SIZE; i++)
     attrs[i] = Qunspecified;
-  merge_face_vector_with_property (f, attrs, attributes);
+  merge_face_ref (f, attributes, attrs, 1, 0);
 
   def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
   if (def_face == NULL)
@@ -6932,7 +6977,7 @@
 
   /* Merge SYMBOL's face with the default face.  */
   get_lface_attributes (f, symbol, symbol_attrs, 1);
-  merge_face_vectors (f, symbol_attrs, attrs, Qnil);
+  merge_face_vectors (f, symbol_attrs, attrs, 0);
 
   /* Realize the face.  */
   new_face = realize_face (c, attrs, 0, NULL, id);
@@ -7402,7 +7447,7 @@
       Lisp_Object attrs[LFACE_VECTOR_SIZE];
       struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
       bcopy (default_face->lface, attrs, sizeof attrs);
-      merge_face_vector_with_property (f, attrs, prop);
+      merge_face_ref (f, prop, attrs, 1, 0);
       face_id = lookup_face (f, attrs, ch, NULL);
     }
 
@@ -7488,7 +7533,7 @@
 
   /* Merge in attributes specified via text properties.  */
   if (!NILP (prop))
-    merge_face_vector_with_property (f, attrs, prop);
+    merge_face_ref (f, prop, attrs, 1, 0);
 
   /* Now merge the overlay data.  */
   noverlays = sort_overlays (overlay_vec, noverlays, w);
@@ -7499,7 +7544,7 @@
 
       prop = Foverlay_get (overlay_vec[i], propname);
       if (!NILP (prop))
-	merge_face_vector_with_property (f, attrs, prop);
+	merge_face_ref (f, prop, attrs, 1, 0);
 
       oend = OVERLAY_END (overlay_vec[i]);
       oendpos = OVERLAY_POSITION (oend);
@@ -7510,8 +7555,7 @@
   /* If in the region, merge in the region face.  */
   if (pos >= region_beg && pos < region_end)
     {
-      Lisp_Object region_face = lface_from_face_name (f, Qregion, 0);
-      merge_face_vectors (f, XVECTOR (region_face)->contents, attrs, Qnil);
+      merge_named_face (f, Qregion, attrs, 0);
 
       if (region_end < endpos)
 	endpos = region_end;
@@ -7607,16 +7651,13 @@
 
   /* Merge in attributes specified via text properties.  */
   if (!NILP (prop))
-    merge_face_vector_with_property (f, attrs, prop);
+    merge_face_ref (f, prop, attrs, 1, 0);
 
   /* If in the region, merge in the region face.  */
   if (bufpos
       && bufpos >= region_beg
       && bufpos < region_end)
-    {
-      Lisp_Object region_face = lface_from_face_name (f, Qregion, 0);
-      merge_face_vectors (f, XVECTOR (region_face)->contents, attrs, Qnil);
-    }
+    merge_named_face (f, Qregion, attrs, 0);
 
   /* Look up a realized face with the given face attributes,
      or realize a new one for ASCII characters.  */