diff options
| author | Noam Postavsky | 2017-11-23 21:57:09 -0500 |
|---|---|---|
| committer | Noam Postavsky | 2018-01-03 20:51:28 -0500 |
| commit | ce48658191befb7734a7af484e368af5ed8b9447 (patch) | |
| tree | b5d6988b30ce6fb135ec36abc9fb113596b9f40a | |
| parent | f8b4e87d5d4f57954b50677add76ce5136211dc1 (diff) | |
| download | emacs-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.el | 6 | ||||
| -rw-r--r-- | src/callint.c | 4 |
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. */ |