diff options
| author | Richard M. Stallman | 1994-02-12 02:27:29 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-02-12 02:27:29 +0000 |
| commit | 26757b4b031111f8e8ae9f1912b457cd17daba9a (patch) | |
| tree | 3b1d173eba7d486ca1214a0571383fbffd6a28e6 | |
| parent | 382d3536baea95fa2200e8597d52340abb6a3967 (diff) | |
| download | emacs-26757b4b031111f8e8ae9f1912b457cd17daba9a.tar.gz emacs-26757b4b031111f8e8ae9f1912b457cd17daba9a.zip | |
(clone-init-mode-variables): Don't defvar
variables if already bound. Put on clone-unmerged props if
they were not bound.
(clone-make-docstring): Install the map unconditionally;
set clone-unmerged property to nil. No clone-merged property.
(clone-set-syntax-table): Set clone-unmerged prop, not clone-merged.
(clone-set-abbrev-table): Call clone-merge-abbrev-tables.
Don't touch properties here.
(clone-merge-keymaps): Splice out the `keymap' of the OLD map.
(clone-merge-abbrev-tables): New function.
| -rw-r--r-- | lisp/derived.el | 101 |
1 files changed, 64 insertions, 37 deletions
diff --git a/lisp/derived.el b/lisp/derived.el index 3a89407749f..ead5ce532e4 100644 --- a/lisp/derived.el +++ b/lisp/derived.el | |||
| @@ -1,8 +1,9 @@ | |||
| 1 | ;;; mode-clone.el (alpha version) -- allow inheritance of major modes. | 1 | ;;; mode-clone.el -- allow inheritance of major modes. |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1993 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1993, 1994 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: David Megginson (dmeggins@aix1.uottawa.ca) | 5 | ;; Author: David Megginson (dmeggins@aix1.uottawa.ca) |
| 6 | ;; Maintainer: FSF | ||
| 6 | 7 | ||
| 7 | ;; This file is part of GNU Emacs. | 8 | ;; This file is part of GNU Emacs. |
| 8 | 9 | ||
| @@ -60,8 +61,9 @@ | |||
| 60 | ;; - replace the current syntax table with | 61 | ;; - replace the current syntax table with |
| 61 | ;; 'hypertext-mode-syntax-table', which will borrow its defaults | 62 | ;; 'hypertext-mode-syntax-table', which will borrow its defaults |
| 62 | ;; from the current text-mode-syntax-table. | 63 | ;; from the current text-mode-syntax-table. |
| 63 | ;; - if 'hypertext-mode-abbrev-table' exists, it will become the | 64 | ;; - replace the current abbrev table with |
| 64 | ;; current abbrev table. | 65 | ;; 'hypertext-mode-abbrev-table', which will borrow its defaults |
| 66 | ;; from the current text-mode-abbrev table | ||
| 65 | ;; - change the mode line to read "Hypertext" | 67 | ;; - change the mode line to read "Hypertext" |
| 66 | ;; - assign the value 'hypertext-mode' to the 'major-mode' variable | 68 | ;; - assign the value 'hypertext-mode' to the 'major-mode' variable |
| 67 | ;; - run the body of commands provided in the macro -- in this case, | 69 | ;; - run the body of commands provided in the macro -- in this case, |
| @@ -203,23 +205,31 @@ Use the `clone-parent' property of the symbol to trace backwards." | |||
| 203 | ;; Utility functions for defining a clone mode. | 205 | ;; Utility functions for defining a clone mode. |
| 204 | 206 | ||
| 205 | (defun clone-init-mode-variables (mode) | 207 | (defun clone-init-mode-variables (mode) |
| 206 | "Initialise variables for a new mode. | 208 | "Initialise variables for a new mode. |
| 207 | Right now, just set up a blank keymap and an empty syntax table." | 209 | Right now, if they don't already exist, set up a blank keymap, an |
| 208 | 210 | empty syntax table, and an empty abbrev table -- these will be merged | |
| 209 | (eval (` (defvar (, (clone-map-name mode)) | 211 | the first time the mode is used." |
| 210 | (make-sparse-keymap) | 212 | |
| 211 | (, (format "Keymap for %s." mode))))) | 213 | (if (boundp (clone-map-name mode)) |
| 212 | (put (clone-map-name mode) 'clone-merged nil) | 214 | t |
| 213 | 215 | (eval (` (defvar (, (clone-map-name mode)) | |
| 214 | (eval (` (defvar (, (clone-syntax-table-name mode)) | 216 | (make-sparse-keymap) |
| 215 | (make-vector 256 nil) | 217 | (, (format "Keymap for %s." mode))))) |
| 216 | (, (format "Syntax table for %s." mode))))) | 218 | (put (clone-map-name mode) 'clone-unmerged t)) |
| 217 | (put (clone-syntax-table-name mode) 'clone-merged nil) | 219 | |
| 218 | 220 | (if (boundp (clone-syntax-table-name mode)) | |
| 219 | (eval (` (defvar (, (clone-abbrev-table-name mode)) | 221 | t |
| 220 | nil | 222 | (eval (` (defvar (, (clone-syntax-table-name mode)) |
| 221 | (, (format "Abbrev table for %s." mode))))) | 223 | (make-vector 256 nil) |
| 222 | (define-abbrev-table (clone-abbrev-table-name mode) ())) | 224 | (, (format "Syntax table for %s." mode))))) |
| 225 | (put (clone-syntax-table-name mode) 'clone-unmerged t)) | ||
| 226 | |||
| 227 | (if (boundp (clone-abbrev-table-name mode)) | ||
| 228 | t | ||
| 229 | (eval (` (defvar (, (clone-abbrev-table-name mode)) | ||
| 230 | (progn (define-abbrev-table (clone-abbrev-table-name mode) nil) | ||
| 231 | (make-abbrev-table)) | ||
| 232 | (, (format "Abbrev table for %s." mode))))))) | ||
| 223 | 233 | ||
| 224 | (defun clone-make-docstring (parent child) | 234 | (defun clone-make-docstring (parent child) |
| 225 | "Construct a docstring for a new mode if none is provided." | 235 | "Construct a docstring for a new mode if none is provided." |
| @@ -244,28 +254,29 @@ which more-or-less shadow | |||
| 244 | (let* ((map-name (clone-map-name mode)) | 254 | (let* ((map-name (clone-map-name mode)) |
| 245 | (new-map (eval map-name)) | 255 | (new-map (eval map-name)) |
| 246 | (old-map (current-local-map))) | 256 | (old-map (current-local-map))) |
| 247 | (if (get map-name 'clone-merged) | 257 | (if (get map-name 'clone-unmerged) |
| 248 | (use-local-map new-map) | 258 | (clone-merge-keymaps old-map new-map)) |
| 249 | (put map-name 'clone-merged t) | 259 | (put map-name 'clone-unmerged nil) |
| 250 | (use-local-map (set map-name (clone-merge-keymaps old-map new-map)))))) | 260 | (use-local-map new-map))) |
| 251 | 261 | ||
| 252 | (defun clone-set-syntax-table (mode) | 262 | (defun clone-set-syntax-table (mode) |
| 253 | "Set the syntax table of the new mode, maybe merging with the parent." | 263 | "Set the syntax table of the new mode, maybe merging with the parent." |
| 254 | (let* ((table-name (clone-syntax-table-name mode)) | 264 | (let* ((table-name (clone-syntax-table-name mode)) |
| 255 | (old-table (syntax-table)) | 265 | (old-table (syntax-table)) |
| 256 | (new-table (eval table-name))) | 266 | (new-table (eval table-name))) |
| 257 | (if (get table-name 'clone-merged) | 267 | (if (get table-name 'clone-unmerged) |
| 258 | t | 268 | (clone-merge-syntax-tables old-table new-table)) |
| 259 | (clone-merge-syntax-tables old-table new-table)) | 269 | (put table-name 'clone-unmerged nil) |
| 260 | (set-syntax-table new-table) | 270 | (set-syntax-table new-table))) |
| 261 | (put table-name 'clone-merged t))) | ||
| 262 | 271 | ||
| 263 | (defun clone-set-abbrev-table (mode) | 272 | (defun clone-set-abbrev-table (mode) |
| 264 | "Set the abbrev table if it exists." | 273 | "Set the abbrev table if it exists. |
| 274 | Always merge its parent into it, since the merge is non-destructive." | ||
| 265 | (let* ((table-name (clone-abbrev-table-name mode)) | 275 | (let* ((table-name (clone-abbrev-table-name mode)) |
| 266 | (table (and (boundp table-name) (eval table-name)))) | 276 | (old-table local-abbrev-table) |
| 267 | (if table | 277 | (new-table (eval table-name))) |
| 268 | (setq local-abbrev-table table)))) | 278 | (clone-merge-abbrev-tables old-table new-table) |
| 279 | (setq local-abbrev-table new-table))) | ||
| 269 | 280 | ||
| 270 | ;;;(defun clone-run-setup-function (mode) | 281 | ;;;(defun clone-run-setup-function (mode) |
| 271 | ;;; "Run the setup function if it exists." | 282 | ;;; "Run the setup function if it exists." |
| @@ -284,13 +295,13 @@ which more-or-less shadow | |||
| 284 | ;; Functions to merge maps and tables. | 295 | ;; Functions to merge maps and tables. |
| 285 | 296 | ||
| 286 | (defun clone-merge-keymaps (old new) | 297 | (defun clone-merge-keymaps (old new) |
| 287 | "Merge a new keymap into an old one. | 298 | "Merge an old keymap into a new one. |
| 288 | The old keymap is set to be the cdr of the new one, so that there will | 299 | The old keymap is set to be the cdr of the new one, so that there will |
| 289 | be automatic inheritance." | 300 | be automatic inheritance." |
| 290 | (append new old)) | 301 | (setcdr (nthcdr (1- (length new)) new) old)) |
| 291 | 302 | ||
| 292 | (defun clone-merge-syntax-tables (old new) | 303 | (defun clone-merge-syntax-tables (old new) |
| 293 | "Merge a new syntax table into an old one. | 304 | "Merge an old syntax table into a new one. |
| 294 | Where the new table already has an entry, nothing is copied from the old one." | 305 | Where the new table already has an entry, nothing is copied from the old one." |
| 295 | (let ((idx 0) | 306 | (let ((idx 0) |
| 296 | (end (min (length new) (length old)))) | 307 | (end (min (length new) (length old)))) |
| @@ -298,7 +309,23 @@ Where the new table already has an entry, nothing is copied from the old one." | |||
| 298 | (if (not (aref new idx)) | 309 | (if (not (aref new idx)) |
| 299 | (aset new idx (aref old idx))) | 310 | (aset new idx (aref old idx))) |
| 300 | (setq idx (1+ idx))))) | 311 | (setq idx (1+ idx))))) |
| 312 | |||
| 313 | (defun clone-merge-abbrev-tables (old new) | ||
| 314 | "Merge an old abbrev table into a new one. | ||
| 315 | This function requires internal knowledge of how abbrev tables work, | ||
| 316 | presuming that they are obarrays with the abbrev as the symbol, the expansion | ||
| 317 | as the value of the symbol, and the hook as the function definition. | ||
| 318 | This could well break with some future version of Gnu Emacs." | ||
| 319 | (mapatoms | ||
| 320 | (function | ||
| 321 | (lambda (symbol) | ||
| 322 | (or (intern-soft (symbol-name symbol) new) | ||
| 323 | (define-abbrev new (symbol-name symbol) | ||
| 324 | (symbol-value symbol) (symbol-function symbol))))) | ||
| 325 | old)) | ||
| 301 | 326 | ||
| 302 | (provide 'mode-clone) | 327 | (provide 'mode-clone) |
| 303 | 328 | ||
| 304 | ;;; mode-clone.el ends here | 329 | ;;; mode-clone.el ends here |
| 330 | |||
| 331 | |||