Subject: Sv: bug#76023: 31.0.50; Observed behavior for substitute-in-file-name different from the doc string

From: arthur miller <[email-masked]>
Date: Mon, 3 Feb 2025 15:34:48 +0000

> > According to docstring, text ending with '/~' should be descarded through
> > the slash. Does not happen:
> >
> > (substitute-in-file-name "some-string/~$HOME") => some-string/~C:\Users\arthur
> >
> > However:
> >
> > (substitute-in-file-name "some-string~/$HOME") => C:\Users\arthur
>
> Yes.  Emacs on MS-Windows doesn't support the "~foo" notation, which

Actually, is seems you do support that notation on Windows :-). It works here:

~/repos/emsrc/emacs/src $ (expand-file-name "~")
c:/Users/Arthur
~/repos/emsrc/emacs/src $ (expand-file-name "~arthur")
c:/Users/Arthur
~/repos/emsrc/emacs/src $ (expand-file-name "~/test")
c:/Users/Arthur/test
~/repos/emsrc/emacs/src $

It seems that you are thinking of the wrong function here, or haven't looked at
the implementation. That would be expand-file-name that supports "~foo"
notation, not substitute-in-file-name.

We are speaking about substitute-in-file-name, which supports "$foo" to
substitute an env variable in the string. Furthermore, it also supports "/~" and
"//" which means that everything before those two strings should be
discarded. As described in the bug report, "~/" does what the doc string
states. Observe that substitute-in-file-name never calls expand-file-name; so
that expansion of tilde you seem to speak about, should never take place there.

In short: everything is supported, the docs just display a bad string.

I think you are confused by my example. I choose "HOME" because the result
string is shorter. I could have used "$PATH" in those examples, or "$UserProfile".

> means "the home directory of user named 'foo'", because that's not
> possible (or at least not easy) on Windows.  So on Windows we treat
> the "~" character literally in those cases.  The above is the direct
> consequence of that non-support.

As long as an user has a "HOME" variable defined it seems to work, see above.

> > Which seems to be the promised effect. I guess it was a typo in
> > the doc string and the code comment, otherwise it is a bug in the
> > implementation. '//' works as advertised, so I guess it is just a typo in
> > the doc string.
>
> It isn't a typo in the doc string, because on Posix systems Emacs
> behaves like the doc string says.  It is a common trait in
> documentation Emacs not to describe too many details about the
> idiosyncrasies of MS-Windows, especially in dark corners such as this
> one.

Why does "~/" works as described in the doc string of substitute-in-file-name,
but the doc says "/~"?

> > Furthermore, I find it a bit arcane, or at least unnexpected that I get
> > a native namestring, instead of Emacs path, since other functions in the
> > fileo.c return Emacs internal (unix-like) namestrings (thus far I have
> > tested them).
>
> That shouldn't matter, since Emacs can use both forward and
> backslashes in file names.

Yes, I understand that, I have seen it. It is not that it matters to Emacs per
se, or if the user types at the prompt interactively. It matters if someone
passes a result of that function to some other function which is not Emacs
built-in namestring manipulation function. Than that person can not assume
platform-independent namestrings, which I don't think would be unreasonable to
assume. Also, it is not very difficult to implement it either.

The only two functions that has this different behavior are
substitute-in-file-name and concat-path-name. The reason is probably because
they don't expand file name as others functions in fileio.c do, but do their own
thing with string concatenations.

As regression: (file-name-concat "foo" "bar\\" "baz") => "foo/bar\\baz"

The reasoning is the same, code could pass-in "bar\\" as a result from some
other computation and pass in the result of file-name-concat into some other
code, in which case they would have to do all the platform dependent stuff
themselves. It wouldn't be very difficult to implement it to be consistent with
other functions and return unix-like path that Emacs uses internally.

> > If it is a "feature" to get the native namestring, at least perhaps mention
> > it?
>
> It is a feature, but I don't think we want to mention it, because it's
> Windows-specific, and because "~$HOME" makes very little sense on
> Windows.

I am not sure why "~$HOME" makes sense anywhere? Do you perhaps mean "~$USER"?