changeset 111870:b47e85affa59

Derive from prog-mode, use derived-mode-p, and fix up various minor style issues in lisp/progmodes. * lisp/progmodes/vhdl-mode.el (vhdl-write-file-hooks-init) (vhdl-hs-minor-mode, vhdl-ps-print-init): Fix make-local-variable -> make-local-hook. * lisp/progmodes/sh-script.el (sh-require-final-newline): Remove. (sh-set-shell): Don't set require-final-newline since it's already done by prog-mode. * lisp/progmodes/modula2.el (m2-mode): Don't make m2-end-comment-column since we never set it. * lisp/progmodes/ebrowse.el (ebrowse-set-tree-indentation): Use read-string and standard prompt. * lisp/progmodes/dcl-mode.el (dcl-mode-map): Move init into declaration. * lisp/progmodes/meta-mode.el (meta-mode-abbrev-table): Merge init and decl. (meta-common-mode-syntax-table): Rename from meta-mode-syntax-table. (meta-common-mode-map): Rename from meta-mode-map. Remove C-m binding, which is a user preference, not mode specific. (meta-common-mode): New major mode; replace meta-common-initialization. * lisp/progmodes/js.el (js-mode): Call syntax-propertize rather than messing around with font-lock. * lisp/progmodes/etags.el (select-tags-table-mode): Derive from special-mode. * lisp/progmodes/octave-mod.el (octave-mode): * lisp/progmodes/gdb-mi.el (gdb-inferior-io-mode, gdb-threads-mode) (gdb-memory-mode, gdb-disassembly-mode, gdb-breakpoints-mode) (gdb-frames-mode, gdb-locals-mode, gdb-registers-mode): Let define-derived-mode do its job. * lisp/progmodes/cpp.el (cpp-edit-mode-map): Move initialization into declaration. (cpp-edit-mode): Use define-derived-mode. (cpp-edit-load): Use derived-mode-p. * lisp/progmodes/mixal-mode.el (mixal-mode): * lisp/progmodes/f90.el (f90-mode): * lisp/progmodes/cfengine.el (cfengine-mode): Don't bother setting require-final-newline since prog-mode does it already. * lisp/progmodes/cc-cmds.el (c-update-modeline): Use match-string. * lisp/progmodes/asm-mode.el (asm-mode-map): Fix menu setup. * lisp/progmodes/antlr-mode.el: Require cc-mode upfront. (antlr-mode-syntax-table, antlr-action-syntax-table): Initialize in the declaration. (antlr-directory-dependencies, antlr-show-makefile-rules): Use derived-mode-p. (antlr-language-option): Don't assume point-min==1. (antlr-mode): Use define-derived-mode. * lisp/progmodes/ada-mode.el: Use derived-mode-p. (ada-mode): Use define-derived-mode. Use hack-local-variables-hook. * lisp/progmodes/vhdl-mode.el (vhdl-mode): * lisp/progmodes/verilog-mode.el (verilog-mode): * lisp/progmodes/vera-mode.el (vera-mode): * lisp/progmodes/sql.el (sql-mode): * lisp/progmodes/scheme.el (scheme-mode): * lisp/progmodes/perl-mode.el (perl-mode): * lisp/progmodes/octave-inf.el (inferior-octave-mode): * lisp/progmodes/autoconf.el (autoconf-mode): * lisp/progmodes/m4-mode.el (m4-mode): * lisp/progmodes/inf-lisp.el (inferior-lisp-mode): * lisp/progmodes/idlwave.el (idlwave-mode): * lisp/progmodes/icon.el (icon-mode): * lisp/progmodes/idlw-help.el (idlwave-help-mode): * lisp/progmodes/dcl-mode.el (dcl-mode): * lisp/progmodes/idlw-shell.el (idlwave-shell-mode): * lisp/progmodes/ebrowse.el (ebrowse-tree-mode, ebrowse-electric-list-mode) (ebrowse-member-mode, ebrowse-electric-position-mode): Use define-derived-mode. * lisp/progmodes/xscheme.el (xscheme-start) (local-set-scheme-interaction-buffer, scheme-interaction-mode): * lisp/progmodes/which-func.el (which-function): * lisp/progmodes/vhdl-mode.el (vhdl-set-style): * lisp/progmodes/verilog-mode.el (verilog-set-compile-command) (verilog-modify-compile-command, verilog-error-regexp-add-xemacs) (verilog-set-define, verilog-auto-reeval-locals): * lisp/progmodes/sql.el (sql-product-font-lock, sql-interactive-mode): * lisp/progmodes/simula.el (simula-mode): * lisp/progmodes/scheme.el (scheme-mode-variables, dsssl-mode): * lisp/progmodes/python.el (python-check, python-mode): * lisp/progmodes/prolog.el (prolog-mode-variables): * lisp/progmodes/gud.el (gud-tooltip-activate-mouse-motions): * lisp/progmodes/ebrowse.el (ebrowse-view-file-other-frame): * lisp/progmodes/delphi.el (delphi-mode): * lisp/progmodes/cc-styles.el (c-setup-paragraph-variables): * lisp/progmodes/cc-mode.el (c-basic-common-init, c-common-init) (c-font-lock-init): Move make-local-variable to their setq. * lisp/progmodes/xscheme.el (exit-scheme-interaction-mode) (xscheme-enter-interaction-mode, xscheme-enter-debugger-mode) (xscheme-debugger-mode-p, xscheme-send-string-1): * lisp/progmodes/tcl.el (inferior-tcl-proc, tcl-current-word) (tcl-load-file, tcl-restart-with-file): * lisp/progmodes/ps-mode.el (ps-run-running): * lisp/progmodes/gdb-mi.el (gud-watch, gdb-mouse-set-clear-breakpoint): * lisp/progmodes/js.el (js--get-all-known-symbols): * lisp/progmodes/inf-lisp.el (inferior-lisp-proc): * lisp/progmodes/idlwave.el (idlwave-beginning-of-statement) (idlwave-template, idlwave-update-buffer-routine-info) (idlwave-update-current-buffer-info) (idlwave-get-routine-info-from-buffers, idlwave-choose) (idlwave-scan-class-info, idlwave-fix-keywords) (idlwave-list-buffer-load-path-shadows): * lisp/progmodes/idlw-toolbar.el (idlwave-toolbar, idlwave-toolbar-add) (idlwave-toolbar-remove): * lisp/progmodes/idlw-shell.el (idlwave-shell-save-and-action) (idlwave-shell-file-name, idlwave-shell-electric-debug-all-off) (idlwave-shell-menu-def): * lisp/progmodes/idlw-complete-structtag.el (idlwave-prepare-structure-tag-completion): * lisp/progmodes/gud.el (gud-set-buffer): * lisp/progmodes/f90.el (f90-backslash-not-special): * lisp/progmodes/delphi.el (delphi-find-unit): Use derived-mode-p.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Fri, 10 Dec 2010 15:00:25 -0500
parents 2b8673bc05c8
children d21197a7fc63
files lisp/ChangeLog lisp/progmodes/ada-mode.el lisp/progmodes/ada-prj.el lisp/progmodes/antlr-mode.el lisp/progmodes/asm-mode.el lisp/progmodes/autoconf.el lisp/progmodes/cc-cmds.el lisp/progmodes/cc-mode.el lisp/progmodes/cc-styles.el lisp/progmodes/cfengine.el lisp/progmodes/compile.el lisp/progmodes/cpp.el lisp/progmodes/dcl-mode.el lisp/progmodes/delphi.el lisp/progmodes/ebrowse.el lisp/progmodes/etags.el lisp/progmodes/f90.el lisp/progmodes/gdb-mi.el lisp/progmodes/gud.el lisp/progmodes/icon.el lisp/progmodes/idlw-complete-structtag.el lisp/progmodes/idlw-help.el lisp/progmodes/idlw-shell.el lisp/progmodes/idlw-toolbar.el lisp/progmodes/idlwave.el lisp/progmodes/inf-lisp.el lisp/progmodes/js.el lisp/progmodes/m4-mode.el lisp/progmodes/meta-mode.el lisp/progmodes/mixal-mode.el lisp/progmodes/modula2.el lisp/progmodes/octave-inf.el lisp/progmodes/octave-mod.el lisp/progmodes/perl-mode.el lisp/progmodes/prolog.el lisp/progmodes/ps-mode.el lisp/progmodes/python.el lisp/progmodes/scheme.el lisp/progmodes/sh-script.el lisp/progmodes/simula.el lisp/progmodes/sql.el lisp/progmodes/tcl.el lisp/progmodes/vera-mode.el lisp/progmodes/verilog-mode.el lisp/progmodes/vhdl-mode.el lisp/progmodes/which-func.el lisp/progmodes/xscheme.el
diffstat 47 files changed, 715 insertions(+), 1021 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/ChangeLog	Fri Dec 10 15:00:25 2010 -0500
@@ -1,3 +1,118 @@
+2010-12-10  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	Derive from prog-mode, use derived-mode-p, and fix up various
+	minor style issues in lisp/progmodes.
+
+	* progmodes/vhdl-mode.el (vhdl-mode):
+	* progmodes/verilog-mode.el (verilog-mode):
+	* progmodes/vera-mode.el (vera-mode):
+	* progmodes/sql.el (sql-mode):
+	* progmodes/scheme.el (scheme-mode):
+	* progmodes/perl-mode.el (perl-mode):
+	* progmodes/octave-inf.el (inferior-octave-mode):
+	* progmodes/autoconf.el (autoconf-mode):
+	* progmodes/m4-mode.el (m4-mode):
+	* progmodes/inf-lisp.el (inferior-lisp-mode):
+	* progmodes/idlwave.el (idlwave-mode):
+	* progmodes/icon.el (icon-mode):
+	* progmodes/idlw-help.el (idlwave-help-mode):
+	* progmodes/dcl-mode.el (dcl-mode):
+	* progmodes/idlw-shell.el (idlwave-shell-mode):
+	* progmodes/ebrowse.el (ebrowse-tree-mode, ebrowse-electric-list-mode)
+	(ebrowse-member-mode, ebrowse-electric-position-mode):
+	Use define-derived-mode.
+
+	* progmodes/xscheme.el (exit-scheme-interaction-mode)
+	(xscheme-enter-interaction-mode, xscheme-enter-debugger-mode)
+	(xscheme-debugger-mode-p, xscheme-send-string-1):
+	* progmodes/tcl.el (inferior-tcl-proc, tcl-current-word)
+	(tcl-load-file, tcl-restart-with-file):
+	* progmodes/ps-mode.el (ps-run-running):
+	* progmodes/gdb-mi.el (gud-watch, gdb-mouse-set-clear-breakpoint):
+	* progmodes/js.el (js--get-all-known-symbols):
+	* progmodes/inf-lisp.el (inferior-lisp-proc):
+	* progmodes/idlwave.el (idlwave-beginning-of-statement)
+	(idlwave-template, idlwave-update-buffer-routine-info)
+	(idlwave-update-current-buffer-info)
+	(idlwave-get-routine-info-from-buffers, idlwave-choose)
+	(idlwave-scan-class-info, idlwave-fix-keywords)
+	(idlwave-list-buffer-load-path-shadows):
+	* progmodes/idlw-toolbar.el (idlwave-toolbar, idlwave-toolbar-add)
+	(idlwave-toolbar-remove):
+	* progmodes/idlw-shell.el (idlwave-shell-save-and-action)
+	(idlwave-shell-file-name, idlwave-shell-electric-debug-all-off)
+	(idlwave-shell-menu-def):
+	* progmodes/idlw-complete-structtag.el
+	(idlwave-prepare-structure-tag-completion):
+	* progmodes/gud.el (gud-set-buffer):
+	* progmodes/f90.el (f90-backslash-not-special):
+	* progmodes/delphi.el (delphi-find-unit): Use derived-mode-p.
+
+	* progmodes/xscheme.el (xscheme-start)
+	(local-set-scheme-interaction-buffer, scheme-interaction-mode):
+	* progmodes/which-func.el (which-function):
+	* progmodes/vhdl-mode.el (vhdl-set-style):
+	* progmodes/verilog-mode.el (verilog-set-compile-command)
+	(verilog-modify-compile-command, verilog-error-regexp-add-xemacs)
+	(verilog-set-define, verilog-auto-reeval-locals):
+	* progmodes/sql.el (sql-product-font-lock, sql-interactive-mode):
+	* progmodes/simula.el (simula-mode):
+	* progmodes/scheme.el (scheme-mode-variables, dsssl-mode):
+	* progmodes/python.el (python-check, python-mode):
+	* progmodes/prolog.el (prolog-mode-variables):
+	* progmodes/gud.el (gud-tooltip-activate-mouse-motions):
+	* progmodes/ebrowse.el (ebrowse-view-file-other-frame):
+	* progmodes/delphi.el (delphi-mode):
+	* progmodes/cc-styles.el (c-setup-paragraph-variables):
+	* progmodes/cc-mode.el (c-basic-common-init, c-common-init)
+	(c-font-lock-init): Move make-local-variable to their setq.
+
+	* progmodes/vhdl-mode.el (vhdl-write-file-hooks-init)
+	(vhdl-hs-minor-mode, vhdl-ps-print-init): Fix make-local-variable ->
+	make-local-hook.
+	* progmodes/sh-script.el (sh-require-final-newline): Remove.
+	(sh-set-shell): Don't set require-final-newline since it's already done
+	by prog-mode.
+	* progmodes/modula2.el (m2-mode): Don't make m2-end-comment-column
+	since we never set it.
+	* progmodes/ebrowse.el (ebrowse-set-tree-indentation):
+	Use read-string and standard prompt.
+	* progmodes/dcl-mode.el (dcl-mode-map): Move init into declaration.
+	* progmodes/meta-mode.el (meta-mode-abbrev-table): Merge init and decl.
+	(meta-common-mode-syntax-table): Rename from meta-mode-syntax-table.
+	(meta-common-mode-map): Rename from meta-mode-map.
+	Remove C-m binding, which is a user preference, not mode specific.
+	(meta-common-mode): New major mode; replace meta-common-initialization.
+	* progmodes/js.el (js-mode): Call syntax-propertize rather than messing
+	around with font-lock.
+	* progmodes/etags.el (select-tags-table-mode):
+	Derive from special-mode.
+	* progmodes/octave-mod.el (octave-mode):
+	* progmodes/gdb-mi.el (gdb-inferior-io-mode, gdb-threads-mode)
+	(gdb-memory-mode, gdb-disassembly-mode, gdb-breakpoints-mode)
+	(gdb-frames-mode, gdb-locals-mode, gdb-registers-mode):
+	Let define-derived-mode do its job.
+	* progmodes/cpp.el (cpp-edit-mode-map):
+	Move initialization into declaration.
+	(cpp-edit-mode): Use define-derived-mode.
+	(cpp-edit-load): Use derived-mode-p.
+	* progmodes/mixal-mode.el (mixal-mode):
+	* progmodes/f90.el (f90-mode):
+	* progmodes/cfengine.el (cfengine-mode): Don't bother setting
+	require-final-newline since prog-mode does it already.
+	* progmodes/cc-cmds.el (c-update-modeline): Use match-string.
+	* progmodes/asm-mode.el (asm-mode-map): Fix menu setup.
+	* progmodes/antlr-mode.el: Require cc-mode upfront.
+	(antlr-mode-syntax-table, antlr-action-syntax-table): Initialize in
+	the declaration.
+	(antlr-directory-dependencies, antlr-show-makefile-rules):
+	Use derived-mode-p.
+	(antlr-language-option): Don't assume point-min==1.
+	(antlr-mode): Use define-derived-mode.
+	* progmodes/ada-mode.el: Use derived-mode-p.
+	(ada-mode): Use define-derived-mode.
+	Use hack-local-variables-hook.
+
 2010-12-10  Stefan Monnier  <monnier@iro.umontreal.ca>
 
 	* textmodes/texinfo.el (texinfo-mode-map): Bind texinfo-insert-@end.
--- a/lisp/progmodes/ada-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/ada-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -461,6 +461,7 @@
 
 (defvar ada-mode-abbrev-table nil
   "Local abbrev table for Ada mode.")
