unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Jonas Bernoulli <jonas@bernoul.li>
To: 61179@debbugs.gnu.org
Cc: Stefan Monnier <monnier@iro.umontreal.ca>
Subject: bug#61179: lambda inside interactive form of around advice isn't a closure
Date: Mon, 30 Jan 2023 16:48:13 +0100	[thread overview]
Message-ID: <87tu082fcy.fsf@bernoul.li> (raw)

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





             reply	other threads:[~2023-01-30 15:48 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-30 15:48 Jonas Bernoulli [this message]
2023-01-31 23:33 ` bug#61179: lambda inside interactive form of around advice isn't a closure 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87tu082fcy.fsf@bernoul.li \
    --to=jonas@bernoul.li \
    --cc=61179@debbugs.gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).