unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Dmitry Gutov <dmitry@gutov.dev>
To: Spencer Baugh <sbaugh@janestreet.com>
Cc: sbaugh@catern.com, 69584@debbugs.gnu.org
Subject: bug#69584: 29.2.50; project-find-functions should have access to maybe-prompt
Date: Thu, 28 Mar 2024 05:44:52 +0200	[thread overview]
Message-ID: <28cf57b9-de16-46a5-9bb8-918827143f72@gutov.dev> (raw)
In-Reply-To: <iermsqqpgbf.fsf@janestreet.com>

On 22/03/2024 15:05, Spencer Baugh wrote:

>> Disabling cache altogether with maybe-prompt=t might be a net
>> negative, given that many users' interaction with project.el might be
>> limited to commands that only do such invocations. But perhaps it's
>> the price to pay for flexibility: as long as we're talking about
>> external cache, it will be up to the callers to avoid caching where
>> the results can be non-deterministic, such as after a prompt.
> 
> Hm, I'm slightly confused, isn't the problem more general than just the
> transient project?  If I run (project-current t directory), and I get a
> project back, I have no idea whether that project is actually for
> DIRECTORY or not: if DIRECTORY is not in a project at all, the returned
> project is instead some project selected by the user with
> project-prompter.

That's a good point. The assumption was that it *would* be for DIRECTORY 
(some parent, perhaps), but that relation won't necessarily hold.

Then it becomes a question for the cache creator - whether such cached 
entry is useful, and for how long.

>>> So my use case then is this: when a user opens code review FE-123 in
>>> a
>>> buffer, they look at the diff and then decide they want to do something
>>> in a working copy of the code.  Currently, to do that they run one of a
>>> variety of internal commands which duplicate things like
>>> project-find-file, but which are aware of whether or not there's a local
>>> working copy, and operate the local working copy if any, and otherwise
>>> prompt to create a local working copy and then error.
>>> I'd like to replace those internal commands with just normal
>>> project-find-file, and also allow other commands which use
>>> project-current to determine the current project to just work.
>>
>> If you set up a project instance in a buffer-local way, would it even
>> work correctly outside of that buffer?
> 
> Hm, I don't see why it wouldn't?  It's not really any different, again,
> from project-prompter returning a project when DIRECTORY isn't a
> project.  I'm intending for these functions to return a totally normal
> vc project, to be clear - the only magic is in initially finding that vc
> project, when default-directory isn't in that vc project.

I mean, it _might not_ work. For example, if the project implementation 
does some additional buffer-local things like storing extra information 
related to the project in buffer-local variables. Which would be a valid 
thing to do for buffer-local projects, but not a particularly great one 
in the general context.

Anyway, that depends on you as the author as well - to avoid such problems.

>> Would project history work fine? When you pick a project from recently
>> visited, you basically just apply its last root directory and expect
>> the project to be "found".
> 
> The project-root would be just be the normal directory that the project
> actually is located in, in the filesystem.  And since it would be a
> normal vc project, project-find-functions would return the same project
> instance when run on its root.  So that would work fine too.

Very good.

>> I've read the article (thanks!), but I'm not sure yet of what would be
>> the ergonomic savings in such scenario when instead of having a
>> separate command to check out a branch and visit a file in it (perhaps
>> bound to 'o f' inside the major mode map for the branches list's
>> buffer), you call project-find-file right away. In the former scenario
>> such command would make sure the branch is checked out, so its
>> directory has proper contents, and then it could delegate to
>> project-find-file inside said directory. And later visits (e.g. from
>> project-switch-project) would work fine until the directory is
>> deleted.
> 
> Consider project-vc-dir or project-dired.  The default-directory of
> these directories is the project root, so if you want to operate on the
> project, you can do that in these buffers.  And that's convenient and
> good - you can do things like find-file or project-find-file or
> whatever, because these buffers are conceptually "within" the project.
> 
> The branch overview is like project-vc-dir, but you can also open it
> when there's no local working copy for a branch.
> 
> If there *is* a local working copy, the branch overview has a
> default-directory in the project, so you can treat it like
> project-vc-dir or project-dired.  This is the common case, this works
> great.

