all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Michael Heerdegen <michael_heerdegen@web.de>
To: Stefan Kangas <stefankangas@gmail.com>
Cc: 62563@debbugs.gnu.org
Subject: bug#62563: [FR] Expose `interactive' arg handling as an Elisp function
Date: Mon, 18 Sep 2023 06:28:14 +0200	[thread overview]
Message-ID: <875y486r6p.fsf@web.de> (raw)
In-Reply-To: <CADwFkmkL9qfViz6RaJEk+oHfXeS7vB3_TkL1kwpca5vusuyGCA@mail.gmail.com> (Stefan Kangas's message of "Sun, 17 Sep 2023 04:31:57 -0700")

Stefan Kangas <stefankangas@gmail.com> writes:

> Could you point to one (or more) examples of real code that would have
> been made significantly simpler by this?  The idea sounds good in
> theory, but it is important to understand if it will also be useful in
> practice.  That will give us a better basis for deciding if this is
> something we would want to add or not.

[ Note I only asked about renaming `advice-eval-interactive-spec' to
`eval-interactive-spec', not about adding something new.  Because the
function is not only useful in nadvice.el.  Dunno if I made that clear. ]

People can of course already use the name `advice-eval-interactive-spec'
- but it is probably not well known.

Ehm - examples, ok.  Whenever a package or config file wants to define a
variant of an existing command that needs to read in the same arguments
in the same order (i.e. the user wants to have multiple commands instead
of one, an additional definition, not an advice), one has to copy the
interactive spec of the original definition.  Or one can use
`advice-eval-interactive-spec'.  The body of the variant also may or may
not reuse the other function.  This is all very similar to defining
advices - only that it doesn't involve an advice, as I described.

When the variant of an existing command wants to skip reading one
argument, `advice-eval-interactive-spec' is not of much use.  But the
same is true of advices of interactive functions that want to skip
reading an argument.

In the Emacs sources it's possible to factor the interactive spec out
into its own defun and reuse it in several places.  So this kind of use
case is mostly relevant for external packages and user configurations.

Ok, you wanted a real life example.  In my init file I have a command
like this:

#+begin_src emacs-lisp
(defun my-dired-restrict-marks ()
  "Restrict marks using the following command.

Only files that are currently marked and are marked again with
the subsequent command will be marked afterwards.  Thereby only
`dired-marker-char' marked files are considered - other marks are
not touched.

The next key sequence can optionally be prefixed with key ! to
mean \"not\" - then only marked files that would _not_ be marked
again with the next command keep their mark [...]
  ...
  )
#+end_src

That way I can combine several marking commands to have files marked
fulfill more than one condition.  If I bind the above command to `&', I
can use * / & * % to mark directories whose name is matched by a certain
regexp, for example.

The implementation saves the current file marks, reads a key sequence,
determines the bound command, then evals the interactive spec to get the
arguments (it is better to do this using the original buffer state, this
is the important part here).

Then all marks are removed, the command is called with the read in
arguments (simply using `apply'), then the marks are merged with the
remembered marks.

A similar case is my command `my-profiler-profile-next-command': It
similarly reads in a key sequence and the according arguments using the
interactive spec, but only after that starts the profiler and calls the
body of the command.  This is nice if you want to avoid that the
argument reading messes the profiler results of the command's code.

Yes, such things, but admittedly, the large majority of calls of
`advice-eval-interactive-spec' is still for defining advices.


I also want to add that what I describe here is related, but not the
same as the request in the original report which, AFAIU, more asked
about a convenient way to simulate (interactive "f") conveniently from
Lisp.  If we would have access to the code reading in the individual
arguments that would be even nicer, but it's not possible in the general
case because the interactive spec returns a list that is the result of
any arbitrary code that returns a list (i.e. there is no separate code
for each single argument in every case).

I let you decide whether my examples are enough to justify this
renaming.  There are probably not that many use cases, still, there are
a few.

Michael.





  reply	other threads:[~2023-09-18  4:28 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-31  7:27 bug#62563: [FR] Expose `interactive' arg handling as an Elisp function Ruijie Yu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-03-31  7:38 ` Eli Zaretskii
2023-09-11 23:54   ` Stefan Kangas
2023-09-17  0:50     ` Michael Heerdegen
2023-09-17 11:31       ` Stefan Kangas
2023-09-18  4:28         ` Michael Heerdegen [this message]
2023-09-19 10:21         ` Richard Stallman

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

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

  git send-email \
    --in-reply-to=875y486r6p.fsf@web.de \
    --to=michael_heerdegen@web.de \
    --cc=62563@debbugs.gnu.org \
    --cc=stefankangas@gmail.com \
    /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 external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.