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: Fri, 20 Oct 2023 02:25:31 +0300

On 19/10/2023 22:30, Spencer Baugh wrote:

>>>> 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?
> 
> To be clear, this was just a comment about how project-status would help
> us on the implementation side of single-key bindings.  I still

<paragraph unfinished>

>> 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.
> 
> I personally use non-project commands quite frequently through C-x p p D
> 
> Some things I run sometimes:
> - find-file (if I just want to find a file from the root rather than
>    with project-find-file)
> - vc-pull
> - vc-root-diff
> - various internal commands to access code review or check the build
>    status

I guess 'find-file' could also be a command that could use the buffer 
text under point. Apparently, not in your usage, but in someone else's.

>> 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.
> 
> True.
> 
> Automatically generating this would be kind of like which-key.

I pushed a version of this to master, but one that looks more like 
read-multiple-choice. Reimplementing which-key would be too much, and 
unfortunately I don't see a way to integrate it when available either.

>> 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.
> 
> Some possibilities:
> - The project type (or the vc type if it's a vc project?)
> - Maybe some vc information; whether the working tree is dirty?
> - The current number of warnings/errors in the *compilation* buffer for
>    that project if any; I implemented that for bug#63896 and it's
>    pretty easy

These first two sound like they call for addition of more generic 
functions that describe a project. Though it seems like they'd be hard 
to explain in terms of other project backends. Maybe we could instead 
say "VCS responsible for project root" and "VCS short status". Anyway, 
both good ideas.

Regarding warnings/compilations, like I said in the other bug, it does 
sound nice when the integration works, but the info will be empty for a 
lot of users.

>>>>> 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.
> 
> Er, I'm not sure I understand.  Let me clarify: The "specific problem
> and the general case" that I was referring to is the problem with some
> implementations of project-switch-project where the buffer changes when
> we use project-switch-project, meaning we can't grab stuff from the
> current buffer.  And we could solve that by just saving the buffer in a
> project-specific variable.

Which only project-aware commands would be able to take advantage of.

>> 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?
> 
> Hm, I think changing default-directory in project-list based on point is
> very discoverable.  Let me explain why: When you hit "g" in the
> project-list buffer, I expect that it would operate on the project at
> point.  That seems obvious and unobjectionable.  So users will be used
> to being able to operate on different projects based on the value of
> point.  And it is (in my experience) a straightforward extension from
> that to running arbitrary commands on different projects based on the
> value of point.

'g' is probably fine. 'f' and the rest of such keys too. Though 'n' and, 
more importantly, 'p' will likely have different expectations.

What if the user presses 'C-x o' while this buffer is current (and point 
is on one of the projects)? Or 'C-x C-s'? Would we dispatch every key 
sequence through our custom prefix command while this buffer is current?

I can't think of an particularly damaging example right now, but the 
concept feels moderately dangerous.

Buuut... simply changing default-directory buffer-locally in 
post-command hook based on what is under point might be fine.