bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec


From: Štěpán Němec
Subject: bug#17871: 24.4.50; (elisp) `Core Advising Primitives': interactive spec as function?
Date: Mon, 05 Aug 2019 10:44:19 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

On Mon, 05 Aug 2019 08:26:03 +0200
Michael Heerdegen wrote:

> [...] the following typical use cases:
>
> (1) Changing how input is read for a single command.  Štěpán's example
> is such a thing.  Make individual commands use helm or ido or icicles,
> or single command not use helm or ido or icicles although the according
> mode is turned on, is a use case.
>
> (2) Enhance a command to accept an additional argument.  The interactive
> form of the :around advice will reuse the interactive form of the
> original command to read in the arguments the original command accepts,
> read in the additional argument, and return the combined list.
>
> (3) Make input reading saver: If certain input for a command is
> potentially dangerous or error-prone, one could change it to add tests/
> ask for confirmation, or run it in a loop y (confirm) n (abort) r
> (retry, give new input).

Thank you for the write-up! I for one would really appreciate if all of
that went into the manual, ideally with examples (not only one). I was
now able to simplify my originally overcomplicated real-life example to
the following, but it wasn't as easy as I would have liked back then to
figure it out perusing the existing documentation (I had to look at the
code as well):

Say you use `ivy-mode' for minibuffer completion, as well as
`ivy-prescient-mode' from the `prescient' package, which modifies the
way ivy sorts completion candidates. But there is a command `my-command'
where `ivy-prescient-mode' really gets in the way instead of helping, so
you want to disable it for that single command. Unfortunately, the
following naïve version does not work:

(defun my-no-prescient-advice (orig &rest args)
  (let ((enabled ivy-prescient-mode))
    (unwind-protect
        (progn (when enabled (ivy-prescient-mode -1))
               (apply orig args))
      (when enabled (ivy-prescient-mode 1)))))

(advice-add 'my-command :around #'my-no-prescient-advice)

because it has no effect on the `interactive' form of `my-command' [BTW,
I find this very strange, so if that's really a feature it should IMO be
mentioned prominently in the documentation].

You have to do something like the following instead:

(defun my-no-prescient-advice (orig &rest args)
  (interactive (lambda (spec)
                 (let ((enabled ivy-prescient-mode))
                   (unwind-protect
                       (progn (when enabled (ivy-prescient-mode -1))
                              (advice-eval-interactive-spec spec))
                     (when enabled (ivy-prescient-mode 1))))))
  (apply orig args))

-- 
Štěpán





reply via email to

[Prev in Thread] Current Thread [Next in Thread]