unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#61179: lambda inside interactive form of around advice isn't a closure
@ 2023-01-30 15:48 Jonas Bernoulli
  2023-01-31 23:33 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-02-04 16:26 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 13+ messages in thread
From: Jonas Bernoulli @ 2023-01-30 15:48 UTC (permalink / raw)
  To: 61179; +Cc: Stefan Monnier

A function used as an around advice may advise the advised function's
interactive form, using (interactive (lambda (spec) ...)).

Unfortunately this inner lambda expression is not turned into a closure
as demonstrated by this simple example:

  ;; -*- lexical-binding: t -*-
  (let ((var :value))
    (lambda (fn &rest args)
      (interactive
       (lambda (spec)
         (message "interactive: %s" var)
         (advice-eval-interactive-spec spec)))
      (message "body: %s" var)
      (apply fn args)))

Or if you want to observe the failure when trying to use such an advice:

  (defun -make-advice ()
    (let ((var :value))
      (lambda (fn &rest args)
        (interactive
         (lambda (spec)
           (message "interactive: %s" var)
           (advice-eval-interactive-spec spec)))
        (message "body: %s" var)
        (apply fn args))))

  (defun -command (arg)
    (interactive (list (read-string ": "))))
  (advice-add '-command :around (-make-advice) '((name . "-advice")))

Could this be changed in the next Emacs release?  Even if this should
make it into 29.1 (which I doubt), it would still be very useful for me
if this could somehow be rewritten to also work in older Emacs releases.
I have tried throwing an eval or two in there, but with limited success.

This gives me an inner closure, but the outside closure does not capture
the same environment it seems:

  (let ((var :value))
    (eval `(lambda (fn &rest args)
             (interactive
              ,(lambda (spec)
                 (message "interactive: %s" var)
                 (advice-eval-interactive-spec spec)))
             (message "body: %s" var)
             (apply fn args))
          t))

I got desperate and also tried things like:

  (call-interactively
   (let ((lex '((var . :value))))
     (eval `(lambda ()
              (interactive
               ,(eval '(lambda (spec)
                        (message "interactive: %s" var)
                        nil)
                      lex))
              (message "body: %s" var))
           lex)))

Thanks for your help!
Jonas





^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2023-02-08 14:38 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-30 15:48 bug#61179: lambda inside interactive form of around advice isn't a closure Jonas Bernoulli
2023-01-31 23:33 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-01  1:33   ` Jonas Bernoulli
2023-02-01 22:34     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-02 14:39       ` Jonas Bernoulli
2023-02-01 22:29   ` Jonas Bernoulli
2023-02-04 16:26 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-04 23:47   ` Michael Heerdegen
2023-02-05 14:05     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 22:23       ` Michael Heerdegen
2023-02-05 16:43   ` Jonas Bernoulli
2023-02-05 18:54     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-08 14:38   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).