+(define-abbrev-table 'ada-mode-abbrev-table ())
 
 (defvar ada-mode-syntax-table nil
   "Syntax table to be used for editing Ada source code.")
@@ -1123,16 +1124,8 @@
 (defvar ada-font-lock-syntactic-keywords) ; defined below
 
 ;;;###autoload
-(defun ada-mode ()
-  "Ada mode is the major mode for editing Ada code.
-\\{ada-mode-map}"
-
-  (interactive)
-  (kill-all-local-variables)
-
-  (set-syntax-table ada-mode-syntax-table)
-
-  (set (make-local-variable 'require-final-newline) mode-require-final-newline)
+(define-derived-mode ada-mode prog-mode "Ada"
+  "Ada mode is the major mode for editing Ada code."
 
   ;;  Set the paragraph delimiters so that one can select a whole block
   ;;  simply with M-h
@@ -1303,64 +1296,54 @@
       (define-key ada-mode-map ada-popup-key 'ada-popup-menu))
 
   ;;  Support for Abbreviations (the user still need to "M-x abbrev-mode"
-  (define-abbrev-table 'ada-mode-abbrev-table ())
   (setq local-abbrev-table ada-mode-abbrev-table)
 
   ;;  Support for which-function mode
-  (make-local-variable 'which-func-functions)
-  (setq which-func-functions '(ada-which-function))
+  (set (make-local-variable 'which-func-functions) '(ada-which-function))
 
   ;;  Support for indent-new-comment-line (Especially for XEmacs)
   (set (make-local-variable 'comment-multi-line) nil)
 
   ;;  Support for add-log
-  (set (make-local-variable 'add-log-current-defun-function) 'ada-which-function)
-
-  (setq major-mode 'ada-mode
-	mode-name "Ada")
-
-  (use-local-map ada-mode-map)
+  (set (make-local-variable 'add-log-current-defun-function)
+       'ada-which-function)
 
   (easy-menu-add ada-mode-menu ada-mode-map)
 
-  (set-syntax-table ada-mode-syntax-table)
-
   (set (make-local-variable 'skeleton-further-elements)
        '((< '(backward-delete-char-untabify
 	      (min ada-indent (current-column))))))
   (add-hook 'skeleton-end-hook  'ada-adjust-case-skeleton nil t)
 
-  (run-mode-hooks 'ada-mode-hook)
-
   ;;  To be run after the hook, in case the user modified
   ;;  ada-fill-comment-prefix
-  ;; FIXME: if the user modified ada-fill-comment-prefix in his .emacs
-  ;; then it was already available before running the hook, and if he
-  ;; modifies it in the hook, he might as well modify comment-start instead.
-  (set (make-local-variable 'comment-start) (or ada-fill-comment-prefix "-- "))
-
-  ;;  Run this after the hook to give the users a chance to activate
-  ;;  font-lock-mode
-
-  (unless (or (eval-when-compile (fboundp 'syntax-propertize-via-font-lock))
-              (featurep 'xemacs))
-    (ada-initialize-syntax-table-properties)
-    (add-hook 'font-lock-mode-hook 'ada-handle-syntax-table-properties nil t))
-
-  ;; the following has to be done after running the ada-mode-hook
-  ;; because users might want to set the values of these variable
-  ;; inside the hook
-  ;; FIXME: it might even be set later on via file-local vars, no?
-  ;; so maybe ada-keywords should be set lazily.
-  (cond ((eq ada-language-version 'ada83)
-	 (setq ada-keywords ada-83-keywords))
-	((eq ada-language-version 'ada95)
-	 (setq ada-keywords ada-95-keywords))
-	((eq ada-language-version 'ada2005)
-	 (setq ada-keywords ada-2005-keywords)))
-
-  (if ada-auto-case
-      (ada-activate-keys-for-case)))
+  (add-hook 'hack-local-variables-hook
+            (lambda ()
+              (set (make-local-variable 'comment-start)
+                   (or ada-fill-comment-prefix "-- "))
+
+              ;; Run this after the hook to give the users a chance
+              ;; to activate font-lock-mode.
+
+              (unless (or (eval-when-compile (fboundp 'syntax-propertize-via-font-lock))
+                          (featurep 'xemacs))
+                (ada-initialize-syntax-table-properties)
+                (add-hook 'font-lock-mode-hook
+                          'ada-handle-syntax-table-properties nil t))
+
+              ;; FIXME: ada-language-version might be set in the mode
+              ;; hook or it might even be set later on via file-local
+              ;; vars, so ada-keywords should be set lazily.
+              (cond ((eq ada-language-version 'ada83)
+                     (setq ada-keywords ada-83-keywords))
+                    ((eq ada-language-version 'ada95)
+                     (setq ada-keywords ada-95-keywords))
+                    ((eq ada-language-version 'ada2005)
+                     (setq ada-keywords ada-2005-keywords)))
+
+              (if ada-auto-case
+                  (ada-activate-keys-for-case)))
+            nil 'local))
 
 (defun ada-adjust-case-skeleton ()
   "Adjust the case of the text inserted by a skeleton."
@@ -4632,7 +4615,7 @@
 	      ["Gdb Documentation"      (info "gdb")
 	       (eq ada-which-compiler 'gnat)]
 	      ["Ada95 Reference Manual" (info "arm95") t])
-	     ("Options"  :included (eq major-mode 'ada-mode)
+	     ("Options"  :included (derived-mode-p 'ada-mode)
 	      ["Auto Casing" (setq ada-auto-case (not ada-auto-case))
 	       :style toggle :selected ada-auto-case]
 	      ["Auto Indent After Return"
@@ -4669,7 +4652,7 @@
 	      ["Load..."      ada-set-default-project-file t]
 	      ["New..."       ada-prj-new                  t]
 	      ["Edit..."      ada-prj-edit                 t])
-	     ("Goto"   :included (eq major-mode 'ada-mode)
+	     ("Goto"   :included (derived-mode-p 'ada-mode)
 	      ["Goto Declaration/Body"   ada-goto-declaration
 	       (eq ada-which-compiler 'gnat)]
 	      ["Goto Body"               ada-goto-body
@@ -4698,7 +4681,7 @@
 	      ["-"                       nil                    nil]
 	      ["Other File"              ff-find-other-file     t]
 	      ["Other File Other Window" ada-ff-other-window    t])
-	     ("Edit"   :included (eq major-mode 'ada-mode)
+	     ("Edit"   :included (derived-mode-p 'ada-mode)
 	      ["Search File On Source Path"  ada-find-file                t]
 	      ["------"                      nil                          nil]
 	      ["Complete Identifier"         ada-complete-identifier      t]
@@ -4730,7 +4713,7 @@
 	      ["-----"                       nil                          nil]
 	      ["Narrow to subprogram"        ada-narrow-to-defun          t])
 	     ("Templates"
-	      :included  (eq major-mode 'ada-mode)
+	      :included  (derived-mode-p 'ada-mode)
 	      ["Header"          ada-header          t]
 	      ["-"               nil                 nil]
 	      ["Package Body"    ada-package-body    t]
--- a/lisp/progmodes/ada-prj.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/ada-prj.el	Fri Dec 10 15:00:25 2010 -0500
@@ -514,11 +514,18 @@
 
       (set (make-local-variable 'ada-prj-ada-buffer) ada-buffer)
 
-      (use-local-map (copy-keymap custom-mode-map))
-      (local-set-key "\C-x\C-s" 'ada-prj-save)
+      (use-local-map
+       (let ((map (make-sparse-keymap)))
+         (set-keymap-parent map custom-mode-map)
+         (define-key map "\C-x\C-s" 'ada-prj-save)
+         map))
 
-      (make-local-variable 'widget-keymap)
-      (define-key widget-keymap "\C-x\C-s" 'ada-prj-save)
+      ;; FIXME: Not sure if this works!!
+      (set (make-local-variable 'widget-keymap)
+           (let ((map (make-sparse-keymap)))
+             (set-keymap-parent map widget-keymap)
+             (define-key map "\C-x\C-s" 'ada-prj-save)
+             map))
 
       (set (make-local-variable 'ada-old-cross-prefix)
 	   (ada-xref-get-project-field 'cross-prefix))
--- a/lisp/progmodes/antlr-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/antlr-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -87,6 +87,7 @@
   (require 'cl))
 
 (require 'easymenu)
+(require 'cc-mode)
 
 ;; Just to get the rid of the byte compiler warning.  The code for
 ;; this function and its friends are too complex for their own good.
@@ -1004,12 +1005,21 @@
 (defvar antlr-mode-hook nil
   "Hook called by `antlr-mode'.")
 
-(defvar antlr-mode-syntax-table nil
+(defvar antlr-mode-syntax-table
+  (let ((st (make-syntax-table)))
+    (c-populate-syntax-table st)
+    st)
   "Syntax table used in `antlr-mode' buffers.
 If non-nil, it will be initialized in `antlr-mode'.")
 
 ;; used for "in Java/C++ code" = syntactic-depth>0
-(defvar antlr-action-syntax-table nil
+(defvar antlr-action-syntax-table
+  (let ((st (copy-syntax-table antlr-mode-syntax-table))
+        (slist (nth 3 antlr-font-lock-defaults)))
+    (while slist
+      (modify-syntax-entry (caar slist) (cdar slist) st)
+      (setq slist (cdr slist)))
+    st)
   "Syntax table used for ANTLR action parsing.
 Initialized by `antlr-mode-syntax-table', changed by SYNTAX-ALIST in
 `antlr-font-lock-defaults'.  This table should be selected if you use
@@ -2189,7 +2199,7 @@
 		  (insert-file-contents file t nil nil t)
 		  (normal-mode t)	; necessary for major-mode, syntax
 					; table and `antlr-language'
-		  (when (eq major-mode 'antlr-mode)
+		  (when (derived-mode-p 'antlr-mode)
 		    (let* ((file-deps (antlr-file-dependencies))
 			   (file (car file-deps)))
 		      (when file-deps
@@ -2373,7 +2383,7 @@
 commentary with value `antlr-help-unknown-file-text' is added.  The
 *Help* buffer always starts with the text in `antlr-help-rules-intro'."
   (interactive)
-  (if (null (eq major-mode 'makefile-mode))
+  (if (null (derived-mode-p 'makefile-mode))
       (antlr-with-displaying-help-buffer 'antlr-insert-makefile-rules)
     (push-mark)
     (antlr-insert-makefile-rules t)))
@@ -2563,13 +2573,15 @@
   "Find language in `antlr-language-alist' for language option.
 If SEARCH is non-nil, find element for language option.  Otherwise, find
 the default language."
-  (let ((value (and search
-		    (save-excursion
-		      (goto-char (point-min))
-		      (re-search-forward (cdr antlr-language-limit-n-regexp)
-					 (car antlr-language-limit-n-regexp)
-					 t))
-		    (match-string 1)))
+  (let ((value
+         (and search
+              (save-excursion
+                (goto-char (point-min))
+                (re-search-forward (cdr antlr-language-limit-n-regexp)
+                                   (+ (point)
+                                      (car antlr-language-limit-n-regexp))
+                                   t))
+              (match-string 1)))
 	(seq antlr-language-alist)
 	r)
     ;; Like (find VALUE antlr-language-alist :key 'cddr :test 'member)
@@ -2581,35 +2593,20 @@
     (car r)))
 
 ;;;###autoload
-(defun antlr-mode ()
-  "Major mode for editing ANTLR grammar files.
-\\{antlr-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
+(define-derived-mode antlr-mode prog-mode
+  ;; FIXME: Since it uses cc-mode, it bumps into c-update-modeline's
+  ;; limitation to mode-name being a string.
+  ;; '("Antlr." (:eval (cadr (assq antlr-language antlr-language-alist))))
+  "Antlr" 
+  "Major mode for editing ANTLR grammar files."
+  :abbrev-table antlr-mode-abbrev-table
   (c-initialize-cc-mode)		; cc-mode is required
   (unless (fboundp 'c-forward-sws)	; see above
     (fset 'antlr-c-forward-sws 'c-forward-syntactic-ws))
   ;; ANTLR specific ----------------------------------------------------------
-  (setq major-mode 'antlr-mode
-	mode-name "Antlr")
-  (setq local-abbrev-table antlr-mode-abbrev-table)
-  (unless antlr-mode-syntax-table
-    (setq antlr-mode-syntax-table (make-syntax-table))
-    (c-populate-syntax-table antlr-mode-syntax-table))
-  (set-syntax-table antlr-mode-syntax-table)
-  (unless antlr-action-syntax-table
-    (let ((slist (nth 3 antlr-font-lock-defaults)))
-      (setq antlr-action-syntax-table
-	    (copy-syntax-table antlr-mode-syntax-table))
-      (while slist
-	(modify-syntax-entry (caar slist) (cdar slist)
-			     antlr-action-syntax-table)
-	(setq slist (cdr slist)))))
-  (use-local-map antlr-mode-map)
-  (make-local-variable 'antlr-language)
   (unless antlr-language
-    (setq antlr-language
-	  (or (antlr-language-option t) (antlr-language-option nil))))
+    (set (make-local-variable 'antlr-language)
+         (or (antlr-language-option t) (antlr-language-option nil))))
   (if (stringp (cadr (assq antlr-language antlr-language-alist)))
       (setq mode-name
 	    (concat "Antlr."
@@ -2627,33 +2624,24 @@
 	(t				; cc-mode upto 5.28
 	 (antlr-c-init-language-vars)))	; do it myself
   (c-basic-common-init antlr-language (or antlr-indent-style "gnu"))
-  (make-local-variable 'outline-regexp)
-  (make-local-variable 'outline-level)
-  (make-local-variable 'require-final-newline)
-  (make-local-variable 'indent-line-function)
-  (make-local-variable 'indent-region-function)
-  (setq outline-regexp "[^#\n\^M]"
-	outline-level 'c-outline-level)	; TODO: define own
-  (setq require-final-newline mode-require-final-newline)
-  (setq indent-line-function 'antlr-indent-line
-	indent-region-function nil)	; too lazy
+  (set (make-local-variable 'outline-regexp) "[^#\n\^M]")
+  (set (make-local-variable 'outline-level) 'c-outline-level) ;TODO: define own
+  (set (make-local-variable 'indent-line-function) 'antlr-indent-line)
+  (set (make-local-variable 'indent-region-function) nil)	; too lazy
   (setq comment-start "// "
  	comment-end ""
 	comment-start-skip "/\\*+ *\\|// *")
   ;; various -----------------------------------------------------------------
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults antlr-font-lock-defaults)
+  (set (make-local-variable 'font-lock-defaults) antlr-font-lock-defaults)
   (easy-menu-add antlr-mode-menu)
-  (make-local-variable 'imenu-create-index-function)
-  (setq imenu-create-index-function 'antlr-imenu-create-index-function)
-  (make-local-variable 'imenu-generic-expression)
-  (setq imenu-generic-expression t)	; fool stupid test
+  (set (make-local-variable 'imenu-create-index-function)
+       'antlr-imenu-create-index-function)
+  (set (make-local-variable 'imenu-generic-expression) t) ; fool stupid test
   (and antlr-imenu-name			; there should be a global variable...
        (fboundp 'imenu-add-to-menubar)
        (imenu-add-to-menubar
 	(if (stringp antlr-imenu-name) antlr-imenu-name "Index")))
-  (antlr-set-tabs)
-  (run-mode-hooks 'antlr-mode-hook))
+  (antlr-set-tabs))
 
 ;; A smarter version of `group-buffers-menu-by-mode-then-alphabetically' (in
 ;; XEmacs) could use the following property.  The header of the submenu would
--- a/lisp/progmodes/asm-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/asm-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -77,15 +77,14 @@
     (define-key map "\C-c;"	'comment-region)
     (define-key map "\C-j"	'newline-and-indent)
     (define-key map "\C-m"	'newline-and-indent)
-    (define-key map [menu-bar] (make-sparse-keymap))
-    (define-key map [menu-bar asm-mode] (cons "Asm" map))
-    (define-key map [comment-region]
+    (define-key map [menu-bar asm-mode] (cons "Asm" (make-sparse-keymap)))
+    (define-key map [menu-bar asm-mode comment-region]
       '(menu-item "Comment Region" comment-region
 		  :help "Comment or uncomment each line in the region"))
-    (define-key map [newline-and-indent]
+    (define-key map [menu-bar asm-mode newline-and-indent]
       '(menu-item "Insert Newline and Indent" newline-and-indent
 		  :help "Insert a newline, then indent according to major mode"))
-    (define-key map [asm-colon]
+    (define-key map [menu-bar asm-mode asm-colon]
       '(menu-item "Insert Colon" asm-colon
 		  :help "Insert a colon; if it follows a label, delete the label's indentation"))
     map)
@@ -142,16 +141,12 @@
   (set-syntax-table (make-syntax-table asm-mode-syntax-table))
   (modify-syntax-entry	asm-comment-char "< b")
 
-  (make-local-variable 'comment-start)
-  (setq comment-start (string asm-comment-char))
-  (make-local-variable 'comment-add)
-  (setq comment-add 1)
-  (make-local-variable 'comment-start-skip)
-  (setq comment-start-skip "\\(?:\\s<+\\|/[/*]+\\)[ \t]*")
-  (make-local-variable 'comment-end-skip)
-  (setq comment-end-skip "[ \t]*\\(\\s>\\|\\*+/\\)")
-  (make-local-variable 'comment-end)
-  (setq comment-end "")
+  (set (make-local-variable 'comment-start) (string asm-comment-char))
+  (set (make-local-variable 'comment-add) 1)
+  (set (make-local-variable 'comment-start-skip)
+       "\\(?:\\s<+\\|/[/*]+\\)[ \t]*")
+  (set (make-local-variable 'comment-end-skip) "[ \t]*\\(\\s>\\|\\*+/\\)")
+  (set (make-local-variable 'comment-end) "")
   (setq fill-prefix "\t"))
 
 (defun asm-indent-line ()
--- a/lisp/progmodes/autoconf.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/autoconf.el	Fri Dec 10 15:00:25 2010 -0500
@@ -78,14 +78,8 @@
 	  (match-string-no-properties 3)))))
 
 ;;;###autoload
-(defun autoconf-mode ()
+(define-derived-mode autoconf-mode prog-mode "Autoconf"
   "Major mode for editing Autoconf configure.in files."
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map autoconf-mode-map)
-  (setq major-mode 'autoconf-mode)
-  (setq mode-name "Autoconf")
-  (set-syntax-table autoconf-mode-syntax-table)
   (set (make-local-variable 'parens-require-spaces) nil) ; for M4 arg lists
   (set (make-local-variable 'defun-prompt-regexp)
        "^[ \t]*A[CM]_\\(\\sw\\|\\s_\\)+")
@@ -100,8 +94,7 @@
   (set (make-local-variable 'imenu-syntax-alist) '(("_" . "w")))
   (set (make-local-variable 'indent-line-function) #'indent-relative)
   (set (make-local-variable 'add-log-current-defun-function)
-	#'autoconf-current-defun-function)
-  (run-mode-hooks 'autoconf-mode-hook))
+	#'autoconf-current-defun-function))
 
 (provide 'autoconf-mode)
 (provide 'autoconf)
--- a/lisp/progmodes/cc-cmds.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/cc-cmds.el	Fri Dec 10 15:00:25 2010 -0500
@@ -266,8 +266,10 @@
 			  (symbol-value 'subword-mode))
 			 "w"
 		       "")))
+        ;; FIXME: Derived modes might want to use something else
+        ;; than a string for `mode-name'.
 	(bare-mode-name (if (string-match "\\(^[^/]*\\)/" mode-name)
-			    (substring mode-name (match-beginning 1) (match-end 1))
+			    (match-string 1 mode-name)
 			  mode-name)))
 ;;     (setq c-submode-indicators
 ;; 	  (if (> (length fmt) 1)
--- a/lisp/progmodes/cc-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/cc-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -487,15 +487,10 @@
 
   ;; these variables should always be buffer local; they do not affect
   ;; indentation style.
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (make-local-variable 'indent-line-function)
-  (make-local-variable 'indent-region-function)
-  (make-local-variable 'normal-auto-fill-function)
   (make-local-variable 'comment-start)
   (make-local-variable 'comment-end)
   (make-local-variable 'comment-start-skip)
-  (make-local-variable 'comment-multi-line)
-  (make-local-variable 'comment-line-break-function)
+  
   (make-local-variable 'paragraph-start)
   (make-local-variable 'paragraph-separate)
   (make-local-variable 'paragraph-ignore-fill-prefix)
@@ -503,18 +498,18 @@
   (make-local-variable 'adaptive-fill-regexp)
 
   ;; now set their values
-  (setq parse-sexp-ignore-comments t
-	indent-line-function 'c-indent-line
-	indent-region-function 'c-indent-region
-	normal-auto-fill-function 'c-do-auto-fill
-	comment-multi-line t
-	comment-line-break-function 'c-indent-new-comment-line)
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
+  (set (make-local-variable 'indent-line-function) 'c-indent-line)
+  (set (make-local-variable 'indent-region-function) 'c-indent-region)
+  (set (make-local-variable 'normal-auto-fill-function) 'c-do-auto-fill)
+  (set (make-local-variable 'comment-multi-line) t)
+  (set (make-local-variable 'comment-line-break-function)
+       'c-indent-new-comment-line)
 
   ;; Install `c-fill-paragraph' on `fill-paragraph-function' so that a
   ;; direct call to `fill-paragraph' behaves better.  This still
   ;; doesn't work with filladapt but it's better than nothing.
-  (make-local-variable 'fill-paragraph-function)
-  (setq fill-paragraph-function 'c-fill-paragraph)
+  (set (make-local-variable 'fill-paragraph-function) 'c-fill-paragraph)
 
   ;; Initialise the cache of brace pairs, and opening braces/brackets/parens.
   (c-state-cache-init)
@@ -532,22 +527,19 @@
 
     ;; Emacs.
     (when (boundp 'parse-sexp-lookup-properties)
-      (make-local-variable 'parse-sexp-lookup-properties)
-      (setq parse-sexp-lookup-properties t))
+      (set (make-local-variable 'parse-sexp-lookup-properties) t))
 
     ;; Same as above for XEmacs.
     (when (boundp 'lookup-syntax-properties)
-      (make-local-variable 'lookup-syntax-properties)
-      (setq lookup-syntax-properties t)))
+      (set (make-local-variable 'lookup-syntax-properties) t)))
 
   ;; Use this in Emacs 21+ to avoid meddling with the rear-nonsticky
   ;; property on each character.
   (when (boundp 'text-property-default-nonsticky)
-    (make-local-variable 'text-property-default-nonsticky)
     (mapc (lambda (tprop)
 	    (unless (assq tprop text-property-default-nonsticky)
-	      (setq text-property-default-nonsticky
-		    (cons `(,tprop . t) text-property-default-nonsticky))))
+	      (set (make-local-variable 'text-property-default-nonsticky)
+                   (cons `(,tprop . t) text-property-default-nonsticky))))
 	  '(syntax-table category c-type)))
 
   ;; In Emacs 21 and later it's possible to turn off the ad-hoc
@@ -587,8 +579,7 @@
   (setq c-offsets-alist (copy-alist c-offsets-alist))
 
   ;; setup the comment indent variable in a Emacs version portable way
-  (make-local-variable 'comment-indent-function)
-  (setq comment-indent-function 'c-comment-indent)
+  (set (make-local-variable 'comment-indent-function) 'c-comment-indent)
 
 ;;   ;; Put submode indicators onto minor-mode-alist, but only once.
 ;;   (or (assq 'c-submode-indicators minor-mode-alist)
@@ -660,16 +651,14 @@
 	  (funcall c-before-font-lock-function (point-min) (point-max)
 		   (- (point-max) (point-min))))))
 
-  (make-local-variable 'outline-regexp)
-  (make-local-variable 'outline-level)
-  (setq outline-regexp "[^#\n\^M]"
-	outline-level 'c-outline-level)
+  (set (make-local-variable 'outline-regexp) "[^#\n\^M]")
+  (set (make-local-variable 'outline-level) 'c-outline-level)
 
   (let ((rfn (assq mode c-require-final-newline)))
     (when rfn
-      (make-local-variable 'require-final-newline)
       (and (cdr rfn)
-	   (setq require-final-newline mode-require-final-newline)))))
+	   (set (make-local-variable 'require-final-newline)
+                mode-require-final-newline)))))
 
 (defun c-count-cfss (lv-alist)
   ;; LV-ALIST is an alist like `file-local-variables-alist'.  Count how many
@@ -1100,8 +1089,7 @@
 This does not load the font-lock package.  Use after
 `c-basic-common-init' and after cc-fonts has been loaded."
 
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults
+  (set (make-local-variable 'font-lock-defaults)
 	`(,(if (c-major-mode-is 'awk-mode)
 	       ;; awk-mode currently has only one font lock level.
 	       'awk-font-lock-keywords
@@ -1206,7 +1194,7 @@
   (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table c-mode-syntax-table)
-  (setq major-mode 'c-mode
+  (setq major-mode 'c-mode           ; FIXME: Use define-derived-mode.
 	mode-name "C"
 	local-abbrev-table c-mode-abbrev-table
 	abbrev-mode t)
@@ -1269,7 +1257,7 @@
   (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table c++-mode-syntax-table)
-  (setq major-mode 'c++-mode
+  (setq major-mode 'c++-mode         ; FIXME: Use define-derived-mode.
 	mode-name "C++"
 	local-abbrev-table c++-mode-abbrev-table
 	abbrev-mode t)
@@ -1330,7 +1318,7 @@
   (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table objc-mode-syntax-table)
-  (setq major-mode 'objc-mode
+  (setq major-mode 'objc-mode        ; FIXME: Use define-derived-mode.
 	mode-name "ObjC"
 	local-abbrev-table objc-mode-abbrev-table
 	abbrev-mode t)
@@ -1400,7 +1388,7 @@
   (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table java-mode-syntax-table)
-  (setq major-mode 'java-mode
+  (setq major-mode 'java-mode        ; FIXME: Use define-derived-mode.
  	mode-name "Java"
  	local-abbrev-table java-mode-abbrev-table
 	abbrev-mode t)
@@ -1459,7 +1447,7 @@
   (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table idl-mode-syntax-table)
-  (setq major-mode 'idl-mode
+  (setq major-mode 'idl-mode         ; FIXME: Use define-derived-mode.
 	mode-name "IDL"
 	local-abbrev-table idl-mode-abbrev-table)
   (use-local-map idl-mode-map)
@@ -1520,7 +1508,7 @@
   (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table pike-mode-syntax-table)
-  (setq major-mode 'pike-mode
+  (setq major-mode 'pike-mode        ; FIXME: Use define-derived-mode.
  	mode-name "Pike"
  	local-abbrev-table pike-mode-abbrev-table
 	abbrev-mode t)
@@ -1594,7 +1582,7 @@
   (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table awk-mode-syntax-table)
-  (setq major-mode 'awk-mode
+  (setq major-mode 'awk-mode         ; FIXME: Use define-derived-mode.
 	mode-name "AWK"
 	local-abbrev-table awk-mode-abbrev-table
 	abbrev-mode t)
@@ -1680,7 +1668,7 @@
 		     adaptive-fill-regexp)
 		   nil)))
 	(mapc (lambda (var) (unless (boundp var)
-			      (setq vars (delq var vars))))
+                         (setq vars (delq var vars))))
 	      '(signal-error-on-buffer-boundary
 		filladapt-mode
 		defun-prompt-regexp
--- a/lisp/progmodes/cc-styles.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/cc-styles.el	Fri Dec 10 15:00:25 2010 -0500
@@ -540,13 +540,12 @@
 
     (when (boundp 'adaptive-fill-first-line-regexp)
       ;; XEmacs adaptive fill mode doesn't have this.
-      (make-local-variable 'adaptive-fill-first-line-regexp)
-      (setq adaptive-fill-first-line-regexp
-	    (concat "\\`" comment-line-prefix
-		    ;; Maybe we should incorporate the old value here,
-		    ;; but then we have to do all sorts of kludges to
-		    ;; deal with the \` and \' it probably contains.
-		    "\\'"))))
+      (set (make-local-variable 'adaptive-fill-first-line-regexp)
+           (concat "\\`" comment-line-prefix
+                   ;; Maybe we should incorporate the old value here,
+                   ;; but then we have to do all sorts of kludges to
+                   ;; deal with the \` and \' it probably contains.
+                   "\\'"))))
 
   ;; Set up the values for use in strings.  These are the default
   ;; paragraph-start/separate values, enhanced to accept escaped EOLs as
--- a/lisp/progmodes/cfengine.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/cfengine.el	Fri Dec 10 15:00:25 2010 -0500
@@ -221,7 +221,6 @@
   ;; movement.
 
   (set (make-local-variable 'parens-require-spaces) nil)
-  (set (make-local-variable 'require-final-newline) mode-require-final-newline)
   (set (make-local-variable 'comment-start)  "# ")
   (set (make-local-variable 'comment-start-skip)
        "\\(\\(?:^\\|[^\\\\\n]\\)\\(?:\\\\\\\\\\)*\\)#+[ \t]*")
--- a/lisp/progmodes/compile.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/compile.el	Fri Dec 10 15:00:25 2010 -0500
@@ -1606,7 +1606,7 @@
   ;; Let windows scroll along with the output.
   (set (make-local-variable 'window-point-insertion-type) t)
   (set (make-local-variable 'tool-bar-map) compilation-mode-tool-bar-map)
-  (setq major-mode 'compilation-mode
+  (setq major-mode 'compilation-mode ; FIXME: Use define-derived-mode.
 	mode-name (or name-of-mode "Compilation"))
   (set (make-local-variable 'page-delimiter)
        compilation-page-delimiter)
--- a/lisp/progmodes/cpp.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/cpp.el	Fri Dec 10 15:00:25 2010 -0500
@@ -416,63 +416,59 @@
 
 ;;; Edit Buffer:
 
-(defvar cpp-edit-map nil)
-;; Keymap for `cpp-edit-mode'.
+(defvar cpp-edit-mode-map
+  (let ((map (make-keymap)))
+    (suppress-keymap map)
+    (define-key map [ down-mouse-2 ] 'cpp-push-button)
+    (define-key map [ mouse-2 ] 'ignore)
+    (define-key map " " 'scroll-up)
+    (define-key map "\C-?" 'scroll-down)
+    (define-key map [ delete ] 'scroll-down)
+    (define-key map "\C-c\C-c" 'cpp-edit-apply)
+    (define-key map "a" 'cpp-edit-apply)
+    (define-key map "A" 'cpp-edit-apply)
+    (define-key map "r" 'cpp-edit-reset)
+    (define-key map "R" 'cpp-edit-reset)
+    (define-key map "s" 'cpp-edit-save)
+    (define-key map "S" 'cpp-edit-save)
+    (define-key map "l" 'cpp-edit-load)
+    (define-key map "L" 'cpp-edit-load)
+    (define-key map "h" 'cpp-edit-home)
+    (define-key map "H" 'cpp-edit-home)
+    (define-key map "b" 'cpp-edit-background)
+    (define-key map "B" 'cpp-edit-background)
+    (define-key map "k" 'cpp-edit-known)
+    (define-key map "K" 'cpp-edit-known)
+    (define-key map "u" 'cpp-edit-unknown)
+    (define-key map "u" 'cpp-edit-unknown)
+    (define-key map "t" 'cpp-edit-true)
+    (define-key map "T" 'cpp-edit-true)
+    (define-key map "f" 'cpp-edit-false)
+    (define-key map "F" 'cpp-edit-false)
+    (define-key map "w" 'cpp-edit-write)
+    (define-key map "W" 'cpp-edit-write)
+    (define-key map "X" 'cpp-edit-toggle-known)
+    (define-key map "x" 'cpp-edit-toggle-known)
+    (define-key map "Y" 'cpp-edit-toggle-unknown)
+    (define-key map "y" 'cpp-edit-toggle-unknown)
+    (define-key map "q" 'bury-buffer)
+    (define-key map "Q" 'bury-buffer)
+    map)
+  "Keymap for `cpp-edit-mode'.")
 
-(if cpp-edit-map
-    ()
-  (setq cpp-edit-map (make-keymap))
-  (suppress-keymap cpp-edit-map)
-  (define-key cpp-edit-map [ down-mouse-2 ] 'cpp-push-button)
-  (define-key cpp-edit-map [ mouse-2 ] 'ignore)
-  (define-key cpp-edit-map " " 'scroll-up)
-  (define-key cpp-edit-map "\C-?" 'scroll-down)
-  (define-key cpp-edit-map [ delete ] 'scroll-down)
-  (define-key cpp-edit-map "\C-c\C-c" 'cpp-edit-apply)
-  (define-key cpp-edit-map "a" 'cpp-edit-apply)
-  (define-key cpp-edit-map "A" 'cpp-edit-apply)
-  (define-key cpp-edit-map "r" 'cpp-edit-reset)
-  (define-key cpp-edit-map "R" 'cpp-edit-reset)
-  (define-key cpp-edit-map "s" 'cpp-edit-save)
-  (define-key cpp-edit-map "S" 'cpp-edit-save)
-  (define-key cpp-edit-map "l" 'cpp-edit-load)
-  (define-key cpp-edit-map "L" 'cpp-edit-load)
-  (define-key cpp-edit-map "h" 'cpp-edit-home)
-  (define-key cpp-edit-map "H" 'cpp-edit-home)
-  (define-key cpp-edit-map "b" 'cpp-edit-background)
-  (define-key cpp-edit-map "B" 'cpp-edit-background)
-  (define-key cpp-edit-map "k" 'cpp-edit-known)
-  (define-key cpp-edit-map "K" 'cpp-edit-known)
-  (define-key cpp-edit-map "u" 'cpp-edit-unknown)
-  (define-key cpp-edit-map "u" 'cpp-edit-unknown)
-  (define-key cpp-edit-map "t" 'cpp-edit-true)
-  (define-key cpp-edit-map "T" 'cpp-edit-true)
-  (define-key cpp-edit-map "f" 'cpp-edit-false)
-  (define-key cpp-edit-map "F" 'cpp-edit-false)
-  (define-key cpp-edit-map "w" 'cpp-edit-write)
-  (define-key cpp-edit-map "W" 'cpp-edit-write)
-  (define-key cpp-edit-map "X" 'cpp-edit-toggle-known)
-  (define-key cpp-edit-map "x" 'cpp-edit-toggle-known)
-  (define-key cpp-edit-map "Y" 'cpp-edit-toggle-unknown)
-  (define-key cpp-edit-map "y" 'cpp-edit-toggle-unknown)
-  (define-key cpp-edit-map "q" 'bury-buffer)
-  (define-key cpp-edit-map "Q" 'bury-buffer))
+
 
 (defvar cpp-edit-symbols nil)
 ;; Symbols defined in the edit buffer.
 (make-variable-buffer-local 'cpp-edit-symbols)
 
-(defun cpp-edit-mode ()
+(define-derived-mode cpp-edit-mode fundamental-mode "CPP Edit"
   "Major mode for editing the criteria for highlighting cpp conditionals.
 Click on objects to change them.
 You can also use the keyboard accelerators indicated like this: [K]ey."
-  (kill-all-local-variables)
   (buffer-disable-undo)
   (auto-save-mode -1)
-  (setq buffer-read-only t)
-  (setq major-mode 'cpp-edit-mode)
-  (setq mode-name "CPP Edit")
-  (use-local-map cpp-edit-map))
+  (setq buffer-read-only t))
 
 (defun cpp-edit-apply ()
   "Apply edited display information to original buffer."
@@ -568,7 +564,7 @@
 	 (load-file cpp-config-file))
 	((file-readable-p (concat "~/" cpp-config-file))
 	 (load-file cpp-config-file)))
-  (if (eq major-mode 'cpp-edit-mode)
+  (if (derived-mode-p 'cpp-edit-mode)
       (cpp-edit-reset)))
 
 (defun cpp-edit-save ()
--- a/lisp/progmodes/dcl-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/dcl-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -296,72 +296,69 @@
 )
 
 
-(defvar dcl-mode-map ()
-  "Keymap used in DCL-mode buffers.")
-(if dcl-mode-map
-    ()
-  (setq dcl-mode-map (make-sparse-keymap))
-  (define-key dcl-mode-map "\e\n"	'dcl-split-line)
-  (define-key dcl-mode-map "\e\t" 	'tempo-complete-tag)
-  (define-key dcl-mode-map "\e^"	'dcl-delete-indentation)
-  (define-key dcl-mode-map "\em"	'dcl-back-to-indentation)
-  (define-key dcl-mode-map "\ee"        'dcl-forward-command)
-  (define-key dcl-mode-map "\ea"        'dcl-backward-command)
-  (define-key dcl-mode-map "\e\C-q" 	'dcl-indent-command)
-  (define-key dcl-mode-map "\t"         'dcl-tab)
-  (define-key dcl-mode-map ":"          'dcl-electric-character)
-  (define-key dcl-mode-map "F"          'dcl-electric-character)
-  (define-key dcl-mode-map "f"          'dcl-electric-character)
-  (define-key dcl-mode-map "E"          'dcl-electric-character)
-  (define-key dcl-mode-map "e"          'dcl-electric-character)
-  (define-key dcl-mode-map "\C-c\C-o" 	'dcl-set-option)
-  (define-key dcl-mode-map "\C-c\C-f" 	'tempo-forward-mark)
-  (define-key dcl-mode-map "\C-c\C-b" 	'tempo-backward-mark)
+(defvar dcl-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "\e\n"	'dcl-split-line)
+    (define-key map "\e\t" 	'tempo-complete-tag)
+    (define-key map "\e^"	'dcl-delete-indentation)
+    (define-key map "\em"	'dcl-back-to-indentation)
+    (define-key map "\ee"        'dcl-forward-command)
+    (define-key map "\ea"        'dcl-backward-command)
+    (define-key map "\e\C-q" 	'dcl-indent-command)
+    (define-key map "\t"         'dcl-tab)
+    (define-key map ":"          'dcl-electric-character)
+    (define-key map "F"          'dcl-electric-character)
+    (define-key map "f"          'dcl-electric-character)
+    (define-key map "E"          'dcl-electric-character)
+    (define-key map "e"          'dcl-electric-character)
+    (define-key map "\C-c\C-o" 	'dcl-set-option)
+    (define-key map "\C-c\C-f" 	'tempo-forward-mark)
+    (define-key map "\C-c\C-b" 	'tempo-backward-mark)
 
-  (define-key dcl-mode-map [menu-bar] 	(make-sparse-keymap))
-  (define-key dcl-mode-map [menu-bar dcl]
-    (cons "DCL" (make-sparse-keymap "DCL")))
+    (define-key map [menu-bar] 	(make-sparse-keymap))
+    (define-key map [menu-bar dcl]
+      (cons "DCL" (make-sparse-keymap "DCL")))
 
-  ;; Define these in bottom-up order
-  (define-key dcl-mode-map [menu-bar dcl tempo-backward-mark]
-    '("Previous template mark" . tempo-backward-mark))
-  (define-key dcl-mode-map [menu-bar dcl tempo-forward-mark]
-    '("Next template mark" . tempo-forward-mark))
-  (define-key dcl-mode-map [menu-bar dcl tempo-complete-tag]
-    '("Complete template tag" . tempo-complete-tag))
-  (define-key dcl-mode-map [menu-bar dcl dcl-separator-tempo]
-    '("--"))
-  (define-key dcl-mode-map [menu-bar dcl dcl-save-all-options]
-    '("Save all options" . dcl-save-all-options))
-  (define-key dcl-mode-map [menu-bar dcl dcl-save-nondefault-options]
-    '("Save changed options" . dcl-save-nondefault-options))
-  (define-key dcl-mode-map [menu-bar dcl dcl-set-option]
-    '("Set option" . dcl-set-option))
-  (define-key dcl-mode-map [menu-bar dcl dcl-separator-option]
-    '("--"))
-  (define-key dcl-mode-map [menu-bar dcl dcl-delete-indentation]
-    '("Delete indentation" . dcl-delete-indentation))
-  (define-key dcl-mode-map [menu-bar dcl dcl-split-line]
-    '("Split line" . dcl-split-line))
-  (define-key dcl-mode-map [menu-bar dcl dcl-indent-command]
-    '("Indent command" . dcl-indent-command))
-  (define-key dcl-mode-map [menu-bar dcl dcl-tab]
-    '("Indent line/insert tab" . dcl-tab))
-  (define-key dcl-mode-map [menu-bar dcl dcl-back-to-indentation]
-    '("Back to indentation" . dcl-back-to-indentation))
-  (define-key dcl-mode-map [menu-bar dcl dcl-forward-command]
-    '("End of statement" . dcl-forward-command))
-  (define-key dcl-mode-map [menu-bar dcl dcl-backward-command]
-    '("Beginning of statement" . dcl-backward-command))
-  ;; imenu is only supported for versions with imenu-generic-expression
-  (if (boundp 'imenu-generic-expression)
-      (progn
-	(define-key dcl-mode-map [menu-bar dcl dcl-separator-movement]
-	  '("--"))
-	(define-key dcl-mode-map [menu-bar dcl imenu]
-	  '("Buffer index menu" . imenu))))
-  )
-
+    ;; Define these in bottom-up order
+    (define-key map [menu-bar dcl tempo-backward-mark]
+      '("Previous template mark" . tempo-backward-mark))
+    (define-key map [menu-bar dcl tempo-forward-mark]
+      '("Next template mark" . tempo-forward-mark))
+    (define-key map [menu-bar dcl tempo-complete-tag]
+      '("Complete template tag" . tempo-complete-tag))
+    (define-key map [menu-bar dcl dcl-separator-tempo]
+      '("--"))
+    (define-key map [menu-bar dcl dcl-save-all-options]
+      '("Save all options" . dcl-save-all-options))
+    (define-key map [menu-bar dcl dcl-save-nondefault-options]
+      '("Save changed options" . dcl-save-nondefault-options))
+    (define-key map [menu-bar dcl dcl-set-option]
+      '("Set option" . dcl-set-option))
+    (define-key map [menu-bar dcl dcl-separator-option]
+      '("--"))
+    (define-key map [menu-bar dcl dcl-delete-indentation]
+      '("Delete indentation" . dcl-delete-indentation))
+    (define-key map [menu-bar dcl dcl-split-line]
+      '("Split line" . dcl-split-line))
+    (define-key map [menu-bar dcl dcl-indent-command]
+      '("Indent command" . dcl-indent-command))
+    (define-key map [menu-bar dcl dcl-tab]
+      '("Indent line/insert tab" . dcl-tab))
+    (define-key map [menu-bar dcl dcl-back-to-indentation]
+      '("Back to indentation" . dcl-back-to-indentation))
+    (define-key map [menu-bar dcl dcl-forward-command]
+      '("End of statement" . dcl-forward-command))
+    (define-key map [menu-bar dcl dcl-backward-command]
+      '("Beginning of statement" . dcl-backward-command))
+    ;; imenu is only supported for versions with imenu-generic-expression
+    (if (boundp 'imenu-generic-expression)
+        (progn
+          (define-key map [menu-bar dcl dcl-separator-movement]
+            '("--"))
+          (define-key map [menu-bar dcl imenu]
+            '("Buffer index menu" . imenu))))
+    map)
+  "Keymap used in DCL-mode buffers.")
 
 (defcustom dcl-ws-r
   "\\([ \t]*-[ \t]*\\(!.*\\)*\n\\)*[ \t]*"
@@ -475,7 +472,7 @@
 
 
 ;;;###autoload
-(defun dcl-mode ()
+(define-derived-mode dcl-mode prog-mode "DCL"
   "Major mode for editing DCL-files.
 
 This mode indents command lines in blocks.  (A block is commands between
@@ -593,29 +590,17 @@
 
 There is some minimal font-lock support (see vars
 `dcl-font-lock-defaults' and `dcl-font-lock-keywords')."
-  (interactive)
-  (kill-all-local-variables)
-  (set-syntax-table dcl-mode-syntax-table)
-
-  (make-local-variable 'indent-line-function)
-  (setq indent-line-function 'dcl-indent-line)
-
-  (make-local-variable 'comment-start)
-  (setq comment-start "!")
-
-  (make-local-variable 'comment-end)
-  (setq comment-end "")
-
-  (make-local-variable 'comment-multi-line)
-  (setq comment-multi-line nil)
+  (set (make-local-variable 'indent-line-function) 'dcl-indent-line)
+  (set (make-local-variable 'comment-start) "!")
+  (set (make-local-variable 'comment-end) "")
+  (set (make-local-variable 'comment-multi-line) nil)
 
   ;; This used to be "^\\$[ \t]*![ \t]*" which looks more correct.
   ;; The drawback was that you couldn't make empty comment lines by pressing
   ;; C-M-j repeatedly - only the first line became a comment line.
   ;; This version has the drawback that the "$" can be anywhere in the line,
   ;; and something inappropriate might be interpreted as a comment.
-  (make-local-variable 'comment-start-skip)
-  (setq comment-start-skip "\\$[ \t]*![ \t]*")
+  (set (make-local-variable 'comment-start-skip) "\\$[ \t]*![ \t]*")
 
   (if (boundp 'imenu-generic-expression)
       (progn (setq imenu-generic-expression dcl-imenu-generic-expression)
@@ -636,14 +621,9 @@
   (make-local-variable 'dcl-electric-reindent-regexps)
 
   ;; font lock
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults dcl-font-lock-defaults)
+  (set (make-local-variable 'font-lock-defaults) dcl-font-lock-defaults)
 
-  (setq major-mode 'dcl-mode)
-  (setq mode-name "DCL")
-  (use-local-map dcl-mode-map)
-  (tempo-use-tag-list 'dcl-tempo-tags)
-  (run-mode-hooks 'dcl-mode-hook))
+  (tempo-use-tag-list 'dcl-tempo-tags))
 
 
 ;;; *** Movement commands ***************************************************
--- a/lisp/progmodes/delphi.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/delphi.el	Fri Dec 10 15:00:25 2010 -0500
@@ -1779,7 +1779,7 @@
     (if (null file)
         (error "unit not found: %s" unit-file)
       (find-file file)
-      (if (not (eq major-mode 'delphi-mode))
+      (if (not (derived-mode-p 'delphi-mode))
           (delphi-mode)))
     file))
 
@@ -2015,7 +2015,7 @@
   (interactive)
   (kill-all-local-variables)
   (use-local-map delphi-mode-map)
-  (setq major-mode 'delphi-mode)
+  (setq major-mode 'delphi-mode)        ;FIXME: Use define-derived-mode.
   (setq mode-name "Delphi")
 
   (setq local-abbrev-table delphi-mode-abbrev-table)
@@ -2025,8 +2025,7 @@
   (mapc #'(lambda (var)
 	    (let ((var-symb (car var))
 		  (var-val (cadr var)))
-	      (make-local-variable var-symb)
-	      (set var-symb var-val)))
+              (set (make-local-variable var-symb) var-val)))
 	(list '(indent-line-function delphi-indent-line)
 	      '(comment-indent-function delphi-indent-line)
 	      '(case-fold-search t)
--- a/lisp/progmodes/ebrowse.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/ebrowse.el	Fri Dec 10 15:00:25 2010 -0500
@@ -1116,7 +1116,7 @@
 ;;; Tree-mode - mode for tree buffers
 
 ;;;###autoload
-(defun ebrowse-tree-mode ()
+(define-derived-mode ebrowse-tree-mode special-mode "Ebrowse-Tree"
   "Major mode for Ebrowse class tree buffers.
 Each line corresponds to a class in a class tree.
 Letters do not insert themselves, they are commands.
@@ -1125,12 +1125,10 @@
 
 Tree mode key bindings:
 \\{ebrowse-tree-mode-map}"
-  (interactive)
   (let* ((ident (propertized-buffer-identification "C++ Tree"))
-	 header tree buffer-read-only)
-
-    (kill-all-local-variables)
-    (use-local-map ebrowse-tree-mode-map)
+	 (inhibit-read-only t)
+         header tree)
+
     (buffer-disable-undo)
 
     (unless (zerop (buffer-size))
@@ -1141,38 +1139,27 @@
       (erase-buffer)
       (message nil))
 
-    (mapc 'make-local-variable
-	  '(ebrowse--tags-file-name
-	    ebrowse--indentation
-	    ebrowse--tree
-	    ebrowse--header
-	    ebrowse--show-file-names-flag
-	    ebrowse--frozen-flag
-	    ebrowse--tree-obarray
-	    revert-buffer-function))
-
-    (setf ebrowse--show-file-names-flag nil
-	  ebrowse--tree-obarray (make-vector 127 0)
-	  ebrowse--frozen-flag nil
-	  major-mode 'ebrowse-tree-mode
-	  mode-name "Ebrowse-Tree"
-	  mode-line-buffer-identification ident
-	  buffer-read-only t
-	  selective-display t
-	  selective-display-ellipses t
-	  revert-buffer-function 'ebrowse-revert-tree-buffer-from-file
-	  ebrowse--header header
-	  ebrowse--tree tree
-	  ebrowse--tags-file-name (buffer-file-name)
-	  ebrowse--tree-obarray (and tree (ebrowse-build-tree-obarray tree))
-	  ebrowse--frozen-flag nil)
-
-    (add-hook 'local-write-file-hooks 'ebrowse-write-file-hook-fn)
+    (set (make-local-variable 'ebrowse--show-file-names-flag) nil)
+    (set (make-local-variable 'ebrowse--tree-obarray) (make-vector 127 0))
+    (set (make-local-variable 'ebrowse--frozen-flag) nil)
+    (setq mode-line-buffer-identification ident)
+    (setq buffer-read-only t)
+    (setq selective-display t)
+    (setq selective-display-ellipses t)
+    (set (make-local-variable 'revert-buffer-function)
+         #'ebrowse-revert-tree-buffer-from-file)
+    (set (make-local-variable 'ebrowse--header) header)
+    (set (make-local-variable 'ebrowse--tree) tree)
+    (set (make-local-variable 'ebrowse--tags-file-name) buffer-file-name)
+    (set (make-local-variable 'ebrowse--tree-obarray)
+         (and tree (ebrowse-build-tree-obarray tree)))
+    (set (make-local-variable 'ebrowse--frozen-flag) nil)
+
+    (add-hook 'local-write-file-hooks 'ebrowse-write-file-hook-fn nil t)
     (modify-syntax-entry ?_ (char-to-string (char-syntax ?a)))
     (when tree
       (ebrowse-redraw-tree)
-      (set-buffer-modified-p nil))
-    (run-mode-hooks 'ebrowse-tree-mode-hook)))
+      (set-buffer-modified-p nil))))
 
 
 
@@ -1340,6 +1327,7 @@
 
 (defun ebrowse-member-buffer-p (buffer)
   "Value is non-nil if BUFFER is a member buffer."
+  ;; FIXME: Why not (buffer-local-value 'major-mode buffer)?
   (eq (cdr (assoc 'major-mode (buffer-local-variables buffer)))
       'ebrowse-member-mode))
 
@@ -1459,12 +1447,13 @@
 (defun ebrowse-set-tree-indentation ()
   "Set the indentation width of the tree display."
   (interactive)
-  (let ((width (string-to-number (read-from-minibuffer
-                                  (concat "Indentation ("
+  (let ((width (string-to-number (read-string
+                                  (concat "Indentation (default "
                                           (int-to-string ebrowse--indentation)
-                                          "): ")))))
+                                          "): ")
+                                  nil nil ebrowse--indentation))))
     (when (plusp width)
-      (setf ebrowse--indentation width)
+      (set (make-local-variable 'ebrowse--indentation) width)
       (ebrowse-redraw-tree))))
 
 
@@ -1632,13 +1621,12 @@
 	(had-a-buf (get-file-buffer file))
 	(buf-to-view (find-file-noselect file)))
     (switch-to-buffer-other-frame buf-to-view)
-    (make-local-variable 'ebrowse--frame-configuration)
-    (setq ebrowse--frame-configuration old-frame-configuration)
-    (make-local-variable 'ebrowse--view-exit-action)
-    (setq ebrowse--view-exit-action
-	  (and (not had-a-buf)
-	       (not (buffer-modified-p buf-to-view))
-	       'kill-buffer))
+    (set (make-local-variable 'ebrowse--frame-configuration)
+         old-frame-configuration)
+    (set (make-local-variable 'ebrowse--view-exit-action)
+         (and (not had-a-buf)
+              (not (buffer-modified-p buf-to-view))
+              'kill-buffer))
     (view-mode-enter (cons (selected-window) (cons (selected-window) t))
 		     'ebrowse-view-exit-fn)))
 
@@ -2006,21 +1994,16 @@
 (put 'ebrowse-electric-list-undefined 'suppress-keymap t)
 
 
-(defun ebrowse-electric-list-mode ()
+(define-derived-mode ebrowse-electric-list-mode
+  fundamental-mode "Electric Position Menu"
   "Mode for electric tree list mode."
-  (kill-all-local-variables)
-  (use-local-map ebrowse-electric-list-mode-map)
-  (setq mode-name "Electric Position Menu"
-	mode-line-buffer-identification "Electric Tree Menu")
+  (setq mode-line-buffer-identification "Electric Tree Menu")
   (when (memq 'mode-name mode-line-format)
     (setq mode-line-format (copy-sequence mode-line-format))
     (setcar (memq 'mode-name mode-line-format) "Tree Buffers"))
-  (make-local-variable 'Helper-return-blurb)
-  (setq Helper-return-blurb "return to buffer editing"
-	truncate-lines t
-	buffer-read-only t
-	major-mode 'ebrowse-electric-list-mode)
-  (run-mode-hooks 'ebrowse-electric-list-mode-hook))
+  (set (make-local-variable 'Helper-return-blurb) "return to buffer editing")
+  (setq truncate-lines t
+	buffer-read-only t))
 
 
 (defun ebrowse-list-tree-buffers ()
@@ -2226,13 +2209,8 @@
 ;;; Member mode
 
 ;;;###autoload
-(defun ebrowse-member-mode ()
-  "Major mode for Ebrowse member buffers.
-
-\\{ebrowse-member-mode-map}"
-  (kill-all-local-variables)
-  (use-local-map ebrowse-member-mode-map)
-  (setq major-mode 'ebrowse-member-mode)
+(define-derived-mode ebrowse-member-mode special-mode "Ebrowse-Members"
+  "Major mode for Ebrowse member buffers."
   (mapc 'make-local-variable
 	'(ebrowse--decl-column	        ;display column
 	  ebrowse--n-columns		;number of short columns
@@ -2255,8 +2233,7 @@
 	  ebrowse--const-display-flag
 	  ebrowse--pure-display-flag
 	  ebrowse--frozen-flag))	;buffer not automagically reused
-  (setq mode-name "Ebrowse-Members"
-	mode-line-buffer-identification
+  (setq mode-line-buffer-identification
 	(propertized-buffer-identification "C++ Members")
 	buffer-read-only t
 	ebrowse--long-display-flag nil
@@ -2270,8 +2247,7 @@
 	ebrowse--inline-display-flag nil
 	ebrowse--const-display-flag nil
 	ebrowse--pure-display-flag nil)
-  (modify-syntax-entry ?_ (char-to-string (char-syntax ?a)))
-  (run-mode-hooks 'ebrowse-member-mode-hook))
+  (modify-syntax-entry ?_ (char-to-string (char-syntax ?a))))
 
 
 
@@ -3967,22 +3943,17 @@
 (put 'ebrowse-electric-position-undefined 'suppress-keymap t)
 
 
-(defun ebrowse-electric-position-mode ()
+(define-derived-mode ebrowse-electric-position-mode
+  fundamental-mode "Electric Position Menu"
   "Mode for electric position buffers.
 Runs the hook `ebrowse-electric-position-mode-hook'."
-  (kill-all-local-variables)
-  (use-local-map ebrowse-electric-position-mode-map)
-  (setq mode-name "Electric Position Menu"
-	mode-line-buffer-identification "Electric Position Menu")
+  (setq mode-line-buffer-identification "Electric Position Menu")
   (when (memq 'mode-name mode-line-format)
     (setq mode-line-format (copy-sequence mode-line-format))
     (setcar (memq 'mode-name mode-line-format) "Positions"))
-  (make-local-variable 'Helper-return-blurb)
-  (setq Helper-return-blurb "return to buffer editing"
-	truncate-lines t
-	buffer-read-only t
-	major-mode 'ebrowse-electric-position-mode)
-  (run-mode-hooks 'ebrowse-electric-position-mode-hook))
+  (set (make-local-variable 'Helper-return-blurb) "return to buffer editing")
+  (setq truncate-lines t
+	buffer-read-only t))
 
 
 (defun ebrowse-draw-position-buffer ()
--- a/lisp/progmodes/etags.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/etags.el	Fri Dec 10 15:00:25 2010 -0500
@@ -280,7 +280,7 @@
 (defun tags-table-mode ()
   "Major mode for tags table file buffers."
   (interactive)
-  (setq major-mode 'tags-table-mode
+  (setq major-mode 'tags-table-mode     ;FIXME: Use define-derived-mode.
         mode-name "Tags Table"
         buffer-undo-list t)
   (initialize-new-tags-table))
@@ -2030,10 +2030,8 @@
     (define-key map "q" 'select-tags-table-quit)
     map))
 
-(define-derived-mode select-tags-table-mode fundamental-mode "Select Tags Table"
-  "Major mode for choosing a current tags table among those already loaded.
-
-\\{select-tags-table-mode-map}"
+(define-derived-mode select-tags-table-mode special-mode "Select Tags Table"
+  "Major mode for choosing a current tags table among those already loaded."
   (setq buffer-read-only t))
 
 (defun select-tags-table-select (button)
--- a/lisp/progmodes/f90.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/f90.el	Fri Dec 10 15:00:25 2010 -0500
@@ -1067,11 +1067,9 @@
 Turning on F90 mode calls the value of the variable `f90-mode-hook'
 with no args, if that value is non-nil."
   :group 'f90
-  :syntax-table f90-mode-syntax-table
   :abbrev-table f90-mode-abbrev-table
   (set (make-local-variable 'indent-line-function) 'f90-indent-line)
   (set (make-local-variable 'indent-region-function) 'f90-indent-region)
-  (set (make-local-variable 'require-final-newline) mode-require-final-newline)
   (set (make-local-variable 'comment-start) "!")
   (set (make-local-variable 'comment-start-skip) "!+ *")
   (set (make-local-variable 'comment-indent-function) 'f90-comment-indent)
@@ -2207,7 +2205,7 @@
 With optional argument ALL, change the default for all present
 and future F90 buffers.  F90 mode normally treats backslash as an
 escape character."
-  (or (eq major-mode 'f90-mode)
+  (or (derived-mode-p 'f90-mode)
       (error "This function should only be used in F90 buffers"))
   (when (equal (char-syntax ?\\ ) ?\\ )
     (or all (set-syntax-table (copy-syntax-table (syntax-table))))
--- a/lisp/progmodes/gdb-mi.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/gdb-mi.el	Fri Dec 10 15:00:25 2010 -0500
@@ -1016,7 +1016,7 @@
 					'gud-gdb-complete-command)
 		     (if (and transient-mark-mode mark-active)
 			 (buffer-substring (region-beginning) (region-end))
-		       (concat (if (eq major-mode 'gdb-registers-mode) "$")
+		       (concat (if (derived-mode-p 'gdb-registers-mode) "$")
 			       (tooltip-identifier-from-point (point)))))))
 	      (set-text-properties 0 (length expr) nil expr)
 	      (gdb-input
@@ -1483,14 +1483,9 @@
 
 ;; We want to use comint because it has various nifty and familiar features.
 (define-derived-mode gdb-inferior-io-mode comint-mode "Inferior I/O"
-  "Major mode for gdb inferior-io.
-
-The following commands are available:
-\\{gdb-inferior-io-mode-map}"
-
+  "Major mode for gdb inferior-io."
   :syntax-table nil :abbrev-table nil
-
-(make-comint-in-buffer "gdb-inferior" (current-buffer)  nil))
+  (make-comint-in-buffer "gdb-inferior" (current-buffer) nil))
 
 (defun gdb-inferior-filter (proc string)
   (unless (string-equal string "")
@@ -2443,7 +2438,7 @@
   (mouse-minibuffer-check event)
   (let ((posn (event-end event)))
     (with-selected-window (posn-window posn)
-      (if (or (buffer-file-name) (eq major-mode 'gdb-disassembly-mode))
+      (if (or (buffer-file-name) (derived-mode-p 'gdb-disassembly-mode))
 	  (if (numberp (posn-point posn))
 	      (save-excursion
 		(goto-char (posn-point posn))
@@ -2627,15 +2622,12 @@
 			  nil nil mode-line)))
 
 (define-derived-mode gdb-threads-mode gdb-parent-mode "Threads"
-  "Major mode for GDB threads.
-
-\\{gdb-threads-mode-map}"
+  "Major mode for GDB threads."
   (setq gdb-thread-position (make-marker))
   (add-to-list 'overlay-arrow-variable-list 'gdb-thread-position)
   (setq header-line-format gdb-threads-header)
   (set (make-local-variable 'font-lock-defaults)
        '(gdb-threads-font-lock-keywords))
-  (run-mode-hooks 'gdb-threads-mode-hook)
   'gdb-invalidate-threads)
 
 (defun gdb-thread-list-handler-custom ()
@@ -3161,13 +3153,10 @@
   "Header line used in `gdb-memory-mode'.")
 
 (define-derived-mode gdb-memory-mode gdb-parent-mode "Memory"
-  "Major mode for examining memory.
-
-\\{gdb-memory-mode-map}"
+  "Major mode for examining memory."
   (setq header-line-format gdb-memory-header)
   (set (make-local-variable 'font-lock-defaults)
        '(gdb-memory-font-lock-keywords))
-  (run-mode-hooks 'gdb-memory-mode-hook)
   'gdb-invalidate-memory)
 
 (defun gdb-memory-buffer-name ()
@@ -3256,16 +3245,13 @@
      map))
 
 (define-derived-mode gdb-disassembly-mode gdb-parent-mode "Disassembly"
-  "Major mode for GDB disassembly information.
-
-\\{gdb-disassembly-mode-map}"
+  "Major mode for GDB disassembly information."
   ;; TODO Rename overlay variable for disassembly mode
   (add-to-list 'overlay-arrow-variable-list 'gdb-disassembly-position)
   (setq fringes-outside-margins t)
   (set (make-local-variable 'gdb-disassembly-position) (make-marker))
   (set (make-local-variable 'font-lock-defaults)
        '(gdb-disassembly-font-lock-keywords))
-  (run-mode-hooks 'gdb-disassembly-mode-hook)
   'gdb-invalidate-disassembly)
 
 (defun gdb-disassembly-handler-custom ()
@@ -3323,11 +3309,8 @@
 
 ;;; Breakpoints view
 (define-derived-mode gdb-breakpoints-mode gdb-parent-mode "Breakpoints"
-  "Major mode for gdb breakpoints.
-
-\\{gdb-breakpoints-mode-map}"
+  "Major mode for gdb breakpoints."
   (setq header-line-format gdb-breakpoints-header)
-  (run-mode-hooks 'gdb-breakpoints-mode-hook)
   'gdb-invalidate-breakpoints)
 
 (defun gdb-toggle-breakpoint ()
@@ -3466,15 +3449,12 @@
   "Font lock keywords used in `gdb-frames-mode'.")
 
 (define-derived-mode gdb-frames-mode gdb-parent-mode "Frames"
-  "Major mode for gdb call stack.
-
-\\{gdb-frames-mode-map}"
+  "Major mode for gdb call stack."
   (setq gdb-stack-position (make-marker))
   (add-to-list 'overlay-arrow-variable-list 'gdb-stack-position)
   (setq truncate-lines t)  ;; Make it easier to see overlay arrow.
   (set (make-local-variable 'font-lock-defaults)
        '(gdb-frames-font-lock-keywords))
-  (run-mode-hooks 'gdb-frames-mode-hook)
   'gdb-invalidate-frames)
 
 (defun gdb-select-frame (&optional event)
@@ -3588,11 +3568,8 @@
      map))
 
 (define-derived-mode gdb-locals-mode gdb-parent-mode "Locals"
-  "Major mode for gdb locals.
-
-\\{gdb-locals-mode-map}"
+  "Major mode for gdb locals."
   (setq header-line-format gdb-locals-header)
-  (run-mode-hooks 'gdb-locals-mode-hook)
   'gdb-invalidate-locals)
 
 (defun gdb-locals-buffer-name ()
@@ -3687,11 +3664,8 @@
 			  nil nil mode-line)))
 
 (define-derived-mode gdb-registers-mode gdb-parent-mode "Registers"
-  "Major mode for gdb registers.
-
-\\{gdb-registers-mode-map}"
+  "Major mode for gdb registers."
   (setq header-line-format gdb-registers-header)
-  (run-mode-hooks 'gdb-registers-mode-hook)
   'gdb-invalidate-registers)
 
 (defun gdb-registers-buffer-name ()
--- a/lisp/progmodes/gud.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/gud.el	Fri Dec 10 15:00:25 2010 -0500
@@ -2533,7 +2533,7 @@
   (gud-set-buffer))
 
 (defun gud-set-buffer ()
-  (when (eq major-mode 'gud-mode)
+  (when (derived-mode-p 'gud-mode)
     (setq gud-comint-buffer (current-buffer))))
 
 (defvar gud-filter-defer-flag nil
@@ -3344,10 +3344,8 @@
 ACTIVATEP non-nil means activate mouse motion events."
   (if activatep
       (progn
-	(make-local-variable 'gud-tooltip-mouse-motions-active)
-	(setq gud-tooltip-mouse-motions-active t)
-	(make-local-variable 'track-mouse)
-	(setq track-mouse t))
+        (set (make-local-variable 'gud-tooltip-mouse-motions-active) t)
+        (set (make-local-variable 'track-mouse) t))
     (when gud-tooltip-mouse-motions-active
       (kill-local-variable 'gud-tooltip-mouse-motions-active)
       (kill-local-variable 'track-mouse))))
--- a/lisp/progmodes/icon.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/icon.el	Fri Dec 10 15:00:25 2010 -0500
@@ -131,7 +131,7 @@
 
 
 ;;;###autoload
-(defun icon-mode ()
+(define-derived-mode icon-mode prog-mode "Icon"
   "Major mode for editing Icon code.
 Expression and list commands understand all Icon brackets.
 Tab indents for Icon code.
@@ -163,49 +163,33 @@
 
 Turning on Icon mode calls the value of the variable `icon-mode-hook'
 with no args, if that value is non-nil."
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map icon-mode-map)
-  (setq major-mode 'icon-mode)
-  (setq mode-name "Icon")
-  (setq local-abbrev-table icon-mode-abbrev-table)
-  (set-syntax-table icon-mode-syntax-table)
-  (make-local-variable 'paragraph-start)
-  (setq paragraph-start (concat "$\\|" page-delimiter))
-  (make-local-variable 'paragraph-separate)
-  (setq paragraph-separate paragraph-start)
-  (make-local-variable 'indent-line-function)
-  (setq indent-line-function 'icon-indent-line)
-  (make-local-variable 'require-final-newline)
-  (setq require-final-newline mode-require-final-newline)
-  (make-local-variable 'comment-start)
-  (setq comment-start "# ")
-  (make-local-variable 'comment-end)
-  (setq comment-end "")
-  (make-local-variable 'comment-start-skip)
-  (setq comment-start-skip "# *")
-  (make-local-variable 'comment-indent-function)
-  (setq comment-indent-function 'icon-comment-indent)
+  :abbrev-table icon-mode-abbrev-table
+  (set (make-local-variable 'paragraph-start) (concat "$\\|" page-delimiter))
+  (set (make-local-variable 'paragraph-separate) paragraph-start)
+  (set (make-local-variable 'indent-line-function) #'icon-indent-line)
+  (set (make-local-variable 'comment-start) "# ")
+  (set (make-local-variable 'comment-end) "")
+  (set (make-local-variable 'comment-start-skip) "# *")
+  (set (make-local-variable 'comment-indent-function) 'icon-comment-indent)
   (set (make-local-variable 'indent-line-function) 'icon-indent-line)
   ;; font-lock support
-  (setq font-lock-defaults
-	'((icon-font-lock-keywords
-	   icon-font-lock-keywords-1 icon-font-lock-keywords-2)
-	  nil nil ((?_ . "w")) beginning-of-defun
-	  ;; Obsoleted by Emacs 19.35 parse-partial-sexp's COMMENTSTOP.
-	  ;(font-lock-comment-start-regexp . "#")
-	  (font-lock-mark-block-function . mark-defun)))
+  (set (make-local-variable 'font-lock-defaults)
+       '((icon-font-lock-keywords
+          icon-font-lock-keywords-1 icon-font-lock-keywords-2)
+         nil nil ((?_ . "w")) beginning-of-defun
+         ;; Obsoleted by Emacs 19.35 parse-partial-sexp's COMMENTSTOP.
+         ;;(font-lock-comment-start-regexp . "#")
+         (font-lock-mark-block-function . mark-defun)))
   ;; imenu support
-  (make-local-variable 'imenu-generic-expression)
-  (setq imenu-generic-expression icon-imenu-generic-expression)
+  (set (make-local-variable 'imenu-generic-expression)
+       icon-imenu-generic-expression)
   ;; hideshow support
   ;; we start from the assertion that `hs-special-modes-alist' is autoloaded.
   (unless (assq 'icon-mode hs-special-modes-alist)
     (setq hs-special-modes-alist
 	  (cons '(icon-mode  "\\<procedure\\>" "\\<end\\>" nil
 			     icon-forward-sexp-function)
-		hs-special-modes-alist)))
-  (run-mode-hooks 'icon-mode-hook))
+		hs-special-modes-alist))))
 
 ;; This is used by indent-for-comment to decide how much to
 ;; indent a comment in Icon code based on its context.
--- a/lisp/progmodes/idlw-complete-structtag.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/idlw-complete-structtag.el	Fri Dec 10 15:00:25 2010 -0500
@@ -167,7 +167,7 @@
 (defun idlwave-prepare-structure-tag-completion (var)
   "Find and parse the tag list for structure tag completion."
   ;; This works differently in source buffers and in the shell
-  (if (eq major-mode 'idlwave-shell-mode)
+  (if (derived-mode-p 'idlwave-shell-mode)
       ;; OK, we are in the shell, do it dynamically
       (progn
         (message "preparing shell tags") 
--- a/lisp/progmodes/idlw-help.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/idlw-help.el	Fri Dec 10 15:00:25 2010 -0500
@@ -288,7 +288,7 @@
 (declare-function idlwave-what-module-find-class "idlwave")
 (declare-function idlwave-where "idlwave")
 
-(defun idlwave-help-mode ()
+(define-derived-mode idlwave-help-mode special-mode "IDLWAVE Help"
   "Major mode for displaying IDL Help.
 
 This is a VIEW mode for the ASCII version of IDL Help files,
@@ -308,11 +308,7 @@
 
 Here are all keybindings.
 \\{idlwave-help-mode-map}"
-  (kill-all-local-variables)
   (buffer-disable-undo)
-  (setq major-mode 'idlwave-help-mode
-	mode-name "IDLWAVE Help")
-  (use-local-map idlwave-help-mode-map)
   (easy-menu-add idlwave-help-menu idlwave-help-mode-map)
   (setq truncate-lines t)
   (setq case-fold-search t)
@@ -325,8 +321,7 @@
   (setq buffer-read-only t)
   (set (make-local-variable 'idlwave-help-def-pos) nil)
   (set (make-local-variable 'idlwave-help-args) nil)
-  (set (make-local-variable 'idlwave-help-in-header) nil)
-  (run-hooks 'idlwave-help-mode-hook))
+  (set (make-local-variable 'idlwave-help-in-header) nil))
 
 (defun idlwave-html-help-location ()
   "Return the help directory where HTML files are, or nil if that is unknown."
--- a/lisp/progmodes/idlw-shell.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/idlw-shell.el	Fri Dec 10 15:00:25 2010 -0500
@@ -866,7 +866,7 @@
 (defvar idlwave-shell-only-prompt-pattern nil)
 (defvar tool-bar-map)
 
-(defun idlwave-shell-mode ()
+(define-derived-mode idlwave-shell-mode comint-mode "IDL-Shell"
   "Major mode for interacting with an inferior IDL process.
 
 1. Shell Interaction
@@ -947,28 +947,23 @@
 8. Keybindings
    -----------
 \\{idlwave-shell-mode-map}"
-
-  (interactive)
+  :abbrev-table idlwave-mode-abbrev-table
   (idlwave-setup) ; Make sure config files and paths, etc. are available.
   (unless (file-name-absolute-p idlwave-shell-command-history-file)
     (setq idlwave-shell-command-history-file
 	  (expand-file-name idlwave-shell-command-history-file
 			    idlwave-config-directory)))
 
-  ;; We don't do `kill-all-local-variables' here, because this is done by
-  ;; comint
   (setq comint-prompt-regexp idlwave-shell-prompt-pattern)
   (setq comint-process-echoes t)
 
   ;; Can not use history expansion because "!" is used for system variables.
   (setq comint-input-autoexpand nil)
-;  (setq comint-input-ring-size 64)
-  (make-local-variable 'comint-completion-addsuffix)
+  ;; (setq comint-input-ring-size 64)
+  
   (set (make-local-variable 'completion-ignore-case) t)
-  (setq comint-completion-addsuffix '("/" . ""))
+  (set (make-local-variable 'comint-completion-addsuffix) '("/" . ""))
   (setq comint-input-ignoredups t)
-  (setq major-mode 'idlwave-shell-mode)
-  (setq mode-name "IDL-Shell")
   (setq idlwave-shell-mode-line-info nil)
   (setq mode-line-format
 	'(""
@@ -1023,7 +1018,6 @@
 	    nil 'local)
   (add-hook 'kill-buffer-hook 'idlwave-shell-delete-temp-files nil 'local)
   (add-hook 'kill-emacs-hook 'idlwave-shell-delete-temp-files)
-  (use-local-map idlwave-shell-mode-map)
   (easy-menu-add idlwave-shell-mode-menu idlwave-shell-mode-map)
 
   ;; Set the optional comint variables
@@ -1054,10 +1048,7 @@
   ;; with overlay-arrows.
   (remove-hook 'comint-output-filter-functions 'py-pdbtrack-track-stack-file)
 
-
   ;; IDLWAVE syntax, and turn on abbreviations
-  (setq local-abbrev-table idlwave-mode-abbrev-table)
-  (set-syntax-table idlwave-mode-syntax-table)
   (set (make-local-variable 'comment-start) ";")
   (setq abbrev-mode t)
 
@@ -1076,8 +1067,6 @@
   ;; Turn off the non-debug toolbar buttons (open,save,etc.)
   (set (make-local-variable 'tool-bar-map) nil)
 
-  ;; Run the hooks.
-  (run-mode-hooks 'idlwave-shell-mode-hook)
   (idlwave-shell-send-command idlwave-shell-initial-commands nil 'hide)
   ;; Turn off IDL's ^d interpreting, and define a system
   ;; variable which knows the version of IDLWAVE
@@ -3895,7 +3884,7 @@
   (setq overlay-arrow-string nil)
   (let (buf)
     (cond
-     ((eq major-mode 'idlwave-mode)
+     ((derived-mode-p 'idlwave-mode)
       (save-buffer)
       (setq idlwave-shell-last-save-and-action-file (buffer-file-name)))
      (idlwave-shell-last-save-and-action-file
@@ -4083,7 +4072,7 @@
 (defun idlwave-shell-file-name (name)
   "If `idlwave-shell-use-truename' is non-nil, convert file name to true name.
 Otherwise, just expand the file name."
-  (let ((def-dir (if (eq major-mode 'idlwave-shell-mode)
+  (let ((def-dir (if (derived-mode-p 'idlwave-shell-mode)
 		     default-directory
 		   idlwave-shell-default-directory)))
     (if idlwave-shell-use-truename
@@ -4346,7 +4335,7 @@
       (while (setq buf (pop buffers))
 	(when (buffer-live-p buf)
 	  (set-buffer buf)
-	  (when (and (eq major-mode 'idlwave-mode)
+	  (when (and (derived-mode-p 'idlwave-mode)
 		     buffer-file-name
 		     idlwave-shell-electric-debug-mode)
 	    (idlwave-shell-electric-debug-mode 0))))))
@@ -4371,51 +4360,51 @@
     ["Electric Debug Mode"
      idlwave-shell-electric-debug-mode
      :style toggle :selected idlwave-shell-electric-debug-mode
-     :included (eq major-mode 'idlwave-mode) :keys "C-c C-d C-v"]
+     :included (derived-mode-p 'idlwave-mode) :keys "C-c C-d C-v"]
     "--"
     ("Compile & Run"
      ["Save and .RUN" idlwave-shell-save-and-run
-      (or (eq major-mode 'idlwave-mode)
+      (or (derived-mode-p 'idlwave-mode)
 	  idlwave-shell-last-save-and-action-file)]
      ["Save and .COMPILE" idlwave-shell-save-and-compile
-      (or (eq major-mode 'idlwave-mode)
+      (or (derived-mode-p 'idlwave-mode)
 	  idlwave-shell-last-save-and-action-file)]
      ["Save and @Batch" idlwave-shell-save-and-batch
-      (or (eq major-mode 'idlwave-mode)
+      (or (derived-mode-p 'idlwave-mode)
 	  idlwave-shell-last-save-and-action-file)]
      "--"
      ["Goto Next Error" idlwave-shell-goto-next-error t]
      "--"
      ["Compile and Run Region" idlwave-shell-run-region
-      (eq major-mode 'idlwave-mode)]
+      (derived-mode-p 'idlwave-mode)]
      ["Evaluate Region" idlwave-shell-evaluate-region
-      (eq major-mode 'idlwave-mode)]
+      (derived-mode-p 'idlwave-mode)]
      "--"
      ["Execute Default Cmd" idlwave-shell-execute-default-command-line t]
      ["Edit Default Cmd" idlwave-shell-edit-default-command-line t])
     ("Breakpoints"
      ["Set Breakpoint" idlwave-shell-break-here
-      :keys "C-c C-d C-b" :active (eq major-mode 'idlwave-mode)]
+      :keys "C-c C-d C-b" :active (derived-mode-p 'idlwave-mode)]
      ("Set Special Breakpoint"
       ["Set After Count Breakpoint"
        (progn
 	(let ((count (string-to-number (read-string "Break after count: "))))
 	      (if (integerp count) (idlwave-shell-break-here count))))
-       :active (eq major-mode 'idlwave-mode)]
+       :active (derived-mode-p 'idlwave-mode)]
       ["Set Condition Breakpoint"
        (idlwave-shell-break-here '(4))
-       :active (eq major-mode 'idlwave-mode)])
+       :active (derived-mode-p 'idlwave-mode)])
      ["Break in Module" idlwave-shell-break-in
-      :keys "C-c C-d C-i" :active (eq major-mode 'idlwave-mode)]
+      :keys "C-c C-d C-i" :active (derived-mode-p 'idlwave-mode)]
      ["Break in this Module" idlwave-shell-break-this-module
-      :keys "C-c C-d C-j" :active (eq major-mode 'idlwave-mode)]
+      :keys "C-c C-d C-j" :active (derived-mode-p 'idlwave-mode)]
      ["Clear Breakpoint" idlwave-shell-clear-current-bp t]
      ["Clear All Breakpoints" idlwave-shell-clear-all-bp t]
      ["Disable/Enable Breakpoint" idlwave-shell-toggle-enable-current-bp t]
      ["Goto Previous Breakpoint" idlwave-shell-goto-previous-bp
-      :keys "C-c C-d [" :active (eq major-mode 'idlwave-mode)]
+      :keys "C-c C-d [" :active (derived-mode-p 'idlwave-mode)]
      ["Goto Next Breakpoint" idlwave-shell-goto-next-bp
-      :keys "C-c C-d ]" :active (eq major-mode 'idlwave-mode)]
+      :keys "C-c C-d ]" :active (derived-mode-p 'idlwave-mode)]
      ["List All Breakpoints" idlwave-shell-list-all-bp t]
      ["Resync Breakpoints" idlwave-shell-bp-query t])
     ("Continue/Step"
@@ -4427,7 +4416,7 @@
      ["... to End of Subprog" idlwave-shell-return t]
      ["... to End of Subprog+1" idlwave-shell-out t]
      ["... to Here (Cursor Line)" idlwave-shell-to-here
-      :keys "C-c C-d C-h" :active (eq major-mode 'idlwave-mode)])
+      :keys "C-c C-d C-h" :active (derived-mode-p 'idlwave-mode)])
     ("Examine Expressions"
      ["Print expression" idlwave-shell-print t]
      ["Help on expression" idlwave-shell-help-expression t]
@@ -4512,7 +4501,7 @@
       (save-current-buffer
 	(dolist (buf (buffer-list))
           (set-buffer buf)
-          (if (eq major-mode 'idlwave-mode)
+          (if (derived-mode-p 'idlwave-mode)
               (progn
                 (easy-menu-remove idlwave-mode-debug-menu)
                 (easy-menu-add idlwave-mode-debug-menu)))))))
--- a/lisp/progmodes/idlw-toolbar.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/idlw-toolbar.el	Fri Dec 10 15:00:25 2010 -0500
@@ -807,7 +807,7 @@
      "Goto Next Error"]
     [idlwave-toolbar-stop-at-icon
      idlwave-shell-break-here
-     (eq major-mode 'idlwave-mode)
+     (derived-mode-p 'idlwave-mode)
      "Set Breakpoint at selected position"]
     [idlwave-toolbar-clear-at-icon
      idlwave-shell-clear-current-bp
@@ -819,7 +819,7 @@
      "Clear all Breakpoints"]
     [idlwave-toolbar-stop-beginning-icon
      idlwave-shell-break-this-module
-     (eq major-mode 'idlwave-mode)
+     (derived-mode-p 'idlwave-mode)
      "Stop at beginning of enclosing Routine"]
     [idlwave-toolbar-stop-in-icon
      idlwave-shell-break-in
@@ -839,7 +839,7 @@
      "Continue Current Program"]
     [idlwave-toolbar-to-here-icon
      idlwave-shell-to-here
-     (eq major-mode 'idlwave-mode)
+     (derived-mode-p 'idlwave-mode)
      "Continue to Here (cursor position)"]
     [idlwave-toolbar-step-over-icon
      idlwave-shell-stepover
@@ -871,7 +871,7 @@
      "Reset IDL (RETALL & CLOSE,/ALL and more)"]
     [idlwave-toolbar-electric-debug-icon
      idlwave-shell-electric-debug-mode
-     (eq major-mode 'idlwave-mode)
+     (derived-mode-p 'idlwave-mode)
      "Toggle Electric Debug Mode"]
     ))
 
@@ -884,8 +884,7 @@
   "Add the IDLWAVE toolbar if appropriate."
   (if (and (featurep 'xemacs)    ; This is a noop on Emacs
 	   (boundp 'idlwave-toolbar-is-possible)
-	   (or (eq major-mode 'idlwave-mode)
-	       (eq major-mode 'idlwave-shell-mode)))
+	   (derived-mode-p 'idlwave-mode 'idlwave-shell-mode))
       (set-specifier default-toolbar (cons (current-buffer)
 					   idlwave-toolbar))))
 
@@ -893,8 +892,7 @@
   "Add the IDLWAVE toolbar if appropriate."
   (if (and (featurep 'xemacs)    ; This is a noop on Emacs
 	   (boundp 'idlwave-toolbar-is-possible)
-	   (or (eq major-mode 'idlwave-mode)
-	       (eq major-mode 'idlwave-shell-mode)))
+           (derived-mode-p 'idlwave-mode 'idlwave-shell-mode))
       (remove-specifier default-toolbar (current-buffer))))
 
 (defvar idlwave-shell-mode-map)
--- a/lisp/progmodes/idlwave.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/idlwave.el	Fri Dec 10 15:00:25 2010 -0500
@@ -1776,7 +1776,7 @@
 (defvar idlwave-mode-debug-menu)
 
 ;;;###autoload
-(defun idlwave-mode ()
+(define-derived-mode idlwave-mode prog-mode "IDLWAVE"
   "Major mode for editing IDL source files (version 6.1_em22).
 
 The main features of this mode are
@@ -1895,21 +1895,15 @@
    followed by the key sequence to see what the key sequence does.
 
 \\{idlwave-mode-map}"
-
-  (interactive)
-  (kill-all-local-variables)
-
+  :abbrev-table idlwave-mode-abbrev-table
   (if idlwave-startup-message
       (message "Emacs IDLWAVE mode version %s." idlwave-mode-version))
   (setq idlwave-startup-message nil)
 
-  (setq local-abbrev-table idlwave-mode-abbrev-table)
-  (set-syntax-table idlwave-mode-syntax-table)
-
   (set (make-local-variable 'indent-line-function) 'idlwave-indent-and-action)
 
-  (make-local-variable idlwave-comment-indent-function)
-  (set idlwave-comment-indent-function 'idlwave-comment-hook)
+  (set (make-local-variable idlwave-comment-indent-function)
+       #'idlwave-comment-hook)
 
   (set (make-local-variable 'comment-start-skip) ";+[ \t]*")
   (set (make-local-variable 'comment-start) ";")
@@ -1919,14 +1913,10 @@
   (set (make-local-variable 'indent-tabs-mode) nil)
   (set (make-local-variable 'completion-ignore-case) t)
 
-  (use-local-map idlwave-mode-map)
-
   (when (featurep 'easymenu)
     (easy-menu-add idlwave-mode-menu idlwave-mode-map)
     (easy-menu-add idlwave-mode-debug-menu idlwave-mode-map))
 
-  (setq mode-name "IDLWAVE")
-  (setq major-mode 'idlwave-mode)
   (setq abbrev-mode t)
 
   (set (make-local-variable idlwave-fill-function) 'idlwave-auto-fill)
@@ -1991,10 +1981,7 @@
   (idlwave-new-buffer-update)
 
   ;; Check help location
-  (idlwave-help-check-locations)
-
-  ;; Run the mode hook
-  (run-mode-hooks 'idlwave-mode-hook))
+  (idlwave-help-check-locations))
 
 (defvar idlwave-setup-done nil)
 (defun idlwave-setup ()
@@ -2543,7 +2530,7 @@
 actual statement."
   (interactive)
   (cond
-   ((eq major-mode 'idlwave-shell-mode)
+   ((derived-mode-p 'idlwave-shell-mode)
     (if (re-search-backward idlwave-shell-prompt-pattern nil t)
 	(goto-char (match-end 0))))
    (t
@@ -3732,7 +3719,7 @@
 
 The lines containing S1 and S2 are reindented using `indent-region'
 unless the optional second argument NOINDENT is non-nil."
-  (if (eq major-mode 'idlwave-shell-mode)
+  (if (derived-mode-p 'idlwave-shell-mode)
       ;; This is a gross hack to avoit template abbrev expansion
       ;; in the shell.  FIXME: This is a dirty hack.
       (if (and (eq this-command 'self-insert-command)
@@ -5088,7 +5075,7 @@
       (setq res nil))
      (t
       ;; Just scan this buffer
-      (if (eq major-mode 'idlwave-mode)
+      (if (derived-mode-p 'idlwave-mode)
 	  (progn
 	    (message "Scanning current buffer...")
 	    (setq res (idlwave-get-routine-info-from-buffers
@@ -5142,7 +5129,7 @@
 (defun idlwave-update-current-buffer-info (why)
   "Update `idlwave-routines' for current buffer.
 Can run from `after-save-hook'."
-  (when (and (eq major-mode 'idlwave-mode)
+  (when (and (derived-mode-p 'idlwave-mode)
 	     (or (eq t idlwave-auto-routine-info-updates)
 		 (memq why idlwave-auto-routine-info-updates))
 	     idlwave-scan-all-buffers-for-routine-info
@@ -5188,7 +5175,7 @@
     (save-excursion
       (while (setq buf (pop buffers))
 	(set-buffer buf)
-	(if (and (eq major-mode 'idlwave-mode)
+	(if (and (derived-mode-p 'idlwave-mode)
 		 buffer-file-name)
 	    ;; yes, this buffer has the right mode.
 	    (progn (setq res (condition-case nil
@@ -7030,7 +7017,7 @@
   "Call FUNCTION as a completion chooser and pass ARGS to it."
   (let ((completion-ignore-case t))	    ; install correct value
     (apply function args))
-  (if (and (eq major-mode 'idlwave-shell-mode)
+  (if (and (derived-mode-p 'idlwave-shell-mode)
 	   (boundp 'font-lock-mode)
 	   (not font-lock-mode))
       ;; For the shell, remove the fontification of the word before point
@@ -7431,7 +7418,7 @@
 	  ;; Read the file in temporarily
 	  (set-buffer (get-buffer-create " *IDLWAVE-tmp*"))
 	  (erase-buffer)
-	  (unless (eq major-mode 'idlwave-mode)
+	  (unless (derived-mode-p 'idlwave-mode)
 	    (idlwave-mode))
 	  (insert-file-contents file))
 	(save-excursion
@@ -8183,8 +8170,7 @@
     ;; If this is the OBJ_NEW function, try to figure out the class and use
     ;; the keywords from the corresponding INIT method.
     (if (and (equal (upcase name) "OBJ_NEW")
-	     (or (eq major-mode 'idlwave-mode)
-		 (eq major-mode 'idlwave-shell-mode)))
+	     (derived-mode-p 'idlwave-mode 'idlwave-shell-mode))
 	(let* ((bos (save-excursion (idlwave-beginning-of-statement) (point)))
 	       (string (buffer-substring bos (point)))
 	       (case-fold-search t)
@@ -8634,7 +8620,7 @@
   "List the load path shadows of all routines defined in current buffer."
   (interactive "P")
   (idlwave-routines)
-  (if (eq major-mode 'idlwave-mode)
+  (if (derived-mode-p 'idlwave-mode)
       (idlwave-list-load-path-shadows
        nil (idlwave-update-current-buffer-info 'save-buffer)
        "in current buffer")
--- a/lisp/progmodes/inf-lisp.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/inf-lisp.el	Fri Dec 10 15:00:25 2010 -0500
@@ -216,7 +216,7 @@
 
 (put 'inferior-lisp-mode 'mode-class 'special)
 
-(defun inferior-lisp-mode ()
+(define-derived-mode inferior-lisp-mode comint-mode "Inferior Lisp"
   "Major mode for interacting with an inferior Lisp process.
 Runs a Lisp interpreter as a subprocess of Emacs, with Lisp I/O through an
 Emacs buffer.  Variable `inferior-lisp-program' controls which Lisp interpreter
@@ -263,18 +263,11 @@
 Paragraphs are separated only by blank lines.  Semicolons start comments.
 If you accidentally suspend your process, use \\[comint-continue-subjob]
 to continue it."
-  (interactive)
-  (delay-mode-hooks
-    (comint-mode))
   (setq comint-prompt-regexp inferior-lisp-prompt)
-  (setq major-mode 'inferior-lisp-mode)
-  (setq mode-name "Inferior Lisp")
   (setq mode-line-process '(":%s"))
   (lisp-mode-variables t)
-  (use-local-map inferior-lisp-mode-map)    ;c-c c-k for "kompile" file
   (setq comint-get-old-input (function lisp-get-old-input))
-  (setq comint-input-filter (function lisp-input-filter))
-  (run-mode-hooks 'inferior-lisp-mode-hook))
+  (setq comint-input-filter (function lisp-input-filter)))
 
 (defun lisp-get-old-input ()
   "Return a string containing the sexp ending at point."
@@ -600,7 +593,7 @@
 ;;  "Returns the current inferior Lisp process.
 ;; See variable `inferior-lisp-buffer'."
 (defun inferior-lisp-proc ()
-  (let ((proc (get-buffer-process (if (eq major-mode 'inferior-lisp-mode)
+  (let ((proc (get-buffer-process (if (derived-mode-p 'inferior-lisp-mode)
 				      (current-buffer)
 				    inferior-lisp-buffer))))
     (or proc
--- a/lisp/progmodes/js.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/js.el	Fri Dec 10 15:00:25 2010 -0500
@@ -2135,7 +2135,7 @@
         with imenu-use-markers = t
         for buffer being the buffers
         for imenu-index = (with-current-buffer buffer
-                            (when (eq major-mode 'js-mode)
+                            (when (derived-mode-p 'js-mode)
                               (js--imenu-create-index)))
         do (js--imenu-to-flat imenu-index "" symbols)
         finally return symbols))
@@ -3286,15 +3286,9 @@
 ;;; Main Function
 
 ;;;###autoload
-(define-derived-mode js-mode prog-mode "js"
-  "Major mode for editing JavaScript.
-
-Key bindings:
-
-\\{js-mode-map}"
-
+(define-derived-mode js-mode prog-mode "Javascript"
+  "Major mode for editing JavaScript."
   :group 'js
-  :syntax-table js-mode-syntax-table
 
   (set (make-local-variable 'indent-line-function) 'js-indent-line)
   (set (make-local-variable 'beginning-of-defun-function)
@@ -3330,9 +3324,6 @@
   (set (make-local-variable 'imenu-create-index-function)
        #'js--imenu-create-index)
 
-  (setq major-mode 'js-mode)
-  (setq mode-name "Javascript")
-
   ;; for filling, pretend we're cc-mode
   (setq c-comment-prefix-regexp "//+\\|\\**"
         c-paragraph-start "$"
@@ -3363,10 +3354,9 @@
   ;; the buffer containing the problem, JIT-lock will apply the
   ;; correct syntax to the regular expresion literal and the problem
   ;; will mysteriously disappear.
-  (font-lock-set-defaults)
-
-  (let (font-lock-keywords) ; leaves syntactic keywords intact
-    (font-lock-fontify-buffer)))
+  ;; FIXME: We should actually do this fontification lazily by adding
+  ;; calls to syntax-propertize wherever it's really needed.
+  (syntax-propertize (point-max)))
 
 ;;;###autoload
 (defalias 'javascript-mode 'js-mode)
--- a/lisp/progmodes/m4-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/m4-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -143,27 +143,12 @@
   (switch-to-buffer-other-window "*m4-output*"))
 
 ;;;###autoload
-(defun m4-mode ()
-  "A major mode to edit m4 macro files.
-\\{m4-mode-map}
-"
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map m4-mode-map)
-
-  (make-local-variable 'comment-start)
-  (setq comment-start "#")
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (setq parse-sexp-ignore-comments t)
-  (setq local-abbrev-table m4-mode-abbrev-table)
-
-  (make-local-variable	'font-lock-defaults)
-  (setq major-mode 'm4-mode
-	mode-name "m4"
-	font-lock-defaults '(m4-font-lock-keywords nil)
-	)
-  (set-syntax-table m4-mode-syntax-table)
-  (run-mode-hooks 'm4-mode-hook))
+(define-derived-mode m4-mode prog-mode "m4"
+  "A major mode to edit m4 macro files."
+  :abbrev-table m4-mode-abbrev-table
+  (set (make-local-variable 'comment-start) "#")
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
+  (set (make-local-variable 'font-lock-defaults) '(m4-font-lock-keywords nil)))
 
 (provide 'm4-mode)
 ;;stuff to play with for debugging
--- a/lisp/progmodes/meta-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/meta-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -474,6 +474,7 @@
 
 (defun meta-complete-symbol ()
   "Perform completion on Metafont or MetaPost symbol preceding point."
+  ;; FIXME: Use completion-at-point-functions.
   (interactive "*")
   (let ((list meta-complete-list)
         entry)
@@ -844,11 +845,10 @@
 
 ;;; Syntax table, keymap and menu.
 
-(defvar meta-mode-abbrev-table nil
+(define-abbrev-table 'meta-mode-abbrev-table ()
   "Abbrev table used in Metafont or MetaPost mode.")
-(define-abbrev-table 'meta-mode-abbrev-table ())
 
-(defvar meta-mode-syntax-table
+(defvar meta-common-mode-syntax-table
   (let ((st (make-syntax-table)))
     ;; underscores are word constituents
     (modify-syntax-entry ?_  "w"  st)
@@ -885,9 +885,8 @@
     st)
   "Syntax table used in Metafont or MetaPost mode.")
 
-(defvar meta-mode-map
+(defvar meta-common-mode-map
   (let ((map (make-sparse-keymap)))
-    (define-key map "\C-m"      'reindent-then-newline-and-indent)
     ;; Comment Paragraphs:
     ;; (define-key map "\M-a"      'backward-sentence)
     ;; (define-key map "\M-e"      'forward-sentence)
@@ -915,10 +914,10 @@
     ;; (define-key map "\C-c\C-l"  'meta-recenter-output)
     map)
   "Keymap used in Metafont or MetaPost mode.")
-
+(define-obsolete-variable-alias 'meta-mode-map 'meta-common-mode-map "24.1")
 
 (easy-menu-define
- meta-mode-menu meta-mode-map
+ meta-mode-menu meta-common-mode-map
  "Menu used in Metafont or MetaPost mode."
  (list "Meta"
        ["Forward Environment"           meta-beginning-of-defun t]
@@ -976,106 +975,62 @@
 
 ;;; Initialization.
 
-(defun meta-common-initialization ()
+(define-derived-mode meta-common-mode prog-mode "-Meta-common-"
   "Common initialization for Metafont or MetaPost mode."
-  (kill-all-local-variables)
-
-  (make-local-variable 'paragraph-start)
-  (make-local-variable 'paragraph-separate)
-  (setq paragraph-start
-        (concat page-delimiter "\\|$"))
-  (setq paragraph-separate
-        (concat page-delimiter "\\|$"))
+  :abbrev-table meta-mode-abbrev-table
+  (set (make-local-variable 'paragraph-start)
+       (concat page-delimiter "\\|$"))
+  (set (make-local-variable 'paragraph-separate)
+       (concat page-delimiter "\\|$"))
 
-  (make-local-variable 'paragraph-ignore-fill-prefix)
-  (setq paragraph-ignore-fill-prefix t)
+  (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
 
-  (make-local-variable 'comment-start-skip)
-  (make-local-variable 'comment-start)
-  (make-local-variable 'comment-end)
-  (make-local-variable 'comment-multi-line)
-  (setq comment-start-skip "%+[ \t\f]*")
-  (setq comment-start "%")
-  (setq comment-end "")
-  (setq comment-multi-line nil)
+  (set (make-local-variable 'comment-start-skip) "%+[ \t\f]*")
+  (set (make-local-variable 'comment-start) "%")
+  (set (make-local-variable 'comment-end) "")
+  (set (make-local-variable 'comment-multi-line) nil)
 
   ;; We use `back-to-indentation' but \f is no indentation sign.
   (modify-syntax-entry ?\f "_   ")
 
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (setq parse-sexp-ignore-comments t)
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
 
-  (make-local-variable 'comment-indent-function)
-  (setq comment-indent-function 'meta-comment-indent)
-  (make-local-variable 'indent-line-function)
-  (setq indent-line-function 'meta-indent-line)
+  (set (make-local-variable 'comment-indent-function) #'meta-comment-indent)
+  (set (make-local-variable 'indent-line-function) #'meta-indent-line)
   ;; No need to define a mode-specific 'indent-region-function.
   ;; Simply use the generic 'indent-region and 'comment-region.
 
   ;; Set defaults for font-lock mode.
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults
-        '(meta-font-lock-keywords
-          nil nil ((?_ . "w")) nil
-          (font-lock-comment-start-regexp . "%")))
+  (set (make-local-variable 'font-lock-defaults)
+       '(meta-font-lock-keywords
+         nil nil ((?_ . "w")) nil
+         (font-lock-comment-start-regexp . "%")))
 
   ;; Activate syntax table, keymap and menu.
-  (setq local-abbrev-table meta-mode-abbrev-table)
-  (set-syntax-table meta-mode-syntax-table)
-  (use-local-map meta-mode-map)
-  (easy-menu-add meta-mode-menu)
-  )
+  (easy-menu-add meta-mode-menu))
 
 
 ;;;###autoload
-(defun metafont-mode ()
-  "Major mode for editing Metafont sources.
-Special commands:
-\\{meta-mode-map}
-
-Turning on Metafont mode calls the value of the variables
-`meta-common-mode-hook' and `metafont-mode-hook'."
-  (interactive)
-  (meta-common-initialization)
-  (setq mode-name "Metafont")
-  (setq major-mode 'metafont-mode)
-
+(define-derived-mode metafont-mode meta-common-mode "Metafont"
+  "Major mode for editing Metafont sources."
   ;; Set defaults for completion function.
-  (make-local-variable 'meta-symbol-list)
-  (make-local-variable 'meta-symbol-changed)
-  (make-local-variable 'meta-complete-list)
-  (setq meta-symbol-list nil)
-  (setq meta-symbol-changed nil)
+  (set (make-local-variable 'meta-symbol-list) nil)
+  (set (make-local-variable 'meta-symbol-changed) nil)
   (apply 'meta-add-symbols metafont-symbol-list)
-  (setq meta-complete-list
+  (set (make-local-variable 'meta-complete-list)
         (list (list "\\<\\(\\sw+\\)" 1 'meta-symbol-list)
-              (list "" 'ispell-complete-word)))
-  (run-mode-hooks 'meta-common-mode-hook 'metafont-mode-hook))
+              (list "" 'ispell-complete-word))))
 
 ;;;###autoload
-(defun metapost-mode ()
-  "Major mode for editing MetaPost sources.
-Special commands:
-\\{meta-mode-map}
-
-Turning on MetaPost mode calls the value of the variable
-`meta-common-mode-hook' and `metafont-mode-hook'."
-  (interactive)
-  (meta-common-initialization)
-  (setq mode-name "MetaPost")
-  (setq major-mode 'metapost-mode)
-
+(define-derived-mode metapost-mode meta-common-mode "MetaPost"
+  "Major mode for editing MetaPost sources."
   ;; Set defaults for completion function.
-  (make-local-variable 'meta-symbol-list)
-  (make-local-variable 'meta-symbol-changed)
-  (make-local-variable 'meta-complete-list)
-  (setq meta-symbol-list nil)
-  (setq meta-symbol-changed nil)
+  (set (make-local-variable 'meta-symbol-list) nil)
+  (set (make-local-variable 'meta-symbol-changed) nil)
   (apply 'meta-add-symbols metapost-symbol-list)
-  (setq meta-complete-list
+  (set (make-local-variable 'meta-complete-list)
         (list (list "\\<\\(\\sw+\\)" 1 'meta-symbol-list)
-              (list "" 'ispell-complete-word)))
-  (run-mode-hooks 'meta-common-mode-hook 'metapost-mode-hook))
+              (list "" 'ispell-complete-word))))
 
 
 ;;; Just in case ...
--- a/lisp/progmodes/mixal-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/mixal-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -1106,8 +1106,7 @@
 
 ;;;###autoload
 (define-derived-mode mixal-mode fundamental-mode "mixal"
-  "Major mode for the mixal asm language.
-\\{mixal-mode-map}"
+  "Major mode for the mixal asm language."
   (set (make-local-variable 'comment-start) "*")
   (set (make-local-variable 'comment-start-skip) "^\\*[ \t]*")
   (set (make-local-variable 'font-lock-defaults)
@@ -1117,11 +1116,7 @@
   ;; might add an indent function in the future
   ;;  (set (make-local-variable 'indent-line-function) 'mixal-indent-line)
   (set (make-local-variable 'compile-command) (concat "mixasm "
-						      buffer-file-name))
-  ;; mixasm will do strange when there is no final newline,
-  ;; so let Emacs ensure that it is always there
-  (set (make-local-variable 'require-final-newline)
-       mode-require-final-newline))
+						      buffer-file-name)))
 
 (provide 'mixal-mode)
 
--- a/lisp/progmodes/modula2.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/modula2.el	Fri Dec 10 15:00:25 2010 -0500
@@ -308,8 +308,6 @@
    `m2-indent' controls the number of spaces for each indentation.
    `m2-compile-command' holds the command to compile a Modula-2 program.
    `m2-link-command' holds the command to link a Modula-2 program."
-  (make-local-variable 'm2-end-comment-column)
-  
   (set (make-local-variable 'paragraph-start) (concat "$\\|" page-delimiter))
   (set (make-local-variable 'paragraph-separate) paragraph-start)
   (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
--- a/lisp/progmodes/octave-inf.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/octave-inf.el	Fri Dec 10 15:00:25 2010 -0500
@@ -121,34 +121,24 @@
 This variable is used to initialize `comint-dynamic-complete-functions'
 in the Inferior Octave buffer.")
 
-(defun inferior-octave-mode ()
+(define-derived-mode inferior-octave-mode comint-mode "Inferior Octave"
   "Major mode for interacting with an inferior Octave process.
 Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs
 buffer.
 
 Entry to this mode successively runs the hooks `comint-mode-hook' and
 `inferior-octave-mode-hook'."
-  (interactive)
-  (delay-mode-hooks (comint-mode))
   (setq comint-prompt-regexp inferior-octave-prompt
-	major-mode 'inferior-octave-mode
-	mode-name "Inferior Octave"
 	mode-line-process '(":%s")
 	local-abbrev-table octave-abbrev-table)
-  (use-local-map inferior-octave-mode-map)
-  (set-syntax-table inferior-octave-mode-syntax-table)
 
-  (make-local-variable 'comment-start)
-  (setq comment-start octave-comment-start)
-  (make-local-variable 'comment-end)
-  (setq comment-end "")
-  (make-local-variable 'comment-column)
-  (setq comment-column 32)
-  (make-local-variable 'comment-start-skip)
-  (setq comment-start-skip octave-comment-start-skip)
+  (set (make-local-variable 'comment-start) octave-comment-start)
+  (set (make-local-variable 'comment-end) "")
+  (set (make-local-variable 'comment-column) 32)
+  (set (make-local-variable 'comment-start-skip) octave-comment-start-skip)
 
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults '(inferior-octave-font-lock-keywords nil nil))
+  (set (make-local-variable 'font-lock-defaults)
+       '(inferior-octave-font-lock-keywords nil nil))
 
   (setq comint-input-ring-file-name
 	(or (getenv "OCTAVE_HISTFILE") "~/.octave_hist")
@@ -157,9 +147,7 @@
        inferior-octave-dynamic-complete-functions)
   (add-hook 'comint-input-filter-functions
 	'inferior-octave-directory-tracker nil t)
-  (comint-read-input-ring t)
-
-  (run-mode-hooks 'inferior-octave-mode-hook))
+  (comint-read-input-ring t))
 
 ;;;###autoload
 (defun inferior-octave (&optional arg)
--- a/lisp/progmodes/octave-mod.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/octave-mod.el	Fri Dec 10 15:00:25 2010 -0500
@@ -655,8 +655,7 @@
        'octave-beginning-of-defun)
 
   (easy-menu-add octave-mode-menu)
-  (octave-initialize-completions)
-  (run-mode-hooks 'octave-mode-hook))
+  (octave-initialize-completions))
 
 (defvar info-lookup-mode)
 
--- a/lisp/progmodes/perl-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/perl-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -545,7 +545,7 @@
   "Normal hook to run when entering Perl mode.")
 
 ;;;###autoload
-(defun perl-mode ()
+(define-derived-mode perl-mode prog-mode "Perl"
   "Major mode for editing Perl code.
 Expression and list commands understand all Perl brackets.
 Tab indents for Perl code.
@@ -592,33 +592,16 @@
   perl-label-offset               -5   -8   -2   -2   -2
 
 Turning on Perl mode runs the normal hook `perl-mode-hook'."
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map perl-mode-map)
-  (setq major-mode 'perl-mode)
-  (setq mode-name "Perl")
-  (setq local-abbrev-table perl-mode-abbrev-table)
-  (set-syntax-table perl-mode-syntax-table)
-  (make-local-variable 'paragraph-start)
-  (setq paragraph-start (concat "$\\|" page-delimiter))
-  (make-local-variable 'paragraph-separate)
-  (setq paragraph-separate paragraph-start)
-  (make-local-variable 'paragraph-ignore-fill-prefix)
-  (setq paragraph-ignore-fill-prefix t)
-  (make-local-variable 'indent-line-function)
-  (setq indent-line-function 'perl-indent-line)
-  (make-local-variable 'require-final-newline)
-  (setq require-final-newline mode-require-final-newline)
-  (make-local-variable 'comment-start)
-  (setq comment-start "# ")
-  (make-local-variable 'comment-end)
-  (setq comment-end "")
-  (make-local-variable 'comment-start-skip)
-  (setq comment-start-skip "\\(^\\|\\s-\\);?#+ *")
-  (make-local-variable 'comment-indent-function)
-  (setq comment-indent-function 'perl-comment-indent)
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (setq parse-sexp-ignore-comments t)
+  :abbrev-table perl-mode-abbrev-table
+  (set (make-local-variable 'paragraph-start) (concat "$\\|" page-delimiter))
+  (set (make-local-variable 'paragraph-separate) paragraph-start)
+  (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
+  (set (make-local-variable 'indent-line-function) #'perl-indent-line)
+  (set (make-local-variable 'comment-start) "# ")
+  (set (make-local-variable 'comment-end) "")
+  (set (make-local-variable 'comment-start-skip) "\\(^\\|\\s-\\);?#+ *")
+  (set (make-local-variable 'comment-indent-function) #'perl-comment-indent)
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
   ;; Tell font-lock.el how to handle Perl.
   (setq font-lock-defaults '((perl-font-lock-keywords
 			      perl-font-lock-keywords-1
@@ -636,8 +619,7 @@
   (setq imenu-case-fold-search nil)
   ;; Setup outline-minor-mode.
   (set (make-local-variable 'outline-regexp) perl-outline-regexp)
-  (set (make-local-variable 'outline-level) 'perl-outline-level)
-  (run-mode-hooks 'perl-mode-hook))
+  (set (make-local-variable 'outline-level) 'perl-outline-level))
 
 ;; This is used by indent-for-comment
 ;; to decide how much to indent a comment in Perl code
--- a/lisp/progmodes/prolog.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/prolog.el	Fri Dec 10 15:00:25 2010 -0500
@@ -180,12 +180,9 @@
     (`(:after . ,(or `":-" `"->")) prolog-indent-width)))
 
 (defun prolog-mode-variables ()
-  (make-local-variable 'paragraph-separate)
-  (setq paragraph-separate (concat "%%\\|$\\|" page-delimiter)) ;'%%..'
-  (make-local-variable 'paragraph-ignore-fill-prefix)
-  (setq paragraph-ignore-fill-prefix t)
-  (make-local-variable 'imenu-generic-expression)
-  (setq imenu-generic-expression '((nil "^\\sw+" 0)))
+  (set (make-local-variable 'paragraph-separate) (concat "%%\\|$\\|" page-delimiter)) ;'%%..'
+  (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
+  (set (make-local-variable 'imenu-generic-expression) '((nil "^\\sw+" 0)))
 
   ;; Setup SMIE.
   (smie-setup prolog-smie-grammar #'prolog-smie-rules
@@ -197,14 +194,10 @@
   ;; There's no real closer in Prolog anyway.
   (set (make-local-variable 'smie-blink-matching-inners) t)
 
-  (make-local-variable 'comment-start)
-  (setq comment-start "%")
-  (make-local-variable 'comment-start-skip)
-  (setq comment-start-skip "\\(?:%+\\|/\\*+\\)[ \t]*")
-  (make-local-variable 'comment-end-skip)
-  (setq comment-end-skip "[ \t]*\\(\n\\|\\*+/\\)")
-  (make-local-variable 'comment-column)
-  (setq comment-column 48))
+  (set (make-local-variable 'comment-start) "%")
+  (set (make-local-variable 'comment-start-skip) "\\(?:%+\\|/\\*+\\)[ \t]*")
+  (set (make-local-variable 'comment-end-skip) "[ \t]*\\(\n\\|\\*+/\\)")
+  (set (make-local-variable 'comment-column) 48))
 
 (defvar prolog-mode-map
   (let ((map (make-sparse-keymap)))
--- a/lisp/progmodes/ps-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/ps-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -979,9 +979,7 @@
 
 (define-derived-mode ps-run-mode comint-mode "Interactive PS"
   "Major mode in interactive PostScript window.
-This mode is invoked from `ps-mode' and should not be called directly.
-
-\\{ps-run-mode-map}"
+This mode is invoked from `ps-mode' and should not be called directly."
   (set (make-local-variable 'font-lock-defaults)
        '((ps-run-font-lock-keywords
 	  ps-run-font-lock-keywords-1
@@ -991,7 +989,7 @@
 
 (defun ps-run-running ()
   "Error if not in `ps-mode' or not running PostScript."
-  (unless (equal major-mode 'ps-mode)
+  (unless (derived-mode-p 'ps-mode)
     (error "This function can only be called from PostScript mode"))
   (unless (equal (process-status "ps-run") 'run)
     (error "No PostScript process running")))
--- a/lisp/progmodes/python.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/python.el	Fri Dec 10 15:00:25 2010 -0500
@@ -1317,7 +1317,7 @@
 				  (let ((name (buffer-file-name)))
 				    (if name
 					(file-name-nondirectory name))))))))
-  (setq python-saved-check-command command)
+  (set (make-local-variable 'python-saved-check-command) command)
   (require 'compile)                    ;To define compilation-* variables.
   (save-some-buffers (not compilation-ask-about-save) nil)
   (let ((compilation-error-regexp-alist
@@ -2522,7 +2522,6 @@
   (set (make-local-variable 'outline-heading-end-regexp) ":\\s-*\n")
   (set (make-local-variable 'outline-level) #'python-outline-level)
   (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil)
-  (make-local-variable 'python-saved-check-command)
   (set (make-local-variable 'beginning-of-defun-function)
        'python-beginning-of-defun)
   (set (make-local-variable 'end-of-defun-function) 'python-end-of-defun)
--- a/lisp/progmodes/scheme.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/scheme.el	Fri Dec 10 15:00:25 2010 -0500
@@ -126,39 +126,27 @@
 (defun scheme-mode-variables ()
   (set-syntax-table scheme-mode-syntax-table)
   (setq local-abbrev-table scheme-mode-abbrev-table)
-  (make-local-variable 'paragraph-start)
-  (setq paragraph-start (concat "$\\|" page-delimiter))
-  (make-local-variable 'paragraph-separate)
-  (setq paragraph-separate paragraph-start)
-  (make-local-variable 'paragraph-ignore-fill-prefix)
-  (setq paragraph-ignore-fill-prefix t)
-  (make-local-variable 'fill-paragraph-function)
-  (setq fill-paragraph-function 'lisp-fill-paragraph)
+  (set (make-local-variable 'paragraph-start) (concat "$\\|" page-delimiter))
+  (set (make-local-variable 'paragraph-separate) paragraph-start)
+  (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
+  (set (make-local-variable 'fill-paragraph-function) 'lisp-fill-paragraph)
   ;; Adaptive fill mode gets in the way of auto-fill,
   ;; and should make no difference for explicit fill
   ;; because lisp-fill-paragraph should do the job.
-  (make-local-variable 'adaptive-fill-mode)
-  (setq adaptive-fill-mode nil)
-  (make-local-variable 'indent-line-function)
-  (setq indent-line-function 'lisp-indent-line)
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (setq parse-sexp-ignore-comments t)
-  (make-local-variable 'outline-regexp)
-  (setq outline-regexp ";;; \\|(....")
-  (make-local-variable 'comment-start)
-  (setq comment-start ";")
+  (set (make-local-variable 'adaptive-fill-mode) nil)
+  (set (make-local-variable 'indent-line-function) 'lisp-indent-line)
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
+  (set (make-local-variable 'outline-regexp) ";;; \\|(....")
+  (set (make-local-variable 'comment-start) ";")
   (set (make-local-variable 'comment-add) 1)
-  (make-local-variable 'comment-start-skip)
   ;; Look within the line for a ; following an even number of backslashes
   ;; after either a non-backslash or the line beginning.
-  (setq comment-start-skip "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\);+[ \t]*")
+  (set (make-local-variable 'comment-start-skip)
+       "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\);+[ \t]*")
   (set (make-local-variable 'font-lock-comment-start-skip) ";+ *")
-  (make-local-variable 'comment-column)
-  (setq comment-column 40)
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (setq parse-sexp-ignore-comments t)
-  (make-local-variable 'lisp-indent-function)
-  (setq lisp-indent-function 'scheme-indent-function)
+  (set (make-local-variable 'comment-column) 40)
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
+  (set (make-local-variable 'lisp-indent-function) 'scheme-indent-function)
   (setq mode-line-process '("" scheme-mode-line-process))
   (set (make-local-variable 'imenu-case-fold-search) t)
   (setq imenu-generic-expression scheme-imenu-generic-expression)
@@ -206,7 +194,7 @@
   (define-key map "\e\C-q" 'indent-sexp))
 
 ;;;###autoload
-(defun scheme-mode ()
+(define-derived-mode scheme-mode prog-mode "Scheme"
   "Major mode for editing Scheme code.
 Editing commands are similar to those of `lisp-mode'.
 
@@ -225,13 +213,7 @@
 \\{scheme-mode-map}
 Entry to this mode calls the value of `scheme-mode-hook'
 if that value is non-nil."
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map scheme-mode-map)
-  (setq major-mode 'scheme-mode)
-  (setq mode-name "Scheme")
-  (scheme-mode-variables)
-  (run-mode-hooks 'scheme-mode-hook))
+  (scheme-mode-variables))
 
 (defgroup scheme nil
   "Editing Scheme code."
@@ -404,10 +386,7 @@
 Entering this mode runs the hooks `scheme-mode-hook' and then
 `dsssl-mode-hook' and inserts the value of `dsssl-sgml-declaration' if
 that variable's value is a string."
-  (make-local-variable 'page-delimiter)
-  (setq page-delimiter "^;;;" ; ^L not valid SGML char
-	major-mode 'dsssl-mode
-	mode-name "DSSSL")
+  (set (make-local-variable 'page-delimiter) "^;;;") ; ^L not valid SGML char
   ;; Insert a suitable SGML declaration into an empty buffer.
   ;; FIXME: This should use `auto-insert-alist' instead.
   (and (zerop (buffer-size))
--- a/lisp/progmodes/sh-script.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/sh-script.el	Fri Dec 10 15:00:25 2010 -0500
@@ -362,8 +362,6 @@
   "The shell being programmed.  This is set by \\[sh-set-shell].")
 ;;;###autoload(put 'sh-shell 'safe-local-variable 'symbolp)
 
-(defvar sh-mode-abbrev-table nil)
-
 (define-abbrev-table 'sh-mode-abbrev-table ())
 
 
@@ -566,19 +564,6 @@
   :type '(repeat function)
   :group 'sh-script)
 
-
-(defcustom sh-require-final-newline
-  '((csh . t)
-    (pdksh . t))
-  "Value of `require-final-newline' in Shell-Script mode buffers.
-\(SHELL . t) means use the value of `mode-require-final-newline' for SHELL.
-See `sh-feature'."
-  :type '(repeat (cons (symbol :tag "Shell")
-		       (choice (const :tag "require" t)
-			       (sexp :format "Evaluate: %v"))))
-  :group 'sh-script)
-
-
 (defcustom sh-assignment-regexp
   '((csh . "\\<\\([[:alnum:]_]+\\)\\(\\[.+\\]\\)?[ \t]*[-+*/%^]?=")
     ;; actually spaces are only supported in let/(( ... ))
@@ -1717,10 +1702,6 @@
       (setq sh-shell-file
 	    (executable-set-magic shell (sh-feature sh-shell-arg)
 				  no-query-flag insert-flag)))
-  (let ((tem (sh-feature sh-require-final-newline)))
-    (if (eq tem t)
-	(set (make-local-variable 'require-final-newline)
-             mode-require-final-newline)))
   (setq mode-line-process (format "[%s]" sh-shell))
   (set (make-local-variable 'sh-shell-variables) nil)
   (set (make-local-variable 'sh-shell-variables-initialized) nil)
--- a/lisp/progmodes/simula.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/simula.el	Fri Dec 10 15:00:25 2010 -0500
@@ -371,33 +371,20 @@
 
 Turning on SIMULA mode calls the value of the variable simula-mode-hook
 with no arguments, if that value is non-nil."
-  (make-local-variable 'comment-column)
-  (setq comment-column 40)
-;  (make-local-variable 'end-comment-column)
-;  (setq end-comment-column 75)
-  (make-local-variable 'paragraph-start)
-  (setq paragraph-start "[ \t]*$\\|\\f")
-  (make-local-variable 'paragraph-separate)
-  (setq paragraph-separate paragraph-start)
-  (make-local-variable 'indent-line-function)
-  (setq indent-line-function 'simula-indent-line)
-  (make-local-variable 'require-final-newline)
-  (setq require-final-newline mode-require-final-newline)
-  (make-local-variable 'comment-start)
-  (setq comment-start "! ")
-  (make-local-variable 'comment-end)
-  (setq comment-end " ;")
-  (make-local-variable 'comment-start-skip)
-  (setq comment-start-skip "!+ *")
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (setq parse-sexp-ignore-comments nil)
-  (make-local-variable 'comment-multi-line)
-  (setq comment-multi-line t)
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults
-	'((simula-font-lock-keywords simula-font-lock-keywords-1
-	   simula-font-lock-keywords-2 simula-font-lock-keywords-3)
-	  nil t ((?_ . "w"))))
+  (set (make-local-variable 'comment-column) 40)
+  ;; (set (make-local-variable 'end-comment-column) 75)
+  (set (make-local-variable 'paragraph-start) "[ \t]*$\\|\\f")
+  (set (make-local-variable 'paragraph-separate) paragraph-start)
+  (set (make-local-variable 'indent-line-function) 'simula-indent-line)
+  (set (make-local-variable 'comment-start) "! ")
+  (set (make-local-variable 'comment-end) " ;")
+  (set (make-local-variable 'comment-start-skip) "!+ *")
+  (set (make-local-variable 'parse-sexp-ignore-comments) nil)
+  (set (make-local-variable 'comment-multi-line) t)
+  (set (make-local-variable 'font-lock-defaults)
+       '((simula-font-lock-keywords simula-font-lock-keywords-1
+          simula-font-lock-keywords-2 simula-font-lock-keywords-3)
+         nil t ((?_ . "w"))))
   (set (make-local-variable 'syntax-propertize-function)
        simula-syntax-propertize-function)
   (abbrev-mode 1))
--- a/lisp/progmodes/sql.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/sql.el	Fri Dec 10 15:00:25 2010 -0500
@@ -2303,20 +2303,21 @@
 	 '((?_ . "w") (?. . "w")))))
 
     ;; Get the product-specific keywords.
-    (setq sql-mode-font-lock-keywords
-	  (append
-	   (unless (eq sql-product 'ansi)
-	     (sql-get-product-feature sql-product :font-lock))
-	   ;; Always highlight ANSI keywords
-	   (sql-get-product-feature 'ansi :font-lock)
-	   ;; Fontify object names in CREATE, DROP and ALTER DDL
-	   ;; statements
-	   (list sql-mode-font-lock-object-name)))
+    (set (make-local-variable 'sql-mode-font-lock-keywords)
+         (append
+          (unless (eq sql-product 'ansi)
+            (sql-get-product-feature sql-product :font-lock))
+          ;; Always highlight ANSI keywords
+          (sql-get-product-feature 'ansi :font-lock)
+          ;; Fontify object names in CREATE, DROP and ALTER DDL
+          ;; statements
+          (list sql-mode-font-lock-object-name)))
 
     ;; Setup font-lock.  Force re-parsing of `font-lock-defaults'.
     (kill-local-variable 'font-lock-set-defaults)
-    (setq font-lock-defaults (list 'sql-mode-font-lock-keywords
-				   keywords-only t syntax-alist))
+    (set (make-local-variable 'font-lock-defaults)
+         (list 'sql-mode-font-lock-keywords
+               keywords-only t syntax-alist))
 
     ;; Force font lock to reinitialize if it is already on
     ;; Otherwise, we can wait until it can be started.
@@ -3232,7 +3233,7 @@
 ;;; SQL mode -- uses SQL interactive mode
 
 ;;;###autoload
-(defun sql-mode ()
+(define-derived-mode sql-mode prog-mode "SQL"
   "Major mode to edit SQL.
 
 You can send SQL statements to the SQLi buffer using
@@ -3259,18 +3260,11 @@
 \(add-hook 'sql-mode-hook
           (lambda ()
 	    (modify-syntax-entry ?\\\\ \".\" sql-mode-syntax-table)))"
-  (interactive)
-  (kill-all-local-variables)
-  (setq major-mode 'sql-mode)
-  (setq mode-name "SQL")
-  (use-local-map sql-mode-map)
+  :abbrev-table sql-mode-abbrev-table
   (if sql-mode-menu
       (easy-menu-add sql-mode-menu)); XEmacs
-  (set-syntax-table sql-mode-syntax-table)
-  (make-local-variable 'font-lock-defaults)
-  (make-local-variable 'sql-mode-font-lock-keywords)
-  (make-local-variable 'comment-start)
-  (setq comment-start "--")
+  
+  (set (make-local-variable 'comment-start) "--")
   ;; Make each buffer in sql-mode remember the "current" SQLi buffer.
   (make-local-variable 'sql-buffer)
   ;; Add imenu support for sql-mode.  Note that imenu-generic-expression
@@ -3280,17 +3274,11 @@
 	imenu-case-fold-search t)
   ;; Make `sql-send-paragraph' work on paragraphs that contain indented
   ;; lines.
-  (make-local-variable 'paragraph-separate)
-  (make-local-variable 'paragraph-start)
-  (setq paragraph-separate "[\f]*$"
-	paragraph-start "[\n\f]")
+  (set (make-local-variable 'paragraph-separate) "[\f]*$")
+  (set (make-local-variable 'paragraph-start) "[\n\f]")
   ;; Abbrevs
-  (setq local-abbrev-table sql-mode-abbrev-table)
   (setq abbrev-all-caps 1)
-  ;; Run hook
-  (run-mode-hooks 'sql-mode-hook)
   ;; Catch changes to sql-product and highlight accordingly
-  (sql-highlight-product)
   (add-hook 'hack-local-variables-hook 'sql-highlight-product t t))
 
 
@@ -3375,15 +3363,14 @@
 	   sql-product))
 
   ;; Setup the mode.
-  (setq major-mode 'sql-interactive-mode)
-  (setq mode-name (concat "SQLi[" (or (sql-get-product-feature sql-product :name)
-				      (symbol-name sql-product)) "]"))
+  (setq major-mode 'sql-interactive-mode) ;FIXME: Use define-derived-mode.
+  (setq mode-name
+        (concat "SQLi[" (or (sql-get-product-feature sql-product :name)
+                            (symbol-name sql-product)) "]"))
   (use-local-map sql-interactive-mode-map)
   (if sql-interactive-mode-menu
       (easy-menu-add sql-interactive-mode-menu)) ; XEmacs
   (set-syntax-table sql-mode-syntax-table)
-  (make-local-variable 'sql-mode-font-lock-keywords)
-  (make-local-variable 'font-lock-defaults)
 
   ;; Note that making KEYWORDS-ONLY nil will cause havoc if you try
   ;; SELECT 'x' FROM DUAL with SQL*Plus, because the title of the column
@@ -3392,8 +3379,7 @@
   (sql-product-font-lock t nil)
 
   ;; Enable commenting and uncommenting of the region.
-  (make-local-variable 'comment-start)
-  (setq comment-start "--")
+  (set (make-local-variable 'comment-start) "--")
   ;; Abbreviation table init and case-insensitive.  It is not activated
   ;; by default.
   (setq local-abbrev-table sql-mode-abbrev-table)
@@ -3403,8 +3389,8 @@
   ;; Save the connection name
   (make-local-variable 'sql-connection)
   ;; Create a usefull name for renaming this buffer later.
-  (make-local-variable 'sql-alternate-buffer-name)
-  (setq sql-alternate-buffer-name (sql-make-alternate-buffer-name))
+  (set (make-local-variable 'sql-alternate-buffer-name)
+       (sql-make-alternate-buffer-name))
   ;; User stuff.  Initialize before the hook.
   (set (make-local-variable 'sql-prompt-regexp)
        (sql-get-product-feature sql-product :prompt-regexp))
--- a/lisp/progmodes/tcl.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/tcl.el	Fri Dec 10 15:00:25 2010 -0500
@@ -572,10 +572,7 @@
 
 Turning on Tcl mode runs `tcl-mode-hook'.  Read the documentation for
 `tcl-mode-hook' to see what kinds of interesting hook functions
-already exist.
-
-Commands:
-\\{tcl-mode-map}"
+already exist."
   (unless (and (boundp 'filladapt-mode) filladapt-mode)
     (set (make-local-variable 'paragraph-ignore-fill-prefix) t))
 
@@ -1064,7 +1061,7 @@
 (defun inferior-tcl-proc ()
   "Return current inferior Tcl process.
 See variable `inferior-tcl-buffer'."
-  (let ((proc (get-buffer-process (if (eq major-mode 'inferior-tcl-mode)
+  (let ((proc (get-buffer-process (if (derived-mode-p 'inferior-tcl-mode)
 				      (current-buffer)
 				    inferior-tcl-buffer))))
     (or proc
@@ -1287,7 +1284,7 @@
 If FLAG is nil, just uses `current-word'.
 Otherwise scans backward for most likely Tcl command word."
   (if (and flag
-	   (memq major-mode '(tcl-mode inferior-tcl-mode)))
+	   (derived-mode-p 'tcl-mode 'inferior-tcl-mode))
       (condition-case nil
 	  (save-excursion
 	    ;; Look backward for first word actually in alist.
@@ -1363,7 +1360,7 @@
     ;; filename.
     (car (comint-get-source "Load Tcl file: "
 			    (or (and
-				 (eq major-mode 'tcl-mode)
+				 (derived-mode-p 'tcl-mode)
 				 (buffer-file-name))
 				tcl-previous-dir/file)
 			    '(tcl-mode) t))
@@ -1383,12 +1380,12 @@
    (list
     (car (comint-get-source "Restart with Tcl file: "
 			    (or (and
-				 (eq major-mode 'tcl-mode)
+				 (derived-mode-p 'tcl-mode)
 				 (buffer-file-name))
 				tcl-previous-dir/file)
 			    '(tcl-mode) t))
     current-prefix-arg))
-  (let* ((buf (if (eq major-mode 'inferior-tcl-mode)
+  (let* ((buf (if (derived-mode-p 'inferior-tcl-mode)
 		  (current-buffer)
 		inferior-tcl-buffer))
 	 (proc (and buf (get-process buf))))
--- a/lisp/progmodes/vera-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/vera-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -253,7 +253,7 @@
 ;;;###autoload (add-to-list 'auto-mode-alist (cons (purecopy "\\.vr[hi]?\\'")  'vera-mode))
 
 ;;;###autoload
-(defun vera-mode ()
+(define-derived-mode vera-mode prog-mode "Vera"
   "Major mode for editing Vera code.
 
 Usage:
@@ -301,13 +301,6 @@
 -------------
 
 \\{vera-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
-  (setq major-mode 'vera-mode)
-  (setq mode-name "Vera")
-  ;; set maps and tables
-  (use-local-map vera-mode-map)
-  (set-syntax-table vera-mode-syntax-table)
   ;; set local variables
   (require 'cc-cmds)
   (set (make-local-variable 'comment-start) "//")
@@ -328,9 +321,7 @@
   ;; add menu (XEmacs)
   (easy-menu-add vera-mode-menu)
   ;; miscellaneous
-  (message "Vera Mode %s.  Type C-c C-h for documentation." vera-version)
-  ;; run hooks
-  (run-hooks 'vera-mode-hook))
+  (message "Vera Mode %s.  Type C-c C-h for documentation." vera-version))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
--- a/lisp/progmodes/verilog-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/verilog-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -1533,16 +1533,14 @@
   (cond
    ((or (file-exists-p "makefile")	;If there is a makefile, use it
 	(file-exists-p "Makefile"))
-    (make-local-variable 'compile-command)
-    (setq compile-command "make "))
+    (set (make-local-variable 'compile-command) "make "))
    (t
-    (make-local-variable 'compile-command)
-    (setq compile-command
-	  (if verilog-tool
-	      (if (string-match "%s" (eval verilog-tool))
-		  (format (eval verilog-tool) (or buffer-file-name ""))
-		(concat (eval verilog-tool) " " (or buffer-file-name "")))
-	    ""))))
+    (set (make-local-variable 'compile-command)
+         (if verilog-tool
+             (if (string-match "%s" (eval verilog-tool))
+                 (format (eval verilog-tool) (or buffer-file-name ""))
+               (concat (eval verilog-tool) " " (or buffer-file-name "")))
+           ""))))
   (verilog-modify-compile-command))
 
 (defun verilog-expand-command (command)
@@ -1566,8 +1564,8 @@
   (when (and
 	 (stringp compile-command)
 	 (string-match "\\b\\(__FLAGS__\\|__FILE__\\)\\b" compile-command))
-    (make-local-variable 'compile-command)
-    (setq compile-command (verilog-expand-command compile-command))))
+    (set (make-local-variable 'compile-command)
+         (verilog-expand-command compile-command))))
 
 (if (featurep 'xemacs)
     ;; Following code only gets called from compilation-mode-hook on XEmacs to add error handling.
@@ -1588,8 +1586,8 @@
 			    (cdr compilation-error-regexp-alist-alist)))))
       (if (boundp 'compilation-font-lock-keywords)
 	  (progn
-	    (make-local-variable 'compilation-font-lock-keywords)
-	    (setq compilation-font-lock-keywords  verilog-error-font-lock-keywords)
+            (set (make-local-variable 'compilation-font-lock-keywords)
+                 verilog-error-font-lock-keywords)
 	    (font-lock-set-defaults)))
       ;; Need to re-run compilation-error-regexp builder
       (if (fboundp 'compilation-build-compilation-error-regexp-alist)
@@ -2975,7 +2973,7 @@
 ;;
 (defvar verilog-which-tool 1)
 ;;;###autoload
-(defun verilog-mode ()
+(define-derived-mode verilog-mode prog-mode "Verilog"
   "Major mode for editing Verilog code.
 \\<verilog-mode-map>
 See \\[describe-function] verilog-auto (\\[verilog-auto]) for details on how
@@ -3103,30 +3101,21 @@
 Key bindings specific to `verilog-mode-map' are:
 
 \\{verilog-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map verilog-mode-map)
-  (setq major-mode 'verilog-mode)
-  (setq mode-name "Verilog")
-  (setq local-abbrev-table verilog-mode-abbrev-table)
+  :abbrev-table verilog-mode-abbrev-table
   (set (make-local-variable 'beginning-of-defun-function)
        'verilog-beg-of-defun)
   (set (make-local-variable 'end-of-defun-function)
        'verilog-end-of-defun)
   (set-syntax-table verilog-mode-syntax-table)
-  (make-local-variable 'indent-line-function)
-  (setq indent-line-function 'verilog-indent-line-relative)
+  (set (make-local-variable 'indent-line-function)
+       #'verilog-indent-line-relative)
   (setq comment-indent-function 'verilog-comment-indent)
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (setq parse-sexp-ignore-comments nil)
-  (make-local-variable 'comment-start)
-  (make-local-variable 'comment-end)
-  (make-local-variable 'comment-multi-line)
-  (make-local-variable 'comment-start-skip)
-  (setq comment-start "// "
-	comment-end ""
-	comment-start-skip "/\\*+ *\\|// *"
-	comment-multi-line nil)
+  (set (make-local-variable 'parse-sexp-ignore-comments) nil)
+  
+  (set (make-local-variable 'comment-start) "// ")
+  (set (make-local-variable 'comment-end) "")
+  (set (make-local-variable 'comment-start-skip) "/\\*+ *\\|// *")
+  (set (make-local-variable 'comment-multi-line) nil)
   ;; Set up for compilation
   (setq verilog-which-tool 1)
   (setq verilog-tool 'verilog-linter)
@@ -3166,8 +3155,8 @@
     (add-hook 'after-change-functions 'verilog-highlight-region t t))
 
   ;; Tell imenu how to handle Verilog.
-  (make-local-variable 'imenu-generic-expression)
-  (setq imenu-generic-expression verilog-imenu-generic-expression)
+  (set (make-local-variable 'imenu-generic-expression)
+       verilog-imenu-generic-expression)
   ;; Tell which-func-modes that imenu knows about verilog
   (when (boundp 'which-function-modes)
     (add-to-list 'which-func-modes 'verilog-mode))
@@ -3180,8 +3169,7 @@
 		  hs-special-modes-alist))))
 
   ;; Stuff for autos
-  (add-hook 'write-contents-hooks 'verilog-auto-save-check) ; already local
-  (run-hooks 'verilog-mode-hook))
+  (add-hook 'write-contents-hooks 'verilog-auto-save-check nil 'local))
 
 
 ;;
@@ -8042,8 +8030,7 @@
 	(let ((enumvar (intern (concat "venum-" enumname))))
 	  ;;(message "Define %s=%s" defname defvalue) (sleep-for 1)
 	  (unless (boundp enumvar) (set enumvar nil))
-	  (make-local-variable enumvar)
-	  (add-to-list enumvar defname)))))
+          (add-to-list (make-local-variable enumvar) defname)))))
 
 (defun verilog-read-defines (&optional filename recurse subcall)
   "Read `defines and parameters for the current file, or optional FILENAME.
@@ -9349,10 +9336,9 @@
 (defun verilog-auto-reeval-locals (&optional force)
   "Read file local variable segment at bottom of file if it has changed.
 If FORCE, always reread it."
-  (make-local-variable 'verilog-auto-last-file-locals)
   (let ((curlocal (verilog-auto-read-locals)))
     (when (or force (not (equal verilog-auto-last-file-locals curlocal)))
-      (setq verilog-auto-last-file-locals curlocal)
+      (set (make-local-variable 'verilog-auto-last-file-locals) curlocal)
       ;; Note this may cause this function to be recursively invoked,
       ;; because hack-local-variables may call (verilog-mode)
       ;; The above when statement will prevent it from recursing forever.
--- a/lisp/progmodes/vhdl-mode.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/vhdl-mode.el	Fri Dec 10 15:00:25 2010 -0500
@@ -4117,7 +4117,10 @@
 ;; performs all buffer local initializations
 
 ;;;###autoload
-(defun vhdl-mode ()
+(define-derived-mode vhdl-mode prog-mode
+  '("VHDL" (vhdl-electric-mode "/" (vhdl-stutter-mode "/"))
+           (vhdl-electric-mode "e")
+           (vhdl-stutter-mode "s"))
   "Major mode for editing VHDL code.
 
 Usage:
@@ -4650,26 +4653,13 @@
 -------------
 
 \\{vhdl-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
-  (setq major-mode 'vhdl-mode)
-  (setq mode-name '("VHDL"
-                    (vhdl-electric-mode "/" (vhdl-stutter-mode "/"))
-                    (vhdl-electric-mode "e")
-                    (vhdl-stutter-mode "s")))
-
-  ;; set maps and tables
-  (use-local-map vhdl-mode-map)
-  (set-syntax-table vhdl-mode-syntax-table)
-  (setq local-abbrev-table vhdl-mode-abbrev-table)
+  :abbrev-table vhdl-mode-abbrev-table
 
   ;; set local variables
   (set (make-local-variable 'paragraph-start)
        "\\s-*\\(--+\\s-*$\\|[^ -]\\|$\\)")
   (set (make-local-variable 'paragraph-separate) paragraph-start)
   (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
-  (set (make-local-variable 'require-final-newline)
-       (if vhdl-emacs-22 mode-require-final-newline t))
   (set (make-local-variable 'parse-sexp-ignore-comments) t)
   (set (make-local-variable 'indent-line-function) 'vhdl-indent-line)
   (set (make-local-variable 'comment-start) "--")
@@ -4686,8 +4676,7 @@
   ;; setup the comment indent variable in a Emacs version portable way
   ;; ignore any byte compiler warnings you might get here
   (when (boundp 'comment-indent-function)
-    (make-local-variable 'comment-indent-function)
-    (setq comment-indent-function 'vhdl-comment-indent))
+    (set (make-local-variable 'comment-indent-function) 'vhdl-comment-indent))
 
   ;; initialize font locking
   (set (make-local-variable 'font-lock-defaults)
@@ -4731,12 +4720,7 @@
   (vhdl-ps-print-init)
   (vhdl-write-file-hooks-init)
   (message "VHDL Mode %s.%s" vhdl-version
-	   (if noninteractive "" "  See menu for documentation and release notes."))
-
-  ;; run hooks
-  (if vhdl-emacs-22
-      (run-mode-hooks 'vhdl-mode-hook)
-    (run-hooks 'vhdl-mode-hook)))
+	   (if noninteractive "" "  See menu for documentation and release notes.")))
 
 (defun vhdl-activate-customizations ()
   "Activate all customizations on local variables."
@@ -4754,10 +4738,10 @@
 (defun vhdl-write-file-hooks-init ()
   "Add/remove hooks when buffer is saved."
   (if vhdl-modify-date-on-saving
-      (add-hook 'local-write-file-hooks 'vhdl-template-modify-noerror)
-    (remove-hook 'local-write-file-hooks 'vhdl-template-modify-noerror))
-  (make-local-variable 'after-save-hook)
-  (add-hook 'after-save-hook 'vhdl-add-modified-file))
+      (add-hook 'local-write-file-hooks 'vhdl-template-modify-noerror nil t)
+    (remove-hook 'local-write-file-hooks 'vhdl-template-modify-noerror t))
+  (if (featurep 'xemacs) (make-local-hook 'after-save-hook))
+  (add-hook 'after-save-hook 'vhdl-add-modified-file nil t))
 
 (defun vhdl-process-command-line-option (option)
   "Process command line options for VHDL Mode."
@@ -5271,13 +5255,12 @@
       (lambda (varentry)
 	(let ((var (car varentry))
 	      (val (cdr varentry)))
-	  (and local
-	       (make-local-variable var))
 	  ;; special case for vhdl-offsets-alist
 	  (if (not (eq var 'vhdl-offsets-alist))
-	      (set var val)
+	      (set (if local (make-local-variable var) var) val)
 	    ;; reset vhdl-offsets-alist to the default value first
-	    (setq vhdl-offsets-alist (copy-alist vhdl-offsets-alist-default))
+	    (set (if local (make-local-variable var) var)
+                 (copy-alist vhdl-offsets-alist-default))
 	    ;; now set the langelems that are different
 	    (mapcar
 	     (function
@@ -12500,10 +12483,10 @@
 	    (cons (list 'vhdl-mode vhdl-hs-start-regexp nil "--\\( \\|$\\)"
 			'vhdl-hs-forward-sexp-func nil)
 		  hs-special-modes-alist)))
-    (make-local-variable 'hs-minor-mode-hook)
+    (if (featurep 'xemacs) (make-local-hook 'hs-minor-mode-hook))
     (if vhdl-hide-all-init
-	(add-hook 'hs-minor-mode-hook 'hs-hide-all)
-      (remove-hook 'hs-minor-mode-hook 'hs-hide-all))
+	(add-hook 'hs-minor-mode-hook 'hs-hide-all nil t)
+      (remove-hook 'hs-minor-mode-hook 'hs-hide-all t))
     (hs-minor-mode arg)
     (force-mode-line-update)))		; hack to update menu bar
 
@@ -12970,8 +12953,8 @@
   (if (featurep 'xemacs)
       (when (boundp 'ps-print-color-p)
 	(vhdl-ps-print-settings))
-    (make-local-variable 'ps-print-hook)
-    (add-hook 'ps-print-hook 'vhdl-ps-print-settings)))
+    (if (featurep 'xemacs) (make-local-hook 'ps-print-hook))
+    (add-hook 'ps-print-hook 'vhdl-ps-print-settings nil t)))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
--- a/lisp/progmodes/which-func.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/which-func.el	Fri Dec 10 15:00:25 2010 -0500
@@ -283,8 +283,7 @@
 	       (null which-function-imenu-failed))
       (imenu--make-index-alist t)
       (unless imenu--index-alist
-	(make-local-variable 'which-function-imenu-failed)
-	(setq which-function-imenu-failed t)))
+        (set (make-local-variable 'which-function-imenu-failed) t)))
     ;; If we have an index alist, use it.
     (when (and (null name)
 	       (boundp 'imenu--index-alist) imenu--index-alist)
--- a/lisp/progmodes/xscheme.el	Fri Dec 10 18:29:54 2010 +0100
+++ b/lisp/progmodes/xscheme.el	Fri Dec 10 15:00:25 2010 -0500
@@ -186,8 +186,7 @@
   (setq-default xscheme-process-command-line command-line)
   (switch-to-buffer
    (xscheme-start-process command-line process-name buffer-name))
-  (make-local-variable 'xscheme-process-command-line)
-  (setq xscheme-process-command-line command-line))
+  (set (make-local-variable 'xscheme-process-command-line) command-line))
 
 (defun xscheme-read-command-line (arg)
   (let ((default
@@ -278,13 +277,11 @@
 		      xscheme-buffer-name
 		      t)))
   (let ((process-name (verify-xscheme-buffer buffer-name t)))
-    (make-local-variable 'xscheme-buffer-name)
-    (setq xscheme-buffer-name buffer-name)
-    (make-local-variable 'xscheme-process-name)
-    (setq xscheme-process-name process-name)
-    (make-local-variable 'xscheme-runlight)
-    (setq xscheme-runlight (with-current-buffer buffer-name
-                             xscheme-runlight))))
+    (set (make-local-variable 'xscheme-buffer-name) buffer-name)
+    (set (make-local-variable 'xscheme-process-name) process-name)
+    (set (make-local-variable 'xscheme-runlight)
+         (with-current-buffer buffer-name
+           xscheme-runlight))))
 
 (defun local-clear-scheme-interaction-buffer ()
   "Make the current buffer use the default scheme interaction buffer."
@@ -386,21 +383,19 @@
 with no args, if that value is non-nil.
  Likewise with the value of scheme-mode-hook.
  scheme-interaction-mode-hook is called after scheme-mode-hook."
+  ;; FIXME: Use define-derived-mode.
   (interactive "P")
   (if (not preserve)
       (let ((previous-mode major-mode))
         (kill-all-local-variables)
-        (make-local-variable 'xscheme-previous-mode)
-        (make-local-variable 'xscheme-buffer-name)
         (make-local-variable 'xscheme-process-name)
         (make-local-variable 'xscheme-previous-process-state)
         (make-local-variable 'xscheme-runlight-string)
         (make-local-variable 'xscheme-runlight)
-        (make-local-variable 'xscheme-last-input-end)
-        (setq xscheme-previous-mode previous-mode)
+        (set (make-local-variable 'xscheme-previous-mode) previous-mode)
         (let ((buffer (current-buffer)))
-          (setq xscheme-buffer-name (buffer-name buffer))
-          (setq xscheme-last-input-end (make-marker))
+          (set (make-local-variable 'xscheme-buffer-name) (buffer-name buffer))
+          (set (make-local-variable 'xscheme-last-input-end) (make-marker))
           (let ((process (get-buffer-process buffer)))
             (if process
                 (progn
@@ -420,7 +415,7 @@
 (defun exit-scheme-interaction-mode ()
   "Take buffer out of scheme interaction mode"
   (interactive)
-  (if (not (eq major-mode 'scheme-interaction-mode))
+  (if (not (derived-mode-p 'scheme-interaction-mode))
       (error "Buffer not in scheme interaction mode"))
   (let ((previous-state xscheme-previous-process-state))
     (funcall xscheme-previous-mode)
@@ -437,7 +432,7 @@
 
 (defun scheme-interaction-mode-initialize ()
   (use-local-map scheme-interaction-mode-map)
-  (setq major-mode 'scheme-interaction-mode)
+  (setq major-mode 'scheme-interaction-mode) ;FIXME: Use define-derived-mode.
   (setq mode-name "Scheme Interaction"))
 
 (defun scheme-interaction-mode-commands (keymap)
@@ -469,8 +464,8 @@
 
 (defun xscheme-enter-interaction-mode ()
   (with-current-buffer (xscheme-process-buffer)
-    (if (not (eq major-mode 'scheme-interaction-mode))
-	(if (eq major-mode 'scheme-debugger-mode)
+    (if (not (derived-mode-p 'scheme-interaction-mode))
+	(if (derived-mode-p 'scheme-debugger-mode)
 	    (scheme-interaction-mode-initialize)
 	    (scheme-interaction-mode t)))))
 
@@ -494,7 +489,7 @@
 
 (defun scheme-debugger-mode-initialize ()
   (use-local-map scheme-debugger-mode-map)
-  (setq major-mode 'scheme-debugger-mode)
+  (setq major-mode 'scheme-debugger-mode) ;FIXME: Use define-derived-mode.
   (setq mode-name "Scheme Debugger"))
 
 (defun scheme-debugger-mode-commands (keymap)
@@ -518,9 +513,9 @@
 
 (defun xscheme-enter-debugger-mode (prompt-string)
   (with-current-buffer (xscheme-process-buffer)
-    (if (not (eq major-mode 'scheme-debugger-mode))
+    (if (not (derived-mode-p 'scheme-debugger-mode))
 	(progn
-	  (if (not (eq major-mode 'scheme-interaction-mode))
+	  (if (not (derived-mode-p 'scheme-interaction-mode))
 	      (scheme-interaction-mode t))
 	  (scheme-debugger-mode-initialize)))))
 
@@ -528,7 +523,7 @@
   (let ((buffer (xscheme-process-buffer)))
     (and buffer
 	 (with-current-buffer buffer
-	   (eq major-mode 'scheme-debugger-mode)))))
+	   (derived-mode-p 'scheme-debugger-mode)))))
 
 ;;;; Evaluation Commands
 
@@ -550,7 +545,7 @@
 (defun xscheme-send-string-1 (strings)
   (let ((string (apply 'concat strings)))
     (xscheme-send-string-2 string)
-    (if (eq major-mode 'scheme-interaction-mode)
+    (if (derived-mode-p 'scheme-interaction-mode)
 	(xscheme-insert-expression string))))
 
 (defun xscheme-send-string-2 (string)