I think I get it now, thanks.

> If there isn't a local working copy, the branch overview has a
> default-directory of "/" just because there's no sensible
> default-directory for the buffer.

This detail makes me somewhat uneasy, but ultimately it's up to you to 
test this and related behaviors (any other callers of project-current 
that you use). If the important ones work out fine, then I suppose this 
can be okay.

> And if you open a branch overview and
> you know there's no local working copy, you could run a command to
> create a local working copy and only then start treating it like
> project-vc-dir, running commands which operate on the project.
> 
> But, it's convenient to be able to ignore whether a given branch
> overview has a local copy or not.  Indeed, there are heuristics which
> pre-create local copies for branches you are likely to interact with,
> e.g. branches you need to review code for.  So for normal development,
> there will usually be a local working copy before you open the branch
> overview, even without your intervention.  So you can get away with only
> rarely explicitly creating one.
> 
> So when you open up a branch overview, you'll usually assume there's a
> local copy, and so your first action will probably some command which
> uses project-current.  But if there's no working copy, then you'll get
> dropped to a prompt to choose a project, instead of (say) a
> project-find-file prompt, which you might not immediately notice, which
> is confusing, and you'll have to C-g out of it, and then run some other
> command to create the working copy.  All that is a hassle.
> 
> A few other potential things I could do to solve that confusing
> situation:
> 
> - My project-find-function could detect if it's running in a branch
>    overview buffer without a local copy and immediately error, which
>    stops project-current from running, so it can't prompt.
> 
> - I could make the branch overview buffer always have a
>    default-directory of the location where the local copy *will* be
>    created, even if it doesn't currently exist.  (All of the local
>    working copies are created as subdirectories of one specific
>    directory.)  Then my project-find-function could look at the
>    default-directory string without touching the filesystem, detect that
>    it's in the directory for projects managed by my package, and return a
>    project instance with a project-root that doesn't actually exist, so
>    then project-find-file will fail when it tries to list files for a
>    nonexistent project.
> 
> I'm guessing both of those also have undesirable implications for the
> project-current semantics, though?

In general, I would prefer the latter - as long as your 
project-find-functions element comes first, it should recognize those 
paths okay.

And the vc-aware backend returns nil silently when default-directory is 
non-existent, so the obvious problem shouldn't come up.

Anyway, the patch we settled on is agnostic to this choice, so there is 
no urgency to make this choice or change.

>> If this change will be enough to cover your scenario, let's go ahead
>> and add the 'non-essential' binding. It does seem to make sense for
>> Tramp, at least.
> 
> Yes, that completely covers my scenario.  (Putting aside whether my
> scenario is a good idea :) )
> 
> So I would be happy with that.

Now pushed to master as commit 1552f8345d8.





  reply	other threads:[~2024-03-28  3:44 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-06 14:23 bug#69584: 29.2.50; project-find-functions should have access to maybe-prompt Spencer Baugh
2024-03-15  1:41 ` Dmitry Gutov
2024-03-16 13:31   ` sbaugh
2024-03-18 21:59     ` Dmitry Gutov
2024-03-22 13:05       ` Spencer Baugh
2024-03-28  3:44         ` Dmitry Gutov [this message]
2024-04-04 14:29           ` Spencer Baugh
2024-04-05  0:33             ` Dmitry Gutov
2024-04-02 17:54         ` Spencer Baugh
2024-04-02 23:10           ` Dmitry Gutov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=28cf57b9-de16-46a5-9bb8-918827143f72@gutov.dev \
    --to=dmitry@gutov.dev \
    --cc=69584@debbugs.gnu.org \
    --cc=sbaugh@catern.com \
    --cc=sbaugh@janestreet.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).