all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* (call-interactively FN) leaks prefix arg into FN when called from within an interactive command
@ 2018-04-24  1:05 Göktuğ Kayaalp
  2018-04-24 13:21 ` Stefan Monnier
  0 siblings, 1 reply; 3+ messages in thread
From: Göktuğ Kayaalp @ 2018-04-24  1:05 UTC (permalink / raw)
  To: help-gnu-emacs

So, I have the following function:

,----
| (defun gk-find-file (arg)
|   (interactive "P")
|   (call-interactively (if arg #'find-file #'ffap)))
`----

bound to C-x C-f.  That key sequence runs ffap, and with prefix argument
(i.e. C-u C-x C-f) it runs find-file.  But that's not what I want, I
want the inverse, so I swap find-file and ffap:

,----
| (defun gk-find-file (arg)
|   (interactive "P")
|   (call-interactively (if arg #'ffap #'find-file)))
`----

but with this version, it always runs find file.  After trying various
things I came up with this:

,----
| (defun gk-find-file (arg)
|   (interactive "P")
|   (if (null arg) (call-interactively #'find-file)
|     (let (current-prefix-arg)
|       (call-interactively #'ffap))))
`----

which worked as intended (yes I tried it w/o the let too).  So the
prefix argument to gk-find-file leaks to ffap, causing it to think it
got a prefix argument too.  Is this intentional, or a bug?
Nevertheless, this is really confusing.  And reading "(elisp) Prefix
Command Arguments", it does not really indicate this:

,----
|  -- Variable: current-prefix-arg
|      This variable holds the raw prefix argument for the _current_
|      command.  Commands may examine it directly, but the usual method
|      for accessing it is with ‘(interactive "P")’.
`----

This is a more generic example:

,----
| (defun foo (arg)
|   (interactive "P")
|   (call-interactively
|    (lambda (arg)
|      (interactive "P")
|      (message "%S %S %S" arg current-prefix-arg prefix-arg))))
| 
| M-x foo     => nil nil nil
| C-u M-x foo => (4) (4) nil
`----

But is it really the _current_ command when it's invoked by
call-interactively?  It was totally unexpected for me that the value of
current-prefix-arg leaks into a function F in (call-interactively F).  I
believe call-interactively should be, at least optionally, able to
suppress the prefix arg from the context it was called in.  Is this
expected behaviour?  If so, why is it not documented?

-- 
İ. Göktuğ Kayaalp	<https://www.gkayaalp.com/>
			 024C 30DD 597D 142B 49AC
			 40EB 465C D949 B101 2427




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

* Re: (call-interactively FN) leaks prefix arg into FN when called from within an interactive command
  2018-04-24  1:05 (call-interactively FN) leaks prefix arg into FN when called from within an interactive command Göktuğ Kayaalp
@ 2018-04-24 13:21 ` Stefan Monnier
  2018-04-24 14:10   ` Göktuğ Kayaalp
  0 siblings, 1 reply; 3+ messages in thread
From: Stefan Monnier @ 2018-04-24 13:21 UTC (permalink / raw)
  To: help-gnu-emacs

> |   (if (null arg) (call-interactively #'find-file)
> |     (let (current-prefix-arg)
> |       (call-interactively #'ffap))))
> `----

I'd use

    (let ((current-prefix-arg nil))
      (call-interactively (if arg #'ffap #'find-file)))

> So the prefix argument to gk-find-file leaks to ffap,

The (interactive "P") does not *consume* the value of
current-prefix-arg, indeed.  It just uses it to set the value of `arg`.

> Is this intentional, or a bug?

Neither.  It's a consecuence of the design.

> But is it really the _current_ command when it's invoked by
> call-interactively?

The "current command" is defined in terms of read-eval-loop, not in
terms of `call-interactively`.  For the same reason `call-interactively`
does not run pre-command-hook and post-command-hook.


        Stefan




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

* Re: (call-interactively FN) leaks prefix arg into FN when called from within an interactive command
  2018-04-24 13:21 ` Stefan Monnier
@ 2018-04-24 14:10   ` Göktuğ Kayaalp
  0 siblings, 0 replies; 3+ messages in thread
From: Göktuğ Kayaalp @ 2018-04-24 14:10 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs

On 2018-04-24 09:21 -04, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
>> So the prefix argument to gk-find-file leaks to ffap,
>
> The (interactive "P") does not *consume* the value of
> current-prefix-arg, indeed.  It just uses it to set the value of `arg`.
>
>> Is this intentional, or a bug?
>
> Neither.  It's a consecuence of the design.
>
>> But is it really the _current_ command when it's invoked by
>> call-interactively?
>
> The "current command" is defined in terms of read-eval-loop, not in
> terms of `call-interactively`.  For the same reason `call-interactively`
> does not run pre-command-hook and post-command-hook.

Thanks a lot for the explanation!

-- 
İ. Göktuğ Kayaalp	<https://www.gkayaalp.com/>
			 024C 30DD 597D 142B 49AC
			 40EB 465C D949 B101 2427



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

end of thread, other threads:[~2018-04-24 14:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-04-24  1:05 (call-interactively FN) leaks prefix arg into FN when called from within an interactive command Göktuğ Kayaalp
2018-04-24 13:21 ` Stefan Monnier
2018-04-24 14:10   ` Göktuğ Kayaalp

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.