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

From: Dmitry Gutov <[email-masked]>
Date: Thu, 19 Oct 2023 20:17:05 +0300

On 19/10/2023 17:00, Spencer Baugh wrote:

>> It makes this capability apparent, and it's still one fewer keystroke
>> (and 'o' is close to 'p', too).
> 
> One fewer keystroke?  Oh, since one has to hit shift to type
> D... there's equivalently C-x p p v, then, which is the same length in
> keystrokes.

'C-x p p v' is a bit farther, but close enough indeed.

>>> The main downside of C-x p p D is that it necessarily switches buffers,
>>> which I often don't want.  Solving that would be nice, but it would be
>>> nice to also get a shorter keybinding out of it.
>>> Actually, this gives me an idea.  What if we embraced having C-x p p
>>> switch buffers?  What if we had a new command which jumps you to some
>>> new "project status buffer", whose default-directory=project-root, and
>>> which has single-letter bindings for the current project-prefix
>>> commands?  Similar to vc-dir.  We could probably find some useful
>>> information to display in that buffer, too, like a header which extracts
>>> the status from the project's compilation buffer, or a list of the
>>> buffers in the project.
>>
>> I'm totally on board with adding such command, except I'm not sure if
>> we will give away the 'C-x p p' binding to it. But as far as calling
>> the "next" command, both project-vc-dir and project-dired currently
>> satisfy your condition, right?
> 
> Yes.  Although project-vc-dir and project-dired don't provide a nice
> solution for how to implement the C-x p p single key bindings.  With the
> project-status buffer, if it had the single-key bindings, then we would
> just say "C-x p p resolves keybindings as they would be resolved in
> project-status".

Hmm... if the goal is to just have 'C-x p p' resolve the short key 
bindings, then (setq project-switch-use-entire-map t) gets you all the 
way there, doesn't it?

So the question is, do you need to be able to use non-project commands 
(like in the title of this report), and how often?

If it's not very often (which would reflect my experience), then 
pressing 'o' once in a while should be a small price to pay.

BTW, when project-switch-use-entire-map is non-nil, we should probably 
display something informative to the user (e.g. some abbreviated list of 
all the bindings in project-prefix-map?), so that the users don't 
mistake the the meaning of the option, and see at least some of the keys 
they can press at that point, instead of the incorrect command menu.

> BTW, a more tangential idea: a list-projects command and associated
> *Project List* buffer would be nice.  With:
> 
> - a list of all remembered projects, with some details about each one
> - you can hit RET to open a project's project-status
> - with something (a post-command-hook?) which updates default-directory
>    so that it matches the project at point, so commands you run operate
>    on that project (e.g. find-file)
> - and the same single key bindings that are in project-prefix-map
>    (maybe C-x p RET should be the binding to open project-status in general)
> 
> This would be a nice complement to project-switch-project: list-projects
> and project-switch-project would be like list-buffers and
> switch-to-buffer.

That reminds me of bug#63896. And I suppose some pieces could be reused 
between these views.

Speaking of 'list-projects', though, I wonder what we could display for 
a project by default, aside from its root dir (abbreviated) and the 
number of open buffers.

> (The combination of list-projects and project-status buffers would
> basically be a port of what we have internally at Jane Street.  While
> I'm saying that, I should mention also our equivalent of
> project-switch-project: when passed a prefix argument, all our
> equivalent-to-project-* commands will prompt for a project.  This is not
> a great solution though, it doesn't scale well since every command needs
> to be aware of this prefix argument.  The C-x p p design of a separate
> command which overrides the project for the next command is much better,
> and once we get a good design I plan to tell our users to start using
> C-x p p for our internal commands instead of passing the prefix
> argument.)
> 
>>> If we replaced C-x p p with this command, then that would avoid all our
>>> issues with default-directory and command loops and so on, by just
>>> biting the bullet and switching buffers.
>>
>> Except when one wants to call a command that takes the current buffer
>> into account. And/or its contents in particular (e.g. file name at
>> point).
>>
>>> Although, maybe we can get the best of both worlds by having C-x p p
>>> just temporarily switch buffer?  It can do (with-current-buffer
>>> (project-status) ...) plus resolving keybindings as if they were typed
>>> in the project-status buffer.  That seems pretty elegant to me and
>>> resolves a lot of complexities without giving up anything.
>>
>> https://debbugs.gnu.org/cgi/bugreport.cgi?bug=63829 was a problem
>> caused by a similar approach in the implementation. OTOH,
> 
> I was thinking we'd solve both this specific problem and the general
> case by just saving the current buffer in a project-old-buffer variable
> so that project-aware commands could go back and grab stuff from it.

I suppose they could, but then we support using them all (?) already 
with project-switch-use-entire-map. When one has custom commands, the 
user would probably add them to project-prefix-map too.

> It does mean that project-unaware commands can't both operate in a
> different project and on the current buffer.  Is there ever a place we
> actually want that though?

 From where I'm standing, we've already passed into the "does anybody 
need this" territory. But people can write their own commands, or 
install packages, and apparently sometimes combine them with projects 
with advanced invocations.

I'm happy to try optimizing different workflows, but it's probably at 
least equally important to make sure the new additions are consistent 
and predictable (meaning, it's easy to tell in advance whether something 
is going to work or not), and hopefully somewhat discoverable too.

The latter probably means that we cannot make just any global key 
sequence work in the *Project List* buffer (or e.g. have 'M-x gnus' 
start in a different directory depending on which line point current is 
on). But we might have a binding for a prefix command which would make 
sure the next one is run within the project room as its 
default-directory. Binding 'project-any-command' (or a variation of it) 
to 'o' seems natural in there too. Do you disagree?