Subject: bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands

From: Spencer Baugh <[email-masked]>
Date: Fri, 01 Sep 2023 11:59:41 -0400

Dmitry Gutov <[email-masked]> writes:
> On 01/09/2023 09:46, Juri Linkov wrote:
>>>> (let ((default-directory "/tmp/"))
>>>>     (list default-directory
>>>>           (buffer-local-value 'default-directory (current-buffer))))
>>>> => ("/tmp/""/tmp/")
>>>> Here is the shortest test case: 'C-x p p C-b' shows buffers
>>>> from two projects when using let-binding for default-directory,
>>>> because 'project-buffers' relies on
>>>>     (buffer-local-value 'default-directory buf)
>>>> This could be fixed by adding special-handling of the default-directory
>>>> for the current buffer in 'project-buffers'.
>>> What kind of special handling? The "real" buffer-local value is hidden
>>> until the "let" exists, the global value is nil, and if the buffer is not
>>> a file-visiting one, there is no other file name to test against.
>> Additional buffer-local variable like 'buffer-default-directory' could help.
>> Or additional global variable 'global-default-directory'.  Or even
>> using the global value of the existing variable 'default-directory'.
>
> What code would use it instead of the local value of
> default-directory? Only project-related code? Or other code as well?
> If it's the former, we have an existing variable in the project
> package. If the latter, we'd need some formal description of those
> usage rules to proceed.
>
>>> Finally, whatever special handling we invent, would have to be mirrored by
>>> all subsequent new commands (built-in and third-party) which look up the
>>> value of default-directory. Especially project-related ones. How to
>>> popularize that knowledge, would be the next question for whatever solution
>>> we invent.
>> Hopefully there should be not much trouble such as in 'project-buffers'.
>
> I think there exists a class of commands (existing and potential ones)
> that would use default-directory with exact same purpose and
> expectations.

Thinking about it, I guess there's (roughly) two classes of commands
which want different things from default-directory, classes 1 and 2:

1. wants whatever the current value of default-directory is (and gets
this by just using default-directory as a variable)

2. wants the value of default-directory for some specific buffer X (and
gets this either with buffer-local-value or by using
with-current-buffer)

If we could change 1 without changing 2, then we'd be happy.

This gets back to my earlier suggestion, that we have some way of
binding a variable which does not change the buffer-local value.
Supporting that would require fairly deep changes in C of course.

(But actually, maybe it would be useful for Lisp threads?  In fact,
maybe Lisp threads already support this?  Because when you're in a
thread and you bind default-directory, you don't want that to affect any
other threads, you only want it to affect code running directly under
you.)

---

Anyway, I'm coming around to the idea that actually the "changing the
local value of default-directory" problem isn't that big of a deal.  We
can do something special for project-buffers, and that would make things
work OK with the next-default-directory approach, and if we run into
further problems in the future, we'll rethink at that time.

Maybe with more time running with the code, we will come up with
something new and clever.