aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoam Postavsky2017-11-23 21:57:09 -0500
committerNoam Postavsky2018-01-03 20:51:28 -0500
commitce48658191befb7734a7af484e368af5ed8b9447 (patch)
treeb5d6988b30ce6fb135ec36abc9fb113596b9f40a
parentf8b4e87d5d4f57954b50677add76ce5136211dc1 (diff)
downloademacs-ce48658191befb7734a7af484e368af5ed8b9447.tar.gz
emacs-ce48658191befb7734a7af484e368af5ed8b9447.zip
Fix command repetition with lexical-binding (Bug#29334)
`call-interactively' relies on analyzing the source of `interactive' forms in order to preserve arguments like (region-end) in the command history, rather than just storing the resulting position. However, the byte-compiler does not preserve the source of the interactive form when lexical-binding is in effect, because `call-interactively' would evaluate the form with dynamic binding in that case. To fix this, change `call-interactively' so that it checks compiled functions for lexical-binding as well. Then the byte-compiler can preserve the source of interactive forms regardless of the value of lexical-binding. * src/callint.c (Fcall_interactively): Functions compiled with lexical-binding have their arglist encoded as an integer, use this to choose the right kind of binding for compiled functions too. * lisp/emacs-lisp/bytecomp.el (byte-compile-lambda): Preserve the uncompiled form of the interactive form when lexical-binding is enabled too.
-rw-r--r--lisp/emacs-lisp/bytecomp.el6
-rw-r--r--src/callint.c4
2 files changed, 4 insertions, 6 deletions
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 2f5f9f8c054..564aac2fc6a 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -2839,11 +2839,7 @@ for symbols generated by the byte compiler itself."
2839 (while (consp (cdr form)) 2839 (while (consp (cdr form))
2840 (setq form (cdr form))) 2840 (setq form (cdr form)))
2841 (setq form (car form))) 2841 (setq form (car form)))
2842 (if (and (eq (car-safe form) 'list) 2842 (if (eq (car-safe form) 'list)
2843 ;; The spec is evalled in callint.c in dynamic-scoping
2844 ;; mode, so just leaving the form unchanged would mean
2845 ;; it won't be eval'd in the right mode.
2846 (not lexical-binding))
2847 nil 2843 nil
2848 (setq int `(interactive ,newform))))) 2844 (setq int `(interactive ,newform)))))
2849 ((cdr int) 2845 ((cdr int)
diff --git a/src/callint.c b/src/callint.c
index c713e08d4d4..dcda0bcf7a0 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -357,7 +357,9 @@ invoke it. If KEYS is omitted or nil, the return value of
357 /* Compute the arg values using the user's expression. */ 357 /* Compute the arg values using the user's expression. */
358 specs = Feval (specs, 358 specs = Feval (specs,
359 CONSP (funval) && EQ (Qclosure, XCAR (funval)) 359 CONSP (funval) && EQ (Qclosure, XCAR (funval))
360 ? CAR_SAFE (XCDR (funval)) : Qnil); 360 ? CAR_SAFE (XCDR (funval))
361 : COMPILEDP (funval) && INTEGERP (AREF (funval, COMPILED_ARGLIST))
362 ? Qt : Qnil);
361 if (events != num_input_events || !NILP (record_flag)) 363 if (events != num_input_events || !NILP (record_flag))
362 { 364 {
363 /* We should record this command on the command history. */ 365 /* We should record this command on the command history. */