diff options
author | Phil Sainty <psainty@orcon.net.nz> | 2019-04-22 18:14:55 +1200 |
---|---|---|
committer | Phil Sainty <psainty@orcon.net.nz> | 2019-04-22 18:14:55 +1200 |
commit | 196b9760e3218c19478628213796900e35fffb74 (patch) | |
tree | ae74954d42c3cfcf4dc5a25636ca208d3919075f | |
parent | e85bff0bbb60e1d819f8f5e00f8496026f27f7ea (diff) | |
download | emacs-196b9760e3218c19478628213796900e35fffb74.tar.gz |
Add :before-hook keyword to define-derived-mode
* lisp/emacs-lisp/derived.el (define-derived-mode): New keyword
* doc/lispref/modes.texi: Update "(elisp) Derived Modes"
* etc/NEWS: Include under "Lisp Changes in Emacs 27.1"
-rw-r--r-- | doc/lispref/modes.texi | 12 | ||||
-rw-r--r-- | etc/NEWS | 6 | ||||
-rw-r--r-- | lisp/emacs-lisp/derived.el | 8 |
3 files changed, 24 insertions, 2 deletions
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 4315b70ed72..925017dbc0c 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -807,8 +807,8 @@ documentation string. If you omit @var{docstring}, @code{define-derived-mode} generates a documentation string. The @var{keyword-args} are pairs of keywords and values. The values, -except for @code{:after-hook}'s, are evaluated. The following -keywords are currently supported: +except for those of @code{:before-hook} and @code{:after-hook}, are +evaluated. The following keywords are currently supported: @table @code @item :syntax-table @@ -832,6 +832,14 @@ this mode. (Not all major modes have one.) The command @code{customize-mode} uses this. @code{define-derived-mode} does @emph{not} automatically define the specified customization group. +@item :before-hook +This optional keyword specifies a single Lisp form to evaluate as the +very first act of the mode function, before any of the functions in +@code{change-major-mode-hook} have been called. It should not be +quoted. A @code{:before-hook} form is useful when the mode needs to +see the original buffer state, before @code{kill-all-local-variables} +has taken effect. + @item :after-hook This optional keyword specifies a single Lisp form to evaluate as the final act of the mode function, after the mode hooks have been run. @@ -1633,6 +1633,12 @@ The function now returns non-nil when the argument MODE is derived from any alias of any of MODES. +++ +** 'define-derived-mode' can now specify a :before-hook form, which +is evaluated before the 'change-major-mode-hook' functions. This allows +the macro to be used to define mode functions which need to act before +'kill-all-local-variables'. + ++++ ** New frame focus state inspection interface. The hooks 'focus-in-hook' and 'focus-out-hook' are now obsolete. Instead, attach to 'after-focus-change-function' using 'add-function' diff --git a/lisp/emacs-lisp/derived.el b/lisp/emacs-lisp/derived.el index 6db0584b987..00aa70a10aa 100644 --- a/lisp/emacs-lisp/derived.el +++ b/lisp/emacs-lisp/derived.el @@ -137,6 +137,9 @@ BODY can start with a bunch of keyword arguments. The following keyword :abbrev-table TABLE Use TABLE instead of the default (CHILD-abbrev-table). A nil value means to simply use the same abbrev-table as the parent. +:before-hook FORM + A single lisp form which will be evaluated before anything else + happens in `change-major-mode-hook'. It should not be quoted. :after-hook FORM A single lisp form which is evaluated after the mode hooks have been run. It should not be quoted. @@ -188,6 +191,7 @@ See Info node `(elisp)Derived Modes' for more details." (declare-syntax t) (hook (derived-mode-hook-name child)) (group nil) + (before-hook nil) (after-hook nil)) ;; Process the keyword args. @@ -196,6 +200,7 @@ See Info node `(elisp)Derived Modes' for more details." (:group (setq group (pop body))) (:abbrev-table (setq abbrev (pop body)) (setq declare-abbrev nil)) (:syntax-table (setq syntax (pop body)) (setq declare-syntax nil)) + (:before-hook (setq before-hook (pop body))) (:after-hook (setq after-hook (pop body))) (_ (pop body)))) @@ -241,6 +246,9 @@ No problems result if this variable is not bound. (defun ,child () ,docstring (interactive) + ,@(when before-hook + `((add-hook 'change-major-mode-hook (lambda () ,before-hook) + nil t))) ; Run the parent. (delay-mode-hooks |