X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/6b410da764ff2df0e05373361f902939d3065f13..01a314694499b7245c21b05a0a48bc22ae8ab575:/lisp/derived.el diff --git a/lisp/derived.el b/lisp/derived.el index f48156a101..d50ac6d288 100644 --- a/lisp/derived.el +++ b/lisp/derived.el @@ -1,4 +1,4 @@ -;;; derived.el -- allow inheritance of major modes. +;;; derived.el --- allow inheritance of major modes. ;;; (formerly mode-clone.el) ;; Copyright (C) 1993, 1994 Free Software Foundation, Inc. @@ -19,8 +19,9 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. ;;; Commentary: @@ -142,30 +143,31 @@ been generated automatically, with a reference to the keymap." (setq docstring (or docstring (derived-mode-make-docstring parent child))) (` (progn - (derived-mode-init-mode-variables (quote (, child))) + (derived-mode-init-mode-variables '(, child)) + (put '(, child) 'derived-mode-parent '(, parent)) (defun (, child) () (, docstring) (interactive) ; Run the parent. ((, parent)) ; Identify special modes. - (if (get (quote (, parent)) 'special) - (put (quote (, child)) 'special t)) + (if (get '(, parent) 'special) + (put '(, child) 'special t)) ; Identify the child mode. - (setq major-mode (quote (, child))) + (setq major-mode '(, child)) (setq mode-name (, name)) ; Set up maps and tables. - (derived-mode-set-keymap (quote (, child))) - (derived-mode-set-syntax-table (quote (, child))) - (derived-mode-set-abbrev-table (quote (, child))) + (derived-mode-set-keymap '(, child)) + (derived-mode-set-syntax-table '(, child)) + (derived-mode-set-abbrev-table '(, child)) ; Splice in the body (if any). (,@ body) ;;; ; Run the setup function, if ;;; ; any -- this will soon be ;;; ; obsolete. -;;; (derived-mode-run-setup-function (quote (, child))) +;;; (derived-mode-run-setup-function '(, child)) ; Run the hooks, if any. - (derived-mode-run-hooks (quote (, child))))))) + (derived-mode-run-hooks '(, child)))))) ;; PUBLIC: find the ultimate class of a derived mode. @@ -221,7 +223,10 @@ the first time the mode is used." (if (boundp (derived-mode-syntax-table-name mode)) t (eval (` (defvar (, (derived-mode-syntax-table-name mode)) - (make-vector 256 nil) + ;; Make a syntax table which doesn't specify anything + ;; for any char. Valid data will be merged in by + ;; derived-mode-merge-syntax-tables. + (make-char-table 'syntax-table nil) (, (format "Syntax table for %s." mode))))) (put (derived-mode-syntax-table-name mode) 'derived-mode-unmerged t)) @@ -255,8 +260,9 @@ which more-or-less shadow (let* ((map-name (derived-mode-map-name mode)) (new-map (eval map-name)) (old-map (current-local-map))) - (if (get map-name 'derived-mode-unmerged) - (derived-mode-merge-keymaps old-map new-map)) + (and old-map + (get map-name 'derived-mode-unmerged) + (derived-mode-merge-keymaps old-map new-map)) (put map-name 'derived-mode-unmerged nil) (use-local-map new-map))) @@ -297,19 +303,36 @@ Always merge its parent into it, since the merge is non-destructive." (defun derived-mode-merge-keymaps (old new) "Merge an old keymap into a new one. -The old keymap is set to be the cdr of the new one, so that there will +The old keymap is set to be the last cdr of the new one, so that there will be automatic inheritance." + (let ((tail new)) + ;; Scan the NEW map for prefix keys. + (while (consp tail) + (and (consp (car tail)) + (let* ((key (vector (car (car tail)))) + (subnew (lookup-key new key)) + (subold (lookup-key old key))) + ;; If KEY is a prefix key in both OLD and NEW, merge them. + (and (keymapp subnew) (keymapp subold) + (derived-mode-merge-keymaps subold subnew)))) + (and (vectorp (car tail)) + ;; Search a vector of ASCII char bindings for prefix keys. + (let ((i (1- (length (car tail))))) + (while (>= i 0) + (let* ((key (vector i)) + (subnew (lookup-key new key)) + (subold (lookup-key old key))) + ;; If KEY is a prefix key in both OLD and NEW, merge them. + (and (keymapp subnew) (keymapp subold) + (derived-mode-merge-keymaps subold subnew))) + (setq i (1- i))))) + (setq tail (cdr tail)))) (setcdr (nthcdr (1- (length new)) new) old)) (defun derived-mode-merge-syntax-tables (old new) "Merge an old syntax table into a new one. Where the new table already has an entry, nothing is copied from the old one." - (let ((idx 0) - (end (min (length new) (length old)))) - (while (< idx end) - (if (not (aref new idx)) - (aset new idx (aref old idx))) - (setq idx (1+ idx))))) + (set-char-table-parent new old)) ;; Merge an old abbrev table into a new one. ;; This function requires internal knowledge of how abbrev tables work,