comparison lisp/emacs-lisp/easy-mmode.el @ 28235:963f1d516e92

* derived.el (define-derived-mode): Don't autoload anymore. Prefer the macro-only version provided by easy-mmode.el. * emacs-lisp/easy-mmode.el (define-derived-mode): New name for `easy-mmode-define-derived-mode'. Use `combine-run-hooks'. (easy-mmode-define-navigation): New macro.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Tue, 21 Mar 2000 15:34:31 +0000
parents 9ff6e6a6c6b5
children 21cd65af5197
comparison
equal deleted inserted replaced
28234:763c6639628b 28235:963f1d516e92
234 (autoload 'easy-mmode-define-syntax "easy-mmode") 234 (autoload 'easy-mmode-define-syntax "easy-mmode")
235 (defconst ,st (easy-mmode-define-syntax ,css ,(cons 'list args)) doc))) 235 (defconst ,st (easy-mmode-define-syntax ,css ,(cons 'list args)) doc)))
236 236
237 237
238 238
239 ;;;
239 ;;; A "macro-only" reimplementation of define-derived-mode. 240 ;;; A "macro-only" reimplementation of define-derived-mode.
240 241 ;;;
241 (defmacro easy-mmode-define-derived-mode (child parent name &optional docstring &rest body) 242
243 (defalias 'easy-mmode-define-derived-mode 'define-derived-mode)
244 ;;;###autoload
245 (defmacro define-derived-mode (child parent name &optional docstring &rest body)
242 "Create a new mode as a variant of an existing mode. 246 "Create a new mode as a variant of an existing mode.
243 247
244 The arguments to this command are as follow: 248 The arguments to this command are as follow:
245 249
246 CHILD: the name of the command for the derived mode. 250 CHILD: the name of the command for the derived mode.
310 314
311 (defun ,child () 315 (defun ,child ()
312 ,docstring 316 ,docstring
313 (interactive) 317 (interactive)
314 ; Run the parent. 318 ; Run the parent.
315 (,parent) 319 (combine-run-hooks
320
321 (,parent)
316 ; Identify special modes. 322 ; Identify special modes.
317 (put ',child 'special (get ',parent 'special)) 323 (put ',child 'special (get ',parent 'special))
318 ; Identify the child mode. 324 ; Identify the child mode.
319 (setq major-mode ',child) 325 (setq major-mode ',child)
320 (setq mode-name ,name) 326 (setq mode-name ,name)
321 ; Set up maps and tables. 327 ; Set up maps and tables.
322 (unless (keymap-parent ,map) 328 (unless (keymap-parent ,map)
323 (set-keymap-parent ,map (current-local-map))) 329 (set-keymap-parent ,map (current-local-map)))
324 (let ((parent (char-table-parent ,syntax))) 330 (let ((parent (char-table-parent ,syntax)))
325 (unless (and parent (not (eq parent (standard-syntax-table)))) 331 (unless (and parent (not (eq parent (standard-syntax-table))))
326 (set-char-table-parent ,syntax (syntax-table)))) 332 (set-char-table-parent ,syntax (syntax-table))))
327 (when local-abbrev-table 333 (when local-abbrev-table
328 (mapatoms 334 (mapatoms
329 (lambda (symbol) 335 (lambda (symbol)
330 (or (intern-soft (symbol-name symbol) ,abbrev) 336 (or (intern-soft (symbol-name symbol) ,abbrev)
331 (define-abbrev ,abbrev (symbol-name symbol) 337 (define-abbrev ,abbrev (symbol-name symbol)
332 (symbol-value symbol) (symbol-function symbol)))) 338 (symbol-value symbol) (symbol-function symbol))))
333 local-abbrev-table)) 339 local-abbrev-table))
334 340
335 (use-local-map ,map) 341 (use-local-map ,map)
336 (set-syntax-table ,syntax) 342 (set-syntax-table ,syntax)
337 (setq local-abbrev-table ,abbrev) 343 (setq local-abbrev-table ,abbrev)
338 ; Splice in the body (if any). 344 ; Splice in the body (if any).
339 ,@body 345 ,@body)
340 ; Run the hooks, if any. 346 ; Run the hooks, if any.
341 (run-hooks ',hook))))) 347 (run-hooks ',hook)))))
342 348
349
350 ;;;
351 ;;; easy-mmode-define-navigation
352 ;;;
353
354 (defmacro easy-mmode-define-navigation (base re &optional name endfun)
355 "Define BASE-next and BASE-prev to navigate in the buffer.
356 RE determines the places the commands should move point to.
357 NAME should describe the entities matched by RE and is used to build
358 the docstrings of the two functions.
359 BASE-next also tries to make sure that the whole entry is visible by
360 searching for its end (by calling ENDFUN if provided or by looking for
361 the next entry) and recentering if necessary.
362 ENDFUN should return the end position (with or without moving point)."
363 (let* ((base-name (symbol-name base))
364 (prev-sym (intern (concat base-name "-prev")))
365 (next-sym (intern (concat base-name "-next"))))
366 `(progn
367 (defun ,next-sym (&optional count)
368 ,(format "Go to the next COUNT'th %s." (or name base-name))
369 (interactive)
370 (unless count (setq count 1))
371 (if (< count 0) (,prev-sym (- count))
372 (if (looking-at ,re) (incf count))
373 (or (re-search-forward ,re nil t count) (ding))
374 (goto-char (match-beginning 0))
375 (when (eq (current-buffer) (window-buffer (selected-window)))
376 (let ((endpt (or (save-excursion
377 ,(if endfun `(,endfun)
378 `(re-search-forward ,re nil t 2)))
379 (point-max))))
380 (unless (<= endpt (window-end)) (recenter))))))
381 (defun ,prev-sym (&optional count)
382 ,(format "Go to the previous COUNT'th %s" (or name base-name))
383 (interactive)
384 (unless count (setq count 1))
385 (if (< count 0) (,next-sym (- count))
386 (or (re-search-backward ,re nil t count) (ding)))))))
343 387
344 (provide 'easy-mmode) 388 (provide 'easy-mmode)
345 389
346 ;;; easy-mmode.el ends here 390 ;;; easy-mmode.el ends here