graduale · 2022-11-01 03:14
I'm trying to understand the behavior of the variable `current-prefix-arg`. In particular, I'm trying to understand whether if I pass a prefix argument to `func`, and `other-func` is called by `func`, `other-func` should be ignoring that prefix argument.
Consider the following four functions:
(defun f1 (arg)
(interactive "P")
(when arg
"Non-nil"))
(defun f2 (arg)
(interactive "P")
(when current-prefix-arg
"Non-nil"))
(defun g1 (arg)
(interactive "P")
(message "%s, %s" current-prefix-arg (f1 nil)))
(defun g2 (arg)
(interactive "P")
(message "%s, %s" current-prefix-arg (f2 nil)))
I would have thought that both `g1` and `g2` would behave the same. But if I call `g1` with the `C-u` prefix key, I get `"(4), nil"`, whereas if I call `g2` with the `C-u` prefix key, I get `"(4), non-nil"`.
Is this as it should be? I understand I can bind `current-prefix-arg` to nil before calling `f2`, i.e. I could just call `f2` inside the scope of a `let` expression, binding `current-prefix-arg` to `nil`. But is there a cleaner way to do this?
Looking at the manual section on [prefix command arguments](https://www.gnu.org/software/emacs/manual/html_node/elisp/Prefix-Command-Arguments.html) hasn't helped me figure this out, so I'm hoping someone here may be able to help. (I'm not clear on what is meant there by "the *next* editing command. At first I thought `prefix-arg` would be passed on to functions in the scope of another, but `current-prefix-arg` would not; now I'm not sure anymore.)
7890yuiop · 2022-11-01 03:18
`current-prefix-arg` has dynamic scope/extent, so the binding lasts until the end of that dynamic scope.
You want to read about dynamic vs lexical binding in the manual.
> I would have thought that both g1 and g2 would behave the same.
You've explicitly passed `nil` to `f1` so of course it reports `nil` for the value of its `arg`. Note that as you are not calling `f1` or `f2` interactively, their `interactive` specs are not relevant.
> I'm not clear on what is meant there by "the next editing command.
The next trip around the command loop: `C-h i g (elisp)Command Loop`
graduale · 2022-11-01 12:14
Thanks! I thought if the issue had to do with dynamic vs lexical binding, enabling lexical binding in the buffer would've mad a difference, but it hadn't, so I jumped to the conclusion that this wasn't it. My bad. [**EDIT**: I now see that `(special-variable-p 'current-prefix-arg)` returns `t`, which implies(right?) that `current-prefix-arg` will take dynamic scope no matter what.]
So am I right in thinking that in e.g. this function:
(defun func ()
(interactive "P")
(message "%s" current-prefix-arg))
`current-prefix-arg` is only bound when called interactively? (I also tried calling `f2` using `call-interactively` instead, but that didn't make a difference.)
Will look at the nodes you point to. Thanks again.
7890yuiop · 2022-11-01 12:53
`C-u` and the like are bound to commands which manipulate the value of `prefix-arg` (maybe repeatedly), and then `current-prefix-arg` usually gets set by `command-execute` based on whatever `prefix-arg` was set to. Commands which manipulate the prefix arg have some special handling associated with that, but they're all just commands -- have a poke around the code and you'll get the idea.