diff options
| -rw-r--r-- | lisp/derived.el | 73 |
1 files changed, 52 insertions, 21 deletions
diff --git a/lisp/derived.el b/lisp/derived.el index 994509855e4..414f321552e 100644 --- a/lisp/derived.el +++ b/lisp/derived.el | |||
| @@ -126,6 +126,17 @@ DOCSTRING: an optional documentation string--if you do not supply one, | |||
| 126 | BODY: forms to execute just before running the | 126 | BODY: forms to execute just before running the |
| 127 | hooks for the new mode. Do not use `interactive' here. | 127 | hooks for the new mode. Do not use `interactive' here. |
| 128 | 128 | ||
| 129 | BODY can start with a bunch of keyword arguments. The following keyword | ||
| 130 | arguments are currently understood: | ||
| 131 | :group GROUP | ||
| 132 | Declare the customization group that corresponds to this mode. | ||
| 133 | :syntax-table TABLE | ||
| 134 | Use TABLE instead of the default. | ||
| 135 | A nil value means to simply use the same syntax-table as the parent. | ||
| 136 | :abbrev-table TABLE | ||
| 137 | Use TABLE instead of the default. | ||
| 138 | A nil value means to simply use the same abbrev-table as the parent. | ||
| 139 | |||
| 129 | Here is how you could define LaTeX-Thesis mode as a variant of LaTeX mode: | 140 | Here is how you could define LaTeX-Thesis mode as a variant of LaTeX mode: |
| 130 | 141 | ||
| 131 | (define-derived-mode LaTeX-thesis-mode LaTeX-mode \"LaTeX-Thesis\") | 142 | (define-derived-mode LaTeX-thesis-mode LaTeX-mode \"LaTeX-Thesis\") |
| @@ -155,15 +166,31 @@ been generated automatically, with a reference to the keymap." | |||
| 155 | (let ((map (derived-mode-map-name child)) | 166 | (let ((map (derived-mode-map-name child)) |
| 156 | (syntax (derived-mode-syntax-table-name child)) | 167 | (syntax (derived-mode-syntax-table-name child)) |
| 157 | (abbrev (derived-mode-abbrev-table-name child)) | 168 | (abbrev (derived-mode-abbrev-table-name child)) |
| 169 | (declare-abbrev t) | ||
| 170 | (declare-syntax t) | ||
| 158 | (hook (derived-mode-hook-name child)) | 171 | (hook (derived-mode-hook-name child)) |
| 159 | (docstring (derived-mode-make-docstring parent child docstring))) | 172 | (group nil)) |
| 173 | |||
| 174 | ;; Process the keyword args. | ||
| 175 | (while (keywordp (car body)) | ||
| 176 | (case (pop body) | ||
| 177 | (:group (setq group (pop body))) | ||
| 178 | (:abbrev-table (setq abbrev (pop body)) (setq declare-abbrev nil)) | ||
| 179 | (:syntax-table (setq syntax (pop body)) (setq declare-syntax nil)))) | ||
| 180 | |||
| 181 | |||
| 182 | (setq docstring (derived-mode-make-docstring | ||
| 183 | parent child docstring syntax abbrev)) | ||
| 160 | 184 | ||
| 161 | `(progn | 185 | `(progn |
| 162 | (defvar ,map (make-sparse-keymap)) | 186 | (defvar ,map (make-sparse-keymap)) |
| 163 | (defvar ,syntax (make-syntax-table)) | 187 | ,(if declare-syntax |
| 164 | (defvar ,abbrev | 188 | `(defvar ,syntax (make-syntax-table))) |
| 165 | (progn (define-abbrev-table ',abbrev nil) ,abbrev)) | 189 | ,(if declare-abbrev |
| 190 | `(defvar ,abbrev | ||
| 191 | (progn (define-abbrev-table ',abbrev nil) ,abbrev))) | ||
| 166 | (put ',child 'derived-mode-parent ',parent) | 192 | (put ',child 'derived-mode-parent ',parent) |
| 193 | ,(if group `(put ',child 'custom-group ,group)) | ||
| 167 | 194 | ||
| 168 | (defun ,child () | 195 | (defun ,child () |
| 169 | ,docstring | 196 | ,docstring |
| @@ -184,20 +211,25 @@ been generated automatically, with a reference to the keymap." | |||
| 184 | ; Set up maps and tables. | 211 | ; Set up maps and tables. |
| 185 | (unless (keymap-parent ,map) | 212 | (unless (keymap-parent ,map) |
| 186 | (set-keymap-parent ,map (current-local-map))) | 213 | (set-keymap-parent ,map (current-local-map))) |
| 187 | (let ((parent (char-table-parent ,syntax))) | 214 | ,(when declare-syntax |
| 188 | (unless (and parent (not (eq parent (standard-syntax-table)))) | 215 | `(let ((parent (char-table-parent ,syntax))) |
| 189 | (set-char-table-parent ,syntax (syntax-table)))) | 216 | (unless (and parent |
| 190 | (when local-abbrev-table | 217 | (not (eq parent (standard-syntax-table)))) |
| 191 | (mapatoms | 218 | (set-char-table-parent ,syntax (syntax-table))))) |
| 192 | (lambda (symbol) | 219 | ,(when declare-abbrev |
| 193 | (or (intern-soft (symbol-name symbol) ,abbrev) | 220 | `(when local-abbrev-table |
| 194 | (define-abbrev ,abbrev (symbol-name symbol) | 221 | (mapatoms |
| 195 | (symbol-value symbol) (symbol-function symbol)))) | 222 | (lambda (symbol) |
| 196 | local-abbrev-table)))) | 223 | (or (intern-soft (symbol-name symbol) ,abbrev) |
| 224 | (define-abbrev ,abbrev | ||
| 225 | (symbol-name symbol) | ||
| 226 | (symbol-value symbol) | ||
| 227 | (symbol-function symbol)))) | ||
| 228 | local-abbrev-table))))) | ||
| 197 | 229 | ||
| 198 | (use-local-map ,map) | 230 | (use-local-map ,map) |
| 199 | (set-syntax-table ,syntax) | 231 | ,(when syntax `(set-syntax-table ,syntax)) |
| 200 | (setq local-abbrev-table ,abbrev) | 232 | ,(when abbrev `(setq local-abbrev-table ,abbrev)) |
| 201 | ; Splice in the body (if any). | 233 | ; Splice in the body (if any). |
| 202 | ,@body | 234 | ,@body |
| 203 | ) | 235 | ) |
| @@ -220,12 +252,11 @@ is not very useful." | |||
| 220 | 252 | ||
| 221 | ;;; PRIVATE | 253 | ;;; PRIVATE |
| 222 | 254 | ||
| 223 | (defun derived-mode-make-docstring (parent child &optional docstring) | 255 | (defun derived-mode-make-docstring (parent child &optional |
| 256 | docstring syntax abbrev) | ||
| 224 | "Construct a docstring for a new mode if none is provided." | 257 | "Construct a docstring for a new mode if none is provided." |
| 225 | 258 | ||
| 226 | (let ((map (derived-mode-map-name child)) | 259 | (let ((map (derived-mode-map-name child)) |
| 227 | (syntax (derived-mode-syntax-table-name child)) | ||
| 228 | (abbrev (derived-mode-abbrev-table-name child)) | ||
| 229 | (hook (derived-mode-hook-name child))) | 260 | (hook (derived-mode-hook-name child))) |
| 230 | 261 | ||
| 231 | (unless (stringp docstring) | 262 | (unless (stringp docstring) |
| @@ -244,7 +275,7 @@ which more-or-less shadow %s's corresponding tables." | |||
| 244 | parent map abbrev syntax parent)))) | 275 | parent map abbrev syntax parent)))) |
| 245 | 276 | ||
| 246 | (unless (string-match (regexp-quote (symbol-name hook)) docstring) | 277 | (unless (string-match (regexp-quote (symbol-name hook)) docstring) |
| 247 | ;; Make sure the docstring mentions the mode's hook | 278 | ;; Make sure the docstring mentions the mode's hook. |
| 248 | (setq docstring | 279 | (setq docstring |
| 249 | (concat docstring | 280 | (concat docstring |
| 250 | (if (null parent) | 281 | (if (null parent) |
| @@ -259,7 +290,7 @@ which more-or-less shadow %s's corresponding tables." | |||
| 259 | ", as the final step\nduring initialization."))) | 290 | ", as the final step\nduring initialization."))) |
| 260 | 291 | ||
| 261 | (unless (string-match "\\\\[{[]" docstring) | 292 | (unless (string-match "\\\\[{[]" docstring) |
| 262 | ;; And don't forget to put the mode's keymap | 293 | ;; And don't forget to put the mode's keymap. |
| 263 | (setq docstring (concat docstring "\n\n\\{" (symbol-name map) "}"))) | 294 | (setq docstring (concat docstring "\n\n\\{" (symbol-name map) "}"))) |
| 264 | 295 | ||
| 265 | docstring)) | 296 | docstring)) |