diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 0000000000000000000000000000000000000000..1acc70ff47d75d987dce40294418ea401ab1993c_LmN2c2lnbm9yZQ==
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1,4 @@
+_pkg.el
+auto-autoloads.el
+custom-load.el
+package-info
diff --git a/ChangeLog b/ChangeLog
index 8f7edb260f43d9e6290bc3de091ebbe948c9e27e_Q2hhbmdlTG9n..1acc70ff47d75d987dce40294418ea401ab1993c_Q2hhbmdlTG9n 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+1998-02-25  SL Baur  <steve@altair.xemacs.org>
+
+	* xrdb-mode.el (xrdb-submit-bug-report): Require reporter here
+	since we don't need it for bytecompiling.
+
 1998-01-25  SL Baur  <steve@altair.xemacs.org>
 
 	* Makefile (VERSION): Update to package standard 1.0.
diff --git a/Makefile b/Makefile
index 8f7edb260f43d9e6290bc3de091ebbe948c9e27e_TWFrZWZpbGU=..1acc70ff47d75d987dce40294418ea401ab1993c_TWFrZWZpbGU= 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@
 
 # This XEmacs package contains independent single file lisp packages
 
-VERSION = 1.03
+VERSION = 1.04
 AUTHOR_VERSION =
 MAINTAINER = XEmacs Development Team <xemacs-beta@xemacs.org>
 PACKAGE = text-modes
diff --git a/xrdb-mode.el b/xrdb-mode.el
index 8f7edb260f43d9e6290bc3de091ebbe948c9e27e_eHJkYi1tb2RlLmVs..1acc70ff47d75d987dce40294418ea401ab1993c_eHJkYi1tb2RlLmVs 100644
--- a/xrdb-mode.el
+++ b/xrdb-mode.el
@@ -1,7 +1,5 @@
 ;;; xrdb-mode.el --- mode for editing X resource database files
 
-;; Copyright (C) 1994 Barry A. Warsaw
-
 ;; Author:        1994-1997 Barry A. Warsaw
 ;; Maintainer:    tools-help@python.org
 ;; Created:       May 1994
@@ -5,7 +3,8 @@
 ;; Author:        1994-1997 Barry A. Warsaw
 ;; Maintainer:    tools-help@python.org
 ;; Created:       May 1994
-;; Version:       1.21x
-;; Last Modified: 1997/02/24 03:34:56
-;; Keywords:      data, languages
+;; Keywords:      data languages
+
+(defconst xrdb-version "2.11"
+  "`xrdb-mode' version number.")
 
@@ -11,3 +10,3 @@
 
-;; This file is part of XEmacs.
+;; Copyright (C) 1994 Barry A. Warsaw
 
@@ -13,5 +12,7 @@
 
-;; XEmacs is free software; you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published by
+;; This file is not part of GNU Emacs.
+
+;; This program 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 of the License, or
 ;; (at your option) any later version.
@@ -16,9 +17,9 @@
 ;; the Free Software Foundation; either version 2 of the License, or
 ;; (at your option) any later version.
-
-;; XEmacs 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.
+;; 
+;; This program 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
@@ -23,10 +24,7 @@
 ;; 
 ;; You should have received a copy of the GNU General Public License
-;; along with XEmacs; see the file COPYING.  If not, write to the Free
-;; Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Synched up with: Not in FSF
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 ;;; Commentary:
 ;;
@@ -30,6 +28,27 @@
 
 ;;; Commentary:
 ;;
+;; This file provides a major mode for editing X resource database
+;; files, and includes font-lock definitions and commands for
+;; controlling indentation, re-indenting by subdivisions, and loading
+;; and merging into the the resource database.
+;;
+;; To use, put the following in your .emacs:
+;;
+;; (autoload 'xrdb-mode "xrdb-mode" "Mode for editing X resource files" t)
+;;
+;; You may also want something like:
+;;
+;; (setq auto-mode-alist
+;;       (append '(("\\.Xdefaults$"    . xrdb-mode)
+;;                 ("\\.Xenvironment$" . xrdb-mode)
+;;                 ("\\.Xresources$"   . xrdb-mode)
+;;                 ("*.\\.ad$"         . xrdb-mode)
+;;                 )
+;;               auto-mode-alist))
+
+;;; History:
+;;
 ;; In 1994 I wrote:
 ;;
 ;; "I used to be like you.  I used to hack on X resource database files
