vim -u NONE -c 'echo expand("%:~") expandcmd("%:~")' "$HOME/file".~/file /home/user/file with the name of the current user.:help does not suggest that expand() and expandcmd() should behave differently regarding command line special variables. These are the relevant parts from :help:
expand(…) … When {string} starts with '%', '#' or '<', the expansion is done like for the cmdline-special variables with their associated modifiers.
expandcmd(…) … This expands special keywords, like with expand(), and environment variables, anywhere in {string}. "~user" and "~/path" are only expanded at the start.
9.2 (patches 1-807)
Operating system: Ubuntu 24.04.4 LTS on WSL 2.7.10.0 (Windows 11 Home 25H2)
Terminal: Windows Terminal 1.24.11911.0
Value of $TERM: xterm-256color
Shell: GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
You already quoted the relevant sections, the behavioural difference is documented:
"
user" and "/path" are only expanded at the start.
Which is not mentioned at :h expand().
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
The way that sentence is phrased suggests e.g., ~, ~/dir, are expanded, but not, say, e.g., ./~temp~. The rationale, of course, is that ~ stands for $HOME in a shell command only at the start.
I would argue %:~ is a different class of expansion that belongs with e.g., %:p, %:h, i.e., command line special variables. These commands (as far as I can tell) work the same way for expand() and expandcmd().
There is also no reason to exclude %:~ from being expanded. A user may want to write, e.g., %:~:s?\~?/root? (same file but under root; this works with, e.g., :edit, :terminal, expand()) or :!docker exec container python %:~:s?\~?? (run this Python script in a Docker container, assuming that $HOME/app is mounted as /app).
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
But expanding %:~ to the actual home path would be backwards incompatible change. I'd think, you could use %:p for that, if you really need that (and then you could use :s?pat?sub afterwards. Even if slightly inconsistent, I think the current behaviour should not be changed, since it has been like that for a very long time.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
I cannot speak to how long this behavior has been or indeed how much code depends on this particular quirk, so I would leave the judgment call to the code maintainers. But as you pointed out, it is inconsistent behavior, and surprising the user is not a good thing to do. I think at least this exception to the regular processing of command line special variables should be documented explicitly under expandcmd().
I have considered your suggestion before regarding the two-step replacement, but if % is used in, e.g., 'makeprg', then $HOME would have to be hard-coded, which is not very desirable—one would need to keep multiple versions of .vimrc on different servers.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
Let me add that, in my opinion, the primary usage of expandcmd() is to expand 'makeprg' and friends out in full so they can be consumed by others, e.g., system() and term_start(). That is why expandcmd() has cmd in its name, why it expands % everywhere, and why it expands only leading ~ in paths. expandcmd() should make scripting easier by exposing the internal expansion mechanism used by Vim. It should produce the same result as, e.g., :edit and 'makeprg'.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()