aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2017-12-18 11:39:17 -0500
committerStefan Monnier2017-12-18 11:39:17 -0500
commit07b7fb98e6f980bae3dd15375dc8603b7e9cb61c (patch)
tree02ca537df778ebd7b143ea002e12693bd0cf3ccc
parenta5b0a4e29243d3cf91e2b5cd365ae9ce0ae48726 (diff)
downloademacs-07b7fb98e6f980bae3dd15375dc8603b7e9cb61c.tar.gz
emacs-07b7fb98e6f980bae3dd15375dc8603b7e9cb61c.zip
* lisp/subr.el (delayed-after-hook-functions): Rename from ...-forms
(run-mode-hooks): `funcall` the functions instead of `eval`ing the forms. * lisp/emacs-lisp/derived.el (define-derived-mode): Push functions rather than forms (bug#29679).
-rw-r--r--lisp/emacs-lisp/derived.el2
-rw-r--r--lisp/subr.el12
-rw-r--r--test/lisp/emacs-lisp/derived-tests.el44
3 files changed, 51 insertions, 7 deletions
diff --git a/lisp/emacs-lisp/derived.el b/lisp/emacs-lisp/derived.el
index 751291afa88..c0ef199424b 100644
--- a/lisp/emacs-lisp/derived.el
+++ b/lisp/emacs-lisp/derived.el
@@ -285,7 +285,7 @@ No problems result if this variable is not bound.
285 (run-mode-hooks ',hook) 285 (run-mode-hooks ',hook)
286 ,@(when after-hook 286 ,@(when after-hook
287 `((if delay-mode-hooks 287 `((if delay-mode-hooks
288 (push ',after-hook delayed-after-hook-forms) 288 (push (lambda () ,after-hook) delayed-after-hook-functions)
289 ,after-hook))))))) 289 ,after-hook)))))))
290 290
291;; PUBLIC: find the ultimate class of a derived mode. 291;; PUBLIC: find the ultimate class of a derived mode.
diff --git a/lisp/subr.el b/lisp/subr.el
index 6db3b614d6d..64521711b7a 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1844,10 +1844,10 @@ if it is empty or a duplicate."
1844(make-variable-buffer-local 'delayed-mode-hooks) 1844(make-variable-buffer-local 'delayed-mode-hooks)
1845(put 'delay-mode-hooks 'permanent-local t) 1845(put 'delay-mode-hooks 'permanent-local t)
1846 1846
1847(defvar delayed-after-hook-forms nil 1847(defvar delayed-after-hook-functions nil
1848 "List of delayed :after-hook forms waiting to be run. 1848 "List of delayed :after-hook forms waiting to be run.
1849These forms come from `define-derived-mode'.") 1849These forms come from `define-derived-mode'.")
1850(make-variable-buffer-local 'delayed-after-hook-forms) 1850(make-variable-buffer-local 'delayed-after-hook-functions)
1851 1851
1852(defvar change-major-mode-after-body-hook nil 1852(defvar change-major-mode-after-body-hook nil
1853 "Normal hook run in major mode functions, before the mode hooks.") 1853 "Normal hook run in major mode functions, before the mode hooks.")
@@ -1865,7 +1865,7 @@ just adds the HOOKS to the list `delayed-mode-hooks'.
1865Otherwise, runs hooks in the sequence: `change-major-mode-after-body-hook', 1865Otherwise, runs hooks in the sequence: `change-major-mode-after-body-hook',
1866`delayed-mode-hooks' (in reverse order), HOOKS, then runs 1866`delayed-mode-hooks' (in reverse order), HOOKS, then runs
1867`hack-local-variables', runs the hook `after-change-major-mode-hook', and 1867`hack-local-variables', runs the hook `after-change-major-mode-hook', and
1868finally evaluates the forms in `delayed-after-hook-forms' (see 1868finally evaluates the functions in `delayed-after-hook-functions' (see
1869`define-derived-mode'). 1869`define-derived-mode').
1870 1870
1871Major mode functions should use this instead of `run-hooks' when 1871Major mode functions should use this instead of `run-hooks' when
@@ -1882,9 +1882,9 @@ running their FOO-mode-hook."
1882 (with-demoted-errors "File local-variables error: %s" 1882 (with-demoted-errors "File local-variables error: %s"
1883 (hack-local-variables 'no-mode))) 1883 (hack-local-variables 'no-mode)))
1884 (run-hooks 'after-change-major-mode-hook) 1884 (run-hooks 'after-change-major-mode-hook)
1885 (dolist (form (nreverse delayed-after-hook-forms)) 1885 (dolist (fun (nreverse delayed-after-hook-functions))
1886 (eval form)) 1886 (funcall fun))
1887 (setq delayed-after-hook-forms nil))) 1887 (setq delayed-after-hook-functions nil)))
1888 1888
1889(defmacro delay-mode-hooks (&rest body) 1889(defmacro delay-mode-hooks (&rest body)
1890 "Execute BODY, but delay any `run-mode-hooks'. 1890 "Execute BODY, but delay any `run-mode-hooks'.
diff --git a/test/lisp/emacs-lisp/derived-tests.el b/test/lisp/emacs-lisp/derived-tests.el
new file mode 100644
index 00000000000..adea102a78e
--- /dev/null
+++ b/test/lisp/emacs-lisp/derived-tests.el
@@ -0,0 +1,44 @@
1;;; gv-tests.el --- tests for gv.el -*- lexical-binding: t; -*-
2
3;; Copyright (C) 2017 Free Software Foundation, Inc.
4
5;; This file is part of GNU Emacs.
6
7;; GNU Emacs is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation, either version 3 of the License, or
10;; (at your option) any later version.
11
12;; GNU Emacs is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
19
20;;; Code:
21
22(require 'ert)
23(eval-when-compile (require 'cl-lib))
24
25(define-derived-mode derived-tests--parent-mode prog-mode "P"
26 :after-hook
27 (let ((f (let ((x "S")) (lambda () x))))
28 (insert (format "AFP=%s " (let ((x "D")) (funcall f)))))
29 (insert "PB "))
30
31(define-derived-mode derived-tests--child-mode derived-tests--parent-mode "C"
32 :after-hook
33 (let ((f (let ((x "S")) (lambda () x))))
34 (insert (format "AFC=%s " (let ((x "D")) (funcall f)))))
35 (insert "CB "))
36
37(ert-deftest derived-tests-after-hook-lexical ()
38 (with-temp-buffer
39 (let ((derived-tests--child-mode-hook
40 (lambda () (insert "MH "))))
41 (derived-tests--child-mode)
42 (should (equal (buffer-string) "PB CB MH AFP=S AFC=S ")))))
43
44;;; gv-tests.el ends here