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

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

Re: Making a function than can only be used interactively


From: Yuri Khan
Subject: Re: Making a function than can only be used interactively
Date: Fri, 8 Jul 2022 13:55:11 +0700

On Fri, 8 Jul 2022 at 13:31, Emanuel Berg <incal@dataswamp.org> wrote:

> > It does not matter for interactive use. [...] ‘&optional’
> > comes into play if you use this function non-interactively,
> > from Lisp
>
> No, it matters. One example how it matters is that optional
> arguments defaults to nil.

You’re right, with an interactive specification that evaluates to a
list it matters, because the list you return may or may not have as
many arguments as the function takes.

My point was that in the specific case of a three-argument function
and a three-item string-valued interactive specification, &optional
does not matter for interactive use.


> Check out this file and in particular example 4 which doesn't
> make sense to me?
>
> ;; DWIM example 1, from Lisp ignore region if set
> ;; example 2, use the region if available from Lisp as well
>
> (defun test-dwim (&optional beg end)
>   (interactive (when (use-region-p)
>                  (list (region-beginning) (region-end)) ))

Here you have two cases. If the region is active, you produce a
two-element list, otherwise, a 0-element list. The function signature
allows 0..2 arguments, so it works in either case.

> ;; example 3, one call to `use-region-p' is enough
>
> (defun test-dwim-3 (re &optional beg end)
>   (interactive `(,(read-regexp "re: ")
>                  ,@(when (use-region-p)
>                      (list (region-beginning) (region-end)) )))

Mostly same, except you build a list of 3 or 1 elements, and the
function accepts 1..3 arguments.

> ;; example 4, let's do that with the `interactive' spec
> ;; string. but without `use-region-p' it doesn't reset after
> ;; I clear the region, or that's what I thought happened
> ;; anyway :) so this doesn't work as intended, which
> ;; `test-dwim-3' does, supposedly the worse one.
>
> (defun test-dwim-4 (re &optional beg end)
>   (interactive "sre: \nr")

Here you use a string interactive spec which always produces 3
elements. In non-interactive use, it will work if called as
(test-dwim-4 "^foo$"), (test-dwim-4 "^foo$" 42), or (test-dwim-4
"^foo$" 42 69).

As to your “clearing” the region, Emacs always maintains the point and
mark positions, and the ‘r’ interactive spec code ignores the region
activation flag and always passes the point and mark. (This could be
considered a bug, but I see no good alternative behavior, except maybe
passing two nils if the region is not active.)



reply via email to

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