@@ -52,19 +71,7 @@
 ;; I have fallen from grace and have been kicked out of paradise.  So
 ;; has Steve Jobs apparently :-)
 ;;
-;; To use, put the following in your .emacs:
-;;
-;; (autoload 'xrdb-mode "xrdb-mode" "Mode for editing X resource files" t)
-;;
-;; You may also want something like:
-;;
-;; (setq auto-mode-alist
-;;       (append '(("\\.Xdefaults$" . xrdb-mode)
-;;                 ("\\.Xenvironment$" . xrdb-mode)
-;;                 ("\\.Xresources$" . xrdb-mode)
-;;                 )
-;;               auto-mode-alist))
-
+;; The database merge feature was inspired by Joel N. Webber, II.
 
 ;; Code:
 
@@ -68,4 +75,7 @@
 
 ;; Code:
 
+(require 'custom)
+
+
 
@@ -71,3 +81,2 @@
 
-;; These variables are available for your customization
 (defgroup xrdb nil
@@ -73,6 +82,5 @@
 (defgroup xrdb nil
-  "Mode for editing X resource database files."
-  :group 'data
+  "Support for editing X resource database files"
   :group 'languages)
 
 (defcustom xrdb-mode-hook nil
@@ -81,10 +89,34 @@
   :group 'xrdb)
 
 (defcustom xrdb-subdivide-by 'paragraph
-  "*Extent of alignment calculations.
-Can be one of `buffer', `paragraph', `page', or `line'.  Do a
-\\[describe-function] xrdb-indent-buffer RET for more information."
-  :type '(radio (const buffer) (const paragraph)
-		(const page) (const line))
+  "*Default alignment subdivision when re-indenting a region or buffer.
+This variable controls how much of the buffer is searched to find a
+goal column on which to align.  Every non-comment line in the region
+defined by this variable is scanned for the first `:' character on the 
+line, and this character's column is the line's goal column.  The
+rightmost line goal column in the region is taken as the region's goal 
+column.
+
+This variable can take one of the following symbol values:
+
+ `buffer'    - All lines in the buffer are scanned.  This is the
+               slowest option. 
+
+ `paragraph' - All lines in the paragraph are scanned.  Paragraphs
+               are delimited by blank lines, comment lines, and page
+               delimiters.
+
+ `page'      - All lines in the page are scanned.  Pages are delimited 
+               with `page-delimiter', usual ^L (control-L).
+
+ `line'      - Only the previous non-comment line is scanned.  This is
+               the fastest method.
+
+This variable is consulted from `xrdb-indent-region' and
+`xrdb-indent-buffer' and can be overridden in both commands."
+  :type '(radio (const :tag "Do not subdivide buffer" buffer)
+		(const :tag "Subdivide by paragraphs" paragraph)
+		(const :tag "Subdivide by pages" page)
+		(const :tag "Each line is independent" line))
   :group 'xrdb)
 
@@ -89,4 +121,36 @@
   :group 'xrdb)
 
+(defcustom xrdb-compress-whitespace nil
+  "*Collapse all whitespace to a single space after insertion of `:'."
+  :type 'boolean
+  :group 'xrdb)
+
+(defcustom xrdb-program "xrdb"
+  "*Program to run to load or merge resources in the X resource database."
+  :type 'string
+  :group 'xrdb)
+
+(defcustom xrdb-program-args '("-merge")
+  "*List of string arguments to pass to `xrdb-program'."
+  :type '(repeat string)
+  :group 'xrdb)
+
+(defvar xrdb-master-file nil
+  "If non-nil, merge in the named file instead of the buffer's file.
+The intent is to allow you to set this variable in the file's local
+variable section, e.g.:
+
+    ! Local Variables:
+    ! xrdb-master-file: \"Xdefaults\"
+    ! End:
+
+so that typing \\[xrdb-database-merge-buffer-or-region] in that buffer
+merges the named master file instead of the buffer's file.  Note that
+if the file name has a relative path, the `default-directory' for the
+buffer is prepended to come up with a file name.
+
+You may also want to set `xrdb-program-args' in the local variables
+section as well.")
+(make-variable-buffer-local 'xrdb-master-file)
 
 
@@ -91,4 +155,4 @@
 
 
-;; no need to customize anything below this line
+;; Non-user customizable
 (defconst xrdb-comment-re "^[ \t]*[!]"
@@ -94,7 +158,6 @@
 (defconst xrdb-comment-re "^[ \t]*[!]"
-  "Character which starts a comment.")
-(defconst xrdb-separator-char ?:
-  "Character which separates resource specs from values.")
+  "Regular expression describing the beginning of a comment line.")
+
 
 
 ;; utilities
@@ -118,6 +181,7 @@
   ;; This function does not modify point or mark.
   (let ((here (point)))
     (cond
+     ((eq position 'bod)  (beginning-of-defun))
      ((eq position 'bol)  (beginning-of-line))
      ((eq position 'eol)  (end-of-line))
      ((eq position 'boi)  (back-to-indentation))
@@ -134,8 +198,14 @@
       (goto-char here))
     ))
 
+(defmacro xrdb-safe (&rest body)
+  ;; safely execute BODY, return nil if an error occurred
+  (` (condition-case nil
+	 (progn (,@ body))
+       (error nil))))
+
 (defsubst xrdb-skip-to-separator ()
   ;; skip forward from the beginning of the line to the separator
   ;; character as given by xrdb-separator-char. Returns t if the
   ;; char was found, otherwise, nil.
   (beginning-of-line)
@@ -137,10 +207,14 @@
 (defsubst xrdb-skip-to-separator ()
   ;; skip forward from the beginning of the line to the separator
   ;; character as given by xrdb-separator-char. Returns t if the
   ;; char was found, otherwise, nil.
   (beginning-of-line)
-  (skip-chars-forward
-   (concat "^" (char-to-string xrdb-separator-char))
-   (xrdb-point 'eol))
-  (= (following-char) xrdb-separator-char))
+  (skip-chars-forward "^:" (xrdb-point 'eol))
+  (and (eq (char-after) ?:)
+       (current-column)))
+
+(defsubst xrdb-in-comment-p (&optional lim)
+  (let* ((lim (or lim (xrdb-point 'bod)))
+	 (state (parse-partial-sexp lim (point))))
+    (nth 4 state)))
 
@@ -146,5 +220,25 @@
 
+(defsubst xrdb-boi-col ()
+  (let ((here (point)))
+    (goto-char (xrdb-point 'boi))
+    (prog1
+	(current-column)
+      (goto-char here))))
+
+(defvar xrdb-prompt-history nil)
+
+(defun xrdb-prompt-for-subdivision ()
+  (let ((options '(("buffer" . buffer)
+		   ("paragraphs" . paragraph)
+		   ("pages" . page)
+		   ("lines" . line)))
+	(completion-ignore-case t))
+    (cdr (assoc
+	  (completing-read "Subdivide alignment by? " options nil t
+			   (cons (format "%s" xrdb-subdivide-by) 0)
+			   'xrdb-prompt-history)
+	  options))))
 
 
 ;; commands
 (defun xrdb-electric-separator (arg)
@@ -147,7 +241,9 @@
 
 
 ;; commands
 (defun xrdb-electric-separator (arg)
-  "Insert the separator character.
-Re-align the line unless an argument is given."
+  "Insert a colon, and possibly indent line.
+Numeric argument inserts that many separators.  If the numeric
+argument is not given, or is 1, and the separator is not inserted in a
+comment, then the line is indented according to `xrdb-subdivide-by'."
   (interactive "P")
@@ -153,4 +249,3 @@
   (interactive "P")
-  ;; first insert the character
   (self-insert-command (prefix-numeric-value arg))
   ;; only do electric behavior if arg is not given
@@ -155,12 +250,9 @@
   (self-insert-command (prefix-numeric-value arg))
   ;; only do electric behavior if arg is not given
-  (if (not arg)
-      (xrdb-align-to (xrdb-point 'bol)
-		     (xrdb-point 'bonl)
-		     (save-excursion
-		       (beginning-of-line)
-		       (forward-comment (- (point-max)))
-		       (beginning-of-line)
-		       (xrdb-skip-to-separator)
-		       (current-column)))))
+  (or arg
+      (xrdb-in-comment-p)
+      (xrdb-indent-line))
+  ;; compress whitespace
+  (and xrdb-compress-whitespace
+       (just-one-space)))
 
@@ -166,19 +258,7 @@
 
-(defun xrdb-align-to (start end goalcolumn)
-  (interactive "r\nnAlign to column: ")
-  (save-excursion
-    (save-restriction
-      (narrow-to-region start end)
-      (beginning-of-buffer)
-      (while (< (point) (point-max))
-	(if (and (not (looking-at xrdb-comment-re))
-		 (xrdb-skip-to-separator)
-		 goalcolumn)
-	    (indent-code-rigidly (xrdb-point 'bol)
-				 (xrdb-point 'bonl)
-				 (- goalcolumn (current-column))))
-	(forward-line 1)))))
-
-(defun xrdb-indent-line (arg)
-  "Re-align current line."
+(defun xrdb-electric-bang (arg)
+  "Insert an exclamation point to start a comment.
+Numeric argument inserts that many exclamation characters.  If the
+numeric argument is not given, or is 1, and the bang character is the
+first character on a line, the line is indented to column zero."
   (interactive "P")
@@ -184,19 +264,10 @@
   (interactive "P")
-  ;; narrow to the region specified by xrdb-subdivide-by
-  (save-excursion
-    (save-restriction
-      (widen)
-      (cond
-       ((eq xrdb-subdivide-by 'buffer))
-       ((eq xrdb-subdivide-by 'page)
-	(narrow-to-page))
-       ((eq xrdb-subdivide-by 'paragraph)
-	(narrow-to-region (xrdb-point 'bop) (xrdb-point 'eop)))
-       (t
-	(narrow-to-region (xrdb-point 'bopl) (xrdb-point 'bonl))
-	))
-      ;; indent line
-      (xrdb-align-to (xrdb-point 'bol) (xrdb-point 'bonl)
-		     (xrdb-region-goal-column))
-      )))
+  (let ((how-many (prefix-numeric-value arg)))
+    (self-insert-command how-many)
+    (save-excursion
+      (if (and (= how-many 1)
+	       (xrdb-in-comment-p)
+	       (memq (char-before (xrdb-point 'boi)) '(?\n nil)))
+	  (indent-line-to 0)))
+    ))
 
@@ -202,12 +273,29 @@
 
-(defun xrdb-indent-region (start end)
-  "Re-align region."
-  (interactive "r")
-  ;; narrow to region
-  (save-excursion
-    (save-restriction
-      (narrow-to-region start end)
-      (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column))
-      )))
+(defun xrdb-indent-line (&optional arg)
+  "Align the current line with the nearest previous non-comment line.
+With universal argument \\[universal-argument], insert just a TAB."
+  (interactive "P")
+  (if arg
+      (insert "\t")
+    (let ((here (point))
+	  goalcol)
+      (while (and (zerop (forward-line -1))
+		  (or (looking-at xrdb-comment-re)
+		      (not (setq goalcol (xrdb-skip-to-separator))))))
+      ;; maybe we didn't find one
+      (goto-char here)
+      (and goalcol
+	   (xrdb-align-to-column goalcol)))
+    ))
+
+(defun xrdb-indent-region (start end &optional arg)
+  "Indent all lines in the region according to `xrdb-subdivide-by'.
+With optional numeric argument, prompt for subdivision."
+  (interactive "r\nP")
+  (xrdb-align-to-column
+   (xrdb-guess-goal-column (if arg
+			       (xrdb-prompt-for-subdivision)
+			     xrdb-subdivide-by))
+   start end))
 
 (defun xrdb-indent-page ()
@@ -212,4 +300,4 @@
 
 (defun xrdb-indent-page ()
-  "Re-align the current page."
+  "Indent all lines in the page according to `xrdb-subdivide-by'."
   (interactive)
@@ -215,8 +303,7 @@
   (interactive)
-  (save-excursion
-    (save-restriction
-      (narrow-to-page)
-      (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column))
-      )))
+  (xrdb-align-to-column
+   (xrdb-guess-goal-column 'page)
+   (xrdb-point 'bopg)
+   (xrdb-point 'eopg)))
 
 (defun xrdb-indent-paragraph ()
@@ -221,4 +308,4 @@
 
 (defun xrdb-indent-paragraph ()
-  "Re-align the current paragraph."
+  "Indent all lines in the paragraph according to `xrdb-subdivide-by'."
   (interactive)
@@ -224,17 +311,6 @@
   (interactive)
-  (save-excursion
-    (save-restriction
-      (narrow-to-region (xrdb-point 'bop) (xrdb-point 'eop))
-      (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column))
-      )))
-
-(defun xrdb-indent-buffer (arg)
-  "Re-align the entire buffer.
-Alignment calculations are controlled by the variable
-`xrdb-subdivide-by', which can take the values `buffer', `paragraph',
-`page', or `line', with the following meanings:
-
- buffer - all non-comment lines are aligned with the longest line in
-          the buffer.  Since every line must be scanned, this will
-	  take the longest to perform.
+  (xrdb-align-to-column
+   (xrdb-guess-goal-column 'paragraph)
+   (xrdb-point 'bop)
+   (xrdb-point 'eop)))
 
@@ -240,12 +316,5 @@
 
- paragraph - alignment of lines spanning paragraphs. A paragraph is
-             defined as all contiguous lines between blank or comment
-	     lines.
-
- page - alignment of lines spanning pages (i.e. separated by
-        page-delimiter, usually ^L).
-
- none - alignment of lines based on the previous line.
-
-With optional \\[universal-argument], queries for alignment subdivision."
+(defun xrdb-indent-buffer (&optional arg)
+  "Indent all lines in the buffer according to `xrdb-subdivide-by'.
+With optional numeric argument, prompt for subdivision."
   (interactive "P")
@@ -251,13 +320,34 @@
   (interactive "P")
-  (let ((align-by (if (not arg)
-		      xrdb-subdivide-by
-		    (completing-read
-		     "Align by: "
-		     '(("buffer" . buffer)
-		       ("paragraph" . paragraph)
-		       ("page" . page)
-		       ("line" . line))
-		     nil t (format "%s" xrdb-subdivide-by)))))
-    (message "Aligning by %s..." align-by)
+  (let ((subdivide-by (if arg
+			  (xrdb-prompt-for-subdivision)
+			xrdb-subdivide-by)))
+    (save-excursion
+      (beginning-of-buffer)
+      (if (eq subdivide-by 'buffer)
+	  (xrdb-align-to-column (xrdb-guess-goal-column 'buffer)
+				(point-min) (point-max))
+	(let (mvfwdfunc indentfunc)
+	  (cond
+	   ((eq subdivide-by 'paragraph)
+	    (setq mvfwdfunc 'forward-paragraph
+		  indentfunc 'xrdb-indent-paragraph))
+	   ((eq subdivide-by 'page)
+	    (setq mvfwdfunc 'forward-page
+		  indentfunc 'xrdb-indent-page))
+	   ((eq subdivide-by 'line)
+	    (setq mvfwdfunc 'forward-line
+		  indentfunc 'xrdb-indent-page))
+	   (t (error "Illegal alignment subdivision: %s" subdivide-by))
+	   )
+	  (while (< (point) (point-max))
+	    (funcall indentfunc)
+	    (funcall mvfwdfunc 1))
+	  )))))
+
+
+;; internal alignment functions
+(defun xrdb-align-to-column (goalcol &optional start end)
+  (let ((start (or start (xrdb-point 'bol)))
+	(end (or end (xrdb-point 'bonl))))
     (save-excursion
       (save-restriction
@@ -262,48 +352,48 @@
     (save-excursion
       (save-restriction
-	(widen)
-	(cond
-	 ;; by buffer
-	 ((eq align-by 'buffer)
-	  (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column)))
-	 ;; by paragraph
-	 ((eq align-by 'paragraph)
-	  (beginning-of-buffer)
-	  (while (< (point) (point-max))
-	    (narrow-to-region (point) (xrdb-point 'eop))
-	    (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column))
-	    (beginning-of-buffer)
-	    (widen)
-	    (forward-paragraph 1)
-	    ))
-	 ;; by page
-	 ((eq align-by 'page)
-	  (beginning-of-buffer)
-	  (while (< (point) (point-max))
-	    (narrow-to-region (point) (xrdb-point 'eopg))
-	    (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column))
-	    (beginning-of-buffer)
-	    (widen)
-	    (forward-page 1)
-	    ))
-	 ;; by line
-	 (t
-	  (beginning-of-buffer)
-	  (let ((prev-goalcol 0))
-	    (while (< (point) (point-max))
-	      ;; skip comments and blank lines
-	      (if (not (looking-at paragraph-start))
-		  (progn
-		    (xrdb-align-to (xrdb-point 'bol) (xrdb-point 'bonl)
-				   prev-goalcol)
-		    (xrdb-skip-to-separator)
-		    (setq prev-goalcol (- (point) (xrdb-point 'boi)))
-		    ))
-	      (forward-line 1))))
-	 )))
-    (message "Aligning by %s... done." align-by)
-    ))
+	(narrow-to-region start end)
+	(beginning-of-buffer)
+	(while (< (point) (point-max))
+	  (if (and (not (looking-at xrdb-comment-re))
+		   (xrdb-skip-to-separator))
+	      (indent-line-to (max 0 (+ goalcol
+					(- (current-column))
+					(xrdb-boi-col))
+				   )))
+	  (forward-line 1))
+	))))
+
+(defun xrdb-guess-goal-column (subdivide-by)
+  ;; Returns the goal column of the current line based on SUBDIVIDE-BY,
+  ;; which can be any value allowed by `xrdb-subdivide-by'.
+  (let ((here (point))
+	(goalcol 0))
+    (save-restriction
+      (cond
+       ((eq subdivide-by 'line)
+	(while (and (zerop (forward-line -1))
+		    (or (looking-at xrdb-comment-re)
+			(not (xrdb-skip-to-separator)))))
+	;; maybe we didn't find one
+	(if (not (xrdb-skip-to-separator))
+	    (goto-char here))
+	(narrow-to-region (xrdb-point 'bol) (xrdb-point 'bonl)))
+       ((eq subdivide-by 'page)
+	(narrow-to-page))
+       ((eq subdivide-by 'paragraph)
+	(narrow-to-region (xrdb-point 'bop) (xrdb-point 'eop)))
+       ((eq subdivide-by 'buffer))
+       (t (error "Illegal alignment subdivision: %s" subdivide-by)))
+      (goto-char (point-min))
+      (while (< (point) (point-max))
+	(if (and (not (looking-at xrdb-comment-re))
+		 (xrdb-skip-to-separator))
+	    (setq goalcol (max goalcol (- (current-column) (xrdb-boi-col)))))
+	(forward-line 1)))
+    (goto-char here)
+    goalcol))
+
 
 
 ;; major-mode stuff
 (defvar xrdb-mode-abbrev-table nil
@@ -306,11 +396,11 @@
 
 
 ;; major-mode stuff
 (defvar xrdb-mode-abbrev-table nil
-  "Abbrev table used in `xrdb-mode' buffers.")
+  "Abbreviation table used in `xrdb-mode' buffers.")
 (define-abbrev-table 'xrdb-mode-abbrev-table ())
 
 
 (defvar xrdb-mode-syntax-table nil
   "Syntax table used in `xrdb-mode' buffers.")
 (if xrdb-mode-syntax-table
@@ -311,8 +401,8 @@
 (define-abbrev-table 'xrdb-mode-abbrev-table ())
 
 
 (defvar xrdb-mode-syntax-table nil
   "Syntax table used in `xrdb-mode' buffers.")
 (if xrdb-mode-syntax-table
-    ()
+    nil
   (setq xrdb-mode-syntax-table (make-syntax-table))
@@ -318,6 +408,15 @@
   (setq xrdb-mode-syntax-table (make-syntax-table))
-  (modify-syntax-entry ?!  "<" xrdb-mode-syntax-table)
-  (modify-syntax-entry ?\n ">" xrdb-mode-syntax-table))
+  (modify-syntax-entry ?!  "<"    xrdb-mode-syntax-table)
+  (modify-syntax-entry ?\\ "\\"   xrdb-mode-syntax-table)
+  (modify-syntax-entry ?\n ">"    xrdb-mode-syntax-table)
+  (modify-syntax-entry ?/  ". 14" xrdb-mode-syntax-table)
+  (modify-syntax-entry ?*  "_ 23" xrdb-mode-syntax-table)
+  (modify-syntax-entry ?.  "_"    xrdb-mode-syntax-table)
+  (modify-syntax-entry ?#  "_"    xrdb-mode-syntax-table)
+  (modify-syntax-entry ??  "_"    xrdb-mode-syntax-table)
+  (modify-syntax-entry ?<  "("    xrdb-mode-syntax-table)
+  (modify-syntax-entry ?>  ")"    xrdb-mode-syntax-table)
+  )
 
 
 (defvar xrdb-mode-map ()
@@ -325,17 +424,17 @@
 (if xrdb-mode-map
     ()
   (setq xrdb-mode-map (make-sparse-keymap))
-  (let ((ekey (char-to-string xrdb-separator-char)))
-    ;; make the separator key electric
-    (define-key xrdb-mode-map ekey 'xrdb-electric-separator)
-    (define-key xrdb-mode-map "\t" 'xrdb-indent-line)
-    (define-key xrdb-mode-map "\C-c\C-a" 'xrdb-indent-paragraph)
-    (define-key xrdb-mode-map "\C-c\C-b" 'xrdb-submit-bug-report)
-    (define-key xrdb-mode-map "\C-c\C-p" 'xrdb-indent-page)
-    (define-key xrdb-mode-map "\C-c\C-r" 'xrdb-indent-region)
-    (define-key xrdb-mode-map "\C-c\C-u" 'xrdb-indent-buffer)
-    (define-key xrdb-mode-map "\C-c>"    'xrdb-align-to)
-    ))
+  ;; make the separator key electric
+  (define-key xrdb-mode-map ":"        'xrdb-electric-separator)
+  (define-key xrdb-mode-map "!"        'xrdb-electric-bang)
+  (define-key xrdb-mode-map "\t"       'xrdb-indent-line)
+  (define-key xrdb-mode-map "\C-c\C-a" 'xrdb-indent-buffer)
+  (define-key xrdb-mode-map "\C-c\C-b" 'xrdb-submit-bug-report)
+  (define-key xrdb-mode-map "\C-c\C-c" 'xrdb-database-merge-buffer-or-region)
+  (define-key xrdb-mode-map "\C-c\C-f" 'xrdb-indent-paragraph)
+  (define-key xrdb-mode-map "\C-c\C-p" 'xrdb-indent-page)
+  (define-key xrdb-mode-map "\C-c\C-r" 'xrdb-indent-region)
+  )
 
 ;;;###autoload
 (defun xrdb-mode ()
@@ -349,6 +448,7 @@
   (use-local-map xrdb-mode-map)
   ;; local variables
   (make-local-variable 'parse-sexp-ignore-comments)
+  (make-local-variable 'comment-start-skip)
   (make-local-variable 'comment-start)
   (make-local-variable 'comment-end)
   (make-local-variable 'paragraph-start)
@@ -356,6 +456,7 @@
   (make-local-variable 'paragraph-ignore-fill-prefix)
   ;; now set their values
   (setq parse-sexp-ignore-comments t
+	comment-start-skip "![ \t]*"
 	comment-start "! "
 	comment-end "")
   (setq indent-region-function 'xrdb-indent-region
@@ -369,6 +470,7 @@
 ;; faces and font-locking
 (defvar xrdb-option-name-face 'xrdb-option-name-face
   "Face for option name on a line in an X resource db file")
+
 (defvar xrdb-option-value-face 'xrdb-option-value-face
   "Face for option value on a line in an X resource db file")
 
@@ -392,27 +494,40 @@
 
 
 
-;; commands
-(defun xrdb-region-goal-column ()
-  ;; Returns the goal column of the current region.  Assumes the
-  ;; buffer has been narrowed to the region to scan.
-  (save-excursion
-    (beginning-of-buffer)
-    (let ((goalcol -1)
-	  linecol)
-      (while (< (point) (point-max))
-	;; skip any comments
-	(if (and (not (looking-at xrdb-comment-re))
-		 (xrdb-skip-to-separator)
-		 (< goalcol (setq linecol (current-column)))
-		 )
-	    (setq goalcol linecol))
-	(forward-line 1))
-      (if (< goalcol 0)
-	  nil
-	goalcol))))
+;; merging and manipulating the X resource database
+(defun xrdb-database-merge-buffer-or-region (start end)
+  "Merge the current buffer's resources into the X resource database.
+`xrdb-program' is the program to actually call, with the arguments
+specified in `xrdb-program-args'.  This latter can be set to do either 
+a merge or a load, etc.  Also, if the file local variable
+`xrdb-master-file' is non-nil, then it is merged instead of the
+buffer's file.
+
+If the current region is active, it is merged instead of the buffer,
+and this overrides any use of `xrdb-master-file'."
+  (interactive
+   ;; the idea here is that if the region is inactive, start and end
+   ;; will be nil, if not passed in programmatically
+   (list (xrdb-safe (and (mark) (region-beginning)))
+	 (xrdb-safe (and (mark) (region-end)))))
+  (let ((outbuf (get-buffer-create "*Shell Command Output*")))
+    ;; I prefer the XEmacs way of doing this, but this is the easiest
+    ;; way to work in both XEmacs and Emacs.
+    (with-current-buffer outbuf (erase-buffer))
+    (cond
+     ((and start end)
+      (apply 'call-process-region start end xrdb-program nil outbuf t
+	     xrdb-program-args))
+     (xrdb-master-file
+      (apply 'call-process xrdb-program xrdb-master-file outbuf t
+	     xrdb-program-args))
+     (t
+      (apply 'call-process-region (point-min) (point-max) xrdb-program
+	     nil outbuf t xrdb-program-args)))
+    (if (not (zerop (with-current-buffer outbuf (buffer-size))))
+	(pop-to-buffer outbuf))))
 
 
 
 ;; submitting bug reports
 
@@ -414,11 +529,8 @@
 
 
 
 ;; submitting bug reports
 
-(defconst xrdb-version "1.21"
-  "xrdb-mode version number.")
-
 (defconst xrdb-mode-help-address "tools-help@python.org"
   "Address for xrdb-mode bug reports.")
 
@@ -422,10 +534,7 @@
 (defconst xrdb-mode-help-address "tools-help@python.org"
   "Address for xrdb-mode bug reports.")
 
-;; (eval-when-compile
-;;  (require 'reporter))
-
 (defun xrdb-submit-bug-report ()
   "Submit via mail a bug report on xrdb-mode."
   (interactive)
   ;; load in reporter
@@ -428,7 +537,8 @@
 (defun xrdb-submit-bug-report ()
   "Submit via mail a bug report on xrdb-mode."
   (interactive)
   ;; load in reporter
+  (require 'reporter)
   (let ((reporter-prompt-for-summary-p t)
 	(varlist '(xrdb-subdivide-by
 		   xrdb-mode-hook
@@ -432,6 +542,7 @@
   (let ((reporter-prompt-for-summary-p t)
 	(varlist '(xrdb-subdivide-by
 		   xrdb-mode-hook
+		   xrdb-compress-whitespace
 		   )))
     (and (if (y-or-n-p "Do you want to submit a report on xrdb-mode? ")
 	     t
@@ -439,8 +550,10 @@
 	   nil)
 	 (require 'reporter)
 	 (reporter-submit-bug-report
-	  xrdb-mode-help-address "xrdb-mode" varlist nil nil "Dear Barry,")
+	  xrdb-mode-help-address
+	  (format "xrdb-mode %s" xrdb-version)
+	  varlist nil nil "Dear Barry,")
 	 )))
 
 
 (provide 'xrdb-mode)
@@ -443,6 +556,5 @@
 	 )))
 
 
 (provide 'xrdb-mode)
-
 ;;; xrdb-mode.el ends here