GNU bug report logs - #79126
vc-switch-working-tree does not work if there is no matching file

Previous Next

Package: emacs;

Reported by: Dmitry Gutov <dmitry <at> gutov.dev>

Date: Wed, 30 Jul 2025 02:38:01 UTC

Severity: normal

Done: Sean Whitton <spwhitton <at> spwhitton.name>

To reply to this bug, email your comments to 79126 AT debbugs.gnu.org.
There is no need to reopen the bug first.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to spwhitton <at> spwhitton.name, sbaugh <at> janestreet.com, bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Wed, 30 Jul 2025 02:38:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Dmitry Gutov <dmitry <at> gutov.dev>:
New bug report received and forwarded. Copy sent to spwhitton <at> spwhitton.name, sbaugh <at> janestreet.com, bug-gnu-emacs <at> gnu.org. (Wed, 30 Jul 2025 02:38:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: bug-gnu-emacs <at> gnu.org
Subject: vc-switch-working-tree does not work if there is no matching file
Date: Wed, 30 Jul 2025 05:36:54 +0300
X-Debbugs-CC: spwhitton <at> spwhitton.name, sbaugh <at> janestreet.com

Hi!

If the current buffer does not visit a file (such as Dired, mentioned in 
a FIXME comment), or if the current file has no corresponding on the 
other worktree, we end up with an error.

Like

  file-relative-name: Wrong type argument: stringp, nil

or

  File ‘lisp/progmodes/abc.el’ not found in ‘~/vc/emacs-28/’

I guess some of these could be improved in project-find-matching-file 
(support for more major modes?) but semantically it seems like 
vc-switch-working-tree should try harder. Falling back to visiting the 
worktree root in Dired, if it doesn't find a better choice.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Wed, 30 Jul 2025 04:31:02 GMT) Full text and rfc822 format available.

Message #8 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Eshel Yaron <me <at> eshelyaron.com>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: sbaugh <at> janestreet.com, 79126 <at> debbugs.gnu.org, spwhitton <at> spwhitton.name
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Wed, 30 Jul 2025 06:30:31 +0200
Hi Dmitry, Sean, Spencer,

First of all, thank you for adding these new worktree commands, I use
Git worktrees a lot and it's great to see VC supporting them.

Dmitry Gutov <dmitry <at> gutov.dev> writes:

> If the current buffer does not visit a file (such as Dired, mentioned
> in a FIXME comment), or if the current file has no corresponding on
> the other worktree, we end up with an error.
>
> Like
>
>   file-relative-name: Wrong type argument: stringp, nil
>
> or
>
>   File ‘lisp/progmodes/abc.el’ not found in ‘~/vc/emacs-28/’

FWIW, while incorporating this new feature in my Emacs branch, I've made
a few experimental tweaks that eliminate these errors.  Namely, I added
a variable vc-switch-working-tree-function which vc-switch-working-tree
consults to do the actual switching.  By default this variable is set to
a function that works for file-visiting buffers (similarly to the
current implementation in master), but major modes can readily set this
variable buffer-locally to provide worktree-switching support also for
non-file buffers.  I used this indirection to support Dired buffers.

( The more fundamental change I made was to avoid the dependency of VC
  on project.el, which I find... suboptimal.  Instead I introduced hooks
  vc-delete/create-tree-hook which one can use, among other things, to
  keep project--list in sync with deleted/created worktrees.  This does
  come at the expense of effectively disabling the Mercurial support. )

If you want to take a look, you can find my tweaks here:

  http://git.eshelyaron.com/gitweb/?p=emacs.git;a=commitdiff;h=2b1383d647402df2b539f69cf73a12c0717b00f3

> I guess some of these could be improved in project-find-matching-file
> (support for more major modes?) but semantically it seems like
> vc-switch-working-tree should try harder. Falling back to visiting the
> worktree root in Dired, if it doesn't find a better choice.

That sounds like a good fallback, indeed.


Best regards,

Eshel




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Wed, 30 Jul 2025 11:05:01 GMT) Full text and rfc822 format available.

Message #11 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: sbaugh <at> janestreet.com, 79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Wed, 30 Jul 2025 12:04:06 +0100
Hello,

On Wed 30 Jul 2025 at 05:36am +03, Dmitry Gutov wrote:

> X-Debbugs-CC: spwhitton <at> spwhitton.name, sbaugh <at> janestreet.com
>
> Hi!
>
> If the current buffer does not visit a file (such as Dired, mentioned in a
> FIXME comment), or if the current file has no corresponding on the other
> worktree, we end up with an error.
>
> Like
>
>   file-relative-name: Wrong type argument: stringp, nil
>
> or
>
>   File ‘lisp/progmodes/abc.el’ not found in ‘~/vc/emacs-28/’
>
> I guess some of these could be improved in project-find-matching-file (support
> for more major modes?) but semantically it seems like vc-switch-working-tree
> should try harder. Falling back to visiting the worktree root in Dired, if it
> doesn't find a better choice.

I was thinking I would implement switching between Dired directories and
VC-Dir buffers in project-find-matching-file, yeah.

Maybe when the file doesn't exist we could fall back to going only as
high up the tree as we need to.  So for example if foo/bar.el doesn't
exist in the other worktree but foo/ does, invoking
vc-switch-working-tree would go to a dired buffer visiting foo/.

The last resort fallback could possibly be to call project-switch-project?

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Wed, 30 Jul 2025 12:31:03 GMT) Full text and rfc822 format available.

Message #14 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Sean Whitton <spwhitton <at> spwhitton.name>
Cc: sbaugh <at> janestreet.com, 79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Wed, 30 Jul 2025 15:30:18 +0300
On 30/07/2025 14:04, Sean Whitton wrote:

>> I guess some of these could be improved in project-find-matching-file (support
>> for more major modes?) but semantically it seems like vc-switch-working-tree
>> should try harder. Falling back to visiting the worktree root in Dired, if it
>> doesn't find a better choice.
> 
> I was thinking I would implement switching between Dired directories and
> VC-Dir buffers in project-find-matching-file, yeah.

Cool, either place sounds good to me.

> Maybe when the file doesn't exist we could fall back to going only as
> high up the tree as we need to.  So for example if foo/bar.el doesn't
> exist in the other worktree but foo/ does, invoking
> vc-switch-working-tree would go to a dired buffer visiting foo/.

Sounds reasonable.

> The last resort fallback could possibly be to call project-switch-project?

Probably not - it would show the prompt a second time, right?

And the last step in the algorithm from the previous paragraph would 
visit the worktree root, I think, so there shouldn't be a scenario of a 
complete failure.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Wed, 30 Jul 2025 13:12:01 GMT) Full text and rfc822 format available.

Message #17 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: sbaugh <at> janestreet.com, Eshel Yaron <me <at> eshelyaron.com>,
 79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Wed, 30 Jul 2025 14:10:55 +0100
Hello,

On Wed 30 Jul 2025 at 06:30am +02, Eshel Yaron wrote:

> FWIW, while incorporating this new feature in my Emacs branch, I've made
> a few experimental tweaks that eliminate these errors.  Namely, I added
> a variable vc-switch-working-tree-function which vc-switch-working-tree
> consults to do the actual switching.  By default this variable is set to
> a function that works for file-visiting buffers (similarly to the
> current implementation in master), but major modes can readily set this
> variable buffer-locally to provide worktree-switching support also for
> non-file buffers.  I used this indirection to support Dired buffers.

Interesting, though it seems to me that instead of adding a whole new
variable vc-switch-working-tree-function, someone could just write a
custom command and bind that to 'C-x v w w'?  Wouldn't that pretty much
cover it?

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Wed, 30 Jul 2025 13:42:01 GMT) Full text and rfc822 format available.

Message #20 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Sean Whitton <spwhitton <at> spwhitton.name>
Cc: Dmitry Gutov <dmitry <at> gutov.dev>, Eshel Yaron <me <at> eshelyaron.com>,
 79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Wed, 30 Jul 2025 09:41:18 -0400
Sean Whitton <spwhitton <at> spwhitton.name> writes:
> Hello,
>
> On Wed 30 Jul 2025 at 06:30am +02, Eshel Yaron wrote:
>
>> FWIW, while incorporating this new feature in my Emacs branch, I've made
>> a few experimental tweaks that eliminate these errors.  Namely, I added
>> a variable vc-switch-working-tree-function which vc-switch-working-tree
>> consults to do the actual switching.  By default this variable is set to
>> a function that works for file-visiting buffers (similarly to the
>> current implementation in master), but major modes can readily set this
>> variable buffer-locally to provide worktree-switching support also for
>> non-file buffers.  I used this indirection to support Dired buffers.
>
> Interesting, though it seems to me that instead of adding a whole new
> variable vc-switch-working-tree-function, someone could just write a
> custom command and bind that to 'C-x v w w'?  Wouldn't that pretty much
> cover it?

No, because multiple other packages providing special buffers might want
to integrate with the existing C-x v w w command.

This sounds like a great idea to me, seems like it would be pretty nice.

For example, we might want:
- C-x v w w while in vc-dir brings you to vc-dir in the other worktree
- C-x v w w while in project-eshell brings you to project-eshell in the
  other worktree
- C-x v w w while in magit-status brings you to magit-status in the other
  worktree

Also, at my site there is a custom "worktree/branch overview" buffer and
it would be great if it was possible to make C-x v w w switch to the
overview buffer for the other worktree.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Tue, 05 Aug 2025 10:47:02 GMT) Full text and rfc822 format available.

Message #23 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: sbaugh <at> janestreet.com, 79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Tue, 05 Aug 2025 11:45:57 +0100
Hello,

On Wed 30 Jul 2025 at 03:30pm +03, Dmitry Gutov wrote:

> On 30/07/2025 14:04, Sean Whitton wrote:
>
>>> I guess some of these could be improved in project-find-matching-file (support
>>> for more major modes?) but semantically it seems like vc-switch-working-tree
>>> should try harder. Falling back to visiting the worktree root in Dired, if it
>>> doesn't find a better choice.
>> I was thinking I would implement switching between Dired directories and
>> VC-Dir buffers in project-find-matching-file, yeah.
>
> Cool, either place sounds good to me.
>
>> Maybe when the file doesn't exist we could fall back to going only as
>> high up the tree as we need to.  So for example if foo/bar.el doesn't
>> exist in the other worktree but foo/ does, invoking
>> vc-switch-working-tree would go to a dired buffer visiting foo/.
>
> Sounds reasonable.
>
>> The last resort fallback could possibly be to call project-switch-project?
>
> Probably not - it would show the prompt a second time, right?

No, I mean calling project-switch-project non-interactively and passing
it the root directory.  Then the user would get some options of exactly
what to do.

> And the last step in the algorithm from the previous paragraph would visit the
> worktree root, I think, so there shouldn't be a scenario of a complete
> failure.

True, but maybe failing all the way up to the root should be a special
case.

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Tue, 05 Aug 2025 10:48:02 GMT) Full text and rfc822 format available.

Message #26 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: Dmitry Gutov <dmitry <at> gutov.dev>, Eshel Yaron <me <at> eshelyaron.com>,
 79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Tue, 05 Aug 2025 11:47:22 +0100
Hello,

On Wed 30 Jul 2025 at 09:41am -04, Spencer Baugh via "Bug reports for GNU Emacs, the Swiss army knife of text editors" wrote:

> Sean Whitton <spwhitton <at> spwhitton.name> writes:
>> Hello,
>>
>> On Wed 30 Jul 2025 at 06:30am +02, Eshel Yaron wrote:
>>
>>> FWIW, while incorporating this new feature in my Emacs branch, I've made
>>> a few experimental tweaks that eliminate these errors.  Namely, I added
>>> a variable vc-switch-working-tree-function which vc-switch-working-tree
>>> consults to do the actual switching.  By default this variable is set to
>>> a function that works for file-visiting buffers (similarly to the
>>> current implementation in master), but major modes can readily set this
>>> variable buffer-locally to provide worktree-switching support also for
>>> non-file buffers.  I used this indirection to support Dired buffers.
>>
>> Interesting, though it seems to me that instead of adding a whole new
>> variable vc-switch-working-tree-function, someone could just write a
>> custom command and bind that to 'C-x v w w'?  Wouldn't that pretty much
>> cover it?
>
> No, because multiple other packages providing special buffers might want
> to integrate with the existing C-x v w w command.

Ah, are you thinking they would do this by using add-function on
vc-switch-working-tree-function?

> This sounds like a great idea to me, seems like it would be pretty nice.
>
> For example, we might want:
> - C-x v w w while in vc-dir brings you to vc-dir in the other worktree
> - C-x v w w while in project-eshell brings you to project-eshell in the
>   other worktree
> - C-x v w w while in magit-status brings you to magit-status in the other
>   worktree
>
> Also, at my site there is a custom "worktree/branch overview" buffer and
> it would be great if it was possible to make C-x v w w switch to the
> overview buffer for the other worktree.

Let's make sure we can support all these, indeed.

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Tue, 05 Aug 2025 11:36:01 GMT) Full text and rfc822 format available.

Message #29 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Sean Whitton <spwhitton <at> spwhitton.name>
Cc: Dmitry Gutov <dmitry <at> gutov.dev>, Eshel Yaron <me <at> eshelyaron.com>,
 79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Tue, 5 Aug 2025 07:34:49 -0400
[Message part 1 (text/plain, inline)]
On Tue, Aug 5, 2025, 6:47 AM Sean Whitton <spwhitton <at> spwhitton.name> wrote:

> Hello,
>
> On Wed 30 Jul 2025 at 09:41am -04, Spencer Baugh via "Bug reports for GNU
> Emacs, the Swiss army knife of text editors" wrote:
>
> > Sean Whitton <spwhitton <at> spwhitton.name> writes:
> >> Hello,
> >>
> >> On Wed 30 Jul 2025 at 06:30am +02, Eshel Yaron wrote:
> >>
> >>> FWIW, while incorporating this new feature in my Emacs branch, I've
> made
> >>> a few experimental tweaks that eliminate these errors.  Namely, I added
> >>> a variable vc-switch-working-tree-function which vc-switch-working-tree
> >>> consults to do the actual switching.  By default this variable is set
> to
> >>> a function that works for file-visiting buffers (similarly to the
> >>> current implementation in master), but major modes can readily set this
> >>> variable buffer-locally to provide worktree-switching support also for
> >>> non-file buffers.  I used this indirection to support Dired buffers.
> >>
> >> Interesting, though it seems to me that instead of adding a whole new
> >> variable vc-switch-working-tree-function, someone could just write a
> >> custom command and bind that to 'C-x v w w'?  Wouldn't that pretty much
> >> cover it?
> >
> > No, because multiple other packages providing special buffers might want
> > to integrate with the existing C-x v w w command.
>
> Ah, are you thinking they would do this by using add-function on
> vc-switch-working-tree-function?
>

No, just by setting that variable buffer locally.

>
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Tue, 05 Aug 2025 12:06:01 GMT) Full text and rfc822 format available.

Message #32 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Eshel Yaron <me <at> eshelyaron.com>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: Dmitry Gutov <dmitry <at> gutov.dev>, 79126 <at> debbugs.gnu.org,
 Sean Whitton <spwhitton <at> spwhitton.name>
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Tue, 05 Aug 2025 14:05:02 +0200
Spencer Baugh <sbaugh <at> janestreet.com> writes:

> On Tue, Aug 5, 2025, 6:47 AM Sean Whitton <spwhitton <at> spwhitton.name> wrote:
>
>  Hello,
>
>  On Wed 30 Jul 2025 at 09:41am -04, Spencer Baugh via "Bug reports for GNU Emacs, the Swiss army
>  knife of text editors" wrote:
>
>  > Sean Whitton <spwhitton <at> spwhitton.name> writes:
>  >> Hello,
>  >>
>  >> On Wed 30 Jul 2025 at 06:30am +02, Eshel Yaron wrote:
>  >>
>  >>> FWIW, while incorporating this new feature in my Emacs branch, I've made
>  >>> a few experimental tweaks that eliminate these errors.  Namely, I added
>  >>> a variable vc-switch-working-tree-function which vc-switch-working-tree
>  >>> consults to do the actual switching.  By default this variable is set to
>  >>> a function that works for file-visiting buffers (similarly to the
>  >>> current implementation in master), but major modes can readily set this
>  >>> variable buffer-locally to provide worktree-switching support also for
>  >>> non-file buffers.  I used this indirection to support Dired buffers.
>  >>
>  >> Interesting, though it seems to me that instead of adding a whole new
>  >> variable vc-switch-working-tree-function, someone could just write a
>  >> custom command and bind that to 'C-x v w w'?  Wouldn't that pretty much
>  >> cover it?
>  >
>  > No, because multiple other packages providing special buffers might want
>  > to integrate with the existing C-x v w w command.
>
>  Ah, are you thinking they would do this by using add-function on
>  vc-switch-working-tree-function?
>
> No, just by setting that variable buffer locally.

Exactly, that'd be the usual way to use this variable.


Eshel




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Tue, 05 Aug 2025 12:31:02 GMT) Full text and rfc822 format available.

Message #35 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Sean Whitton <spwhitton <at> spwhitton.name>
Cc: sbaugh <at> janestreet.com, 79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Tue, 5 Aug 2025 15:30:21 +0300
On 05/08/2025 13:45, Sean Whitton wrote:
>>> The last resort fallback could possibly be to call project-switch-project?
>> Probably not - it would show the prompt a second time, right?
> No, I mean calling project-switch-project non-interactively and passing
> it the root directory.  Then the user would get some options of exactly
> what to do.

Adhering to project-switch-commands might be a fine idea, indeed. 
Although I'd probably prefer to just use Dired, myself.

>> And the last step in the algorithm from the previous paragraph would visit the
>> worktree root, I think, so there shouldn't be a scenario of a complete
>> failure.
> True, but maybe failing all the way up to the root should be a special
> case.

Semantically, just going by the command's name, it seems to me that 
switching to a different directory is the key part of its behavior, and 
finding a corresponding file - a secondary one.

Perhaps we'll want to add a command called 'vc-worktree-find-matching-file'?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Wed, 06 Aug 2025 14:09:01 GMT) Full text and rfc822 format available.

Message #38 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Dmitry Gutov <dmitry <at> gutov.dev>, Spencer Baugh <sbaugh <at> janestreet.com>,
 Eshel Yaron <me <at> eshelyaron.com>
Cc: 79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Wed, 06 Aug 2025 15:08:17 +0100
[Message part 1 (text/plain, inline)]
Hello,

Thank you all for the comments.  Please find attached an implementation.

On Tue 05 Aug 2025 at 03:30pm +03, Dmitry Gutov wrote:

> On 05/08/2025 13:45, Sean Whitton wrote:
>>>> The last resort fallback could possibly be to call project-switch-project?
>>> Probably not - it would show the prompt a second time, right?
>> No, I mean calling project-switch-project non-interactively and passing
>> it the root directory.  Then the user would get some options of exactly
>> what to do.
>
> Adhering to project-switch-commands might be a fine idea, indeed. Although I'd
> probably prefer to just use Dired, myself.

Skipped that idea for now.

>>> And the last step in the algorithm from the previous paragraph would visit the
>>> worktree root, I think, so there shouldn't be a scenario of a complete
>>> failure.
>> True, but maybe failing all the way up to the root should be a special
>> case.
>
> Semantically, just going by the command's name, it seems to me that switching
> to a different directory is the key part of its behavior, and finding a
> corresponding file - a secondary one.
>
> Perhaps we'll want to add a command called 'vc-worktree-find-matching-file'?

I've done it within project-find-matching-file for now but am certainly
open to renaming that function or moving things around -- let me know
what you think.

-- 
Sean Whitton
[0001-Generalize-project-find-matching-file-to-other-major.patch (text/x-diff, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Wed, 06 Aug 2025 14:39:02 GMT) Full text and rfc822 format available.

Message #41 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Sean Whitton <spwhitton <at> spwhitton.name>,
 Spencer Baugh <sbaugh <at> janestreet.com>, Eshel Yaron <me <at> eshelyaron.com>
Cc: 79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Wed, 6 Aug 2025 17:37:50 +0300
On 06/08/2025 17:08, Sean Whitton wrote:
> +;; The default value works for file-visiting and Dired buffers.
> +;; Non-file-visiting major modes (other than `dired-mode'), where there
> +;; is a sensible notion of a matching buffer, can set this.
> +;; File-visiting major modes shouldn't set it, except possibly some
> +;; highly specialized ones.
> +(defvar project-find-matching-buffer-function #'project-find-matching-file
> +  "Function to switch to a matching buffer in another project.
> +Usually set buffer-locally by non-file-visiting major modes.
> +The function will be called with no arguments.  If the other project is
> +already determined, `project-current-directory-override' will be bound
> +to a directory under that other project.  Otherwise the function should
> +prompt for the other project, usually with `project-read-project'.")

How about we try to simplify that hook?

The command will check whether there is an overriding project and pass 
that value as an argument to project-find-matching-buffer-function. Or 
just the root directory, is that is simpler.

Or two arguments: current-root and new-root. That should cut the default 
function's definition by about a third, and do even better for the 
specialized ones.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Wed, 06 Aug 2025 16:07:01 GMT) Full text and rfc822 format available.

Message #44 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: Eshel Yaron <me <at> eshelyaron.com>, 79126 <at> debbugs.gnu.org,
 Sean Whitton <spwhitton <at> spwhitton.name>
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Wed, 06 Aug 2025 12:06:50 -0400
Dmitry Gutov <dmitry <at> gutov.dev> writes:

> On 06/08/2025 17:08, Sean Whitton wrote:
>> +;; The default value works for file-visiting and Dired buffers.
>> +;; Non-file-visiting major modes (other than `dired-mode'), where there
>> +;; is a sensible notion of a matching buffer, can set this.
>> +;; File-visiting major modes shouldn't set it, except possibly some
>> +;; highly specialized ones.
>> +(defvar project-find-matching-buffer-function #'project-find-matching-file
>> +  "Function to switch to a matching buffer in another project.
>> +Usually set buffer-locally by non-file-visiting major modes.
>> +The function will be called with no arguments.  If the other project is
>> +already determined, `project-current-directory-override' will be bound
>> +to a directory under that other project.  Otherwise the function should
>> +prompt for the other project, usually with `project-read-project'.")
>
> How about we try to simplify that hook?
>
> The command will check whether there is an overriding project and pass
> that value as an argument to project-find-matching-buffer-function. Or
> just the root directory, is that is simpler.
>
> Or two arguments: current-root and new-root. That should cut the
> default function's definition by about a third, and do even better for
> the specialized ones.

Yes, I agree with that, we should at least pass the new project as an
argument.  Passing the current project too sounds even better.

IMO, it's slightly nicer to pass project objects rather than the root
file names, since that avoids duplicate filesystem accesses to find
project information (e.g. the vc backend) when necessary, but either way
is fine.

(This is maybe overengineering, but: we could even make it take *either*
a root file name or a project object, so that callers can pass whatever
is most convenient for them.  Then the code inside could use some new
helper function which when passed a file name, returns (project-current
nil file-name), and when passed anything else, returns that thing.  That
might be simple enough, and this function would be fairly useful I
think)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Wed, 06 Aug 2025 16:16:01 GMT) Full text and rfc822 format available.

Message #47 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Eshel Yaron <me <at> eshelyaron.com>
To: Sean Whitton <spwhitton <at> spwhitton.name>
Cc: Dmitry Gutov <dmitry <at> gutov.dev>, 79126 <at> debbugs.gnu.org,
 Spencer Baugh <sbaugh <at> janestreet.com>
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Wed, 06 Aug 2025 18:15:32 +0200
Hi,

Sean Whitton <spwhitton <at> spwhitton.name> writes:

> Hello,
>
> Thank you all for the comments.  Please find attached an implementation.

[...]

> From a458eb6a117408821c7ec304c7bef60cf4a544ab Mon Sep 17 00:00:00 2001
> From: Sean Whitton <spwhitton <at> spwhitton.name>
> Date: Wed, 6 Aug 2025 15:05:08 +0100
> Subject: [PATCH] Generalize project-find-matching-file to other major modes
>
> * lisp/progmodes/project.el (dired-current-directory): Declare.
> (project-find-matching-file): Handle Dired buffers (bug#79126).

Any good reason to special-case Dired?  Wouldn't it be nicer to have
Dired set project-find-matching-buffer-function appropriately, as I do
in my implementation with vc-switch-working-tree-function? :)

[...]

> +                               (dirp (dired-current-directory))

I don't think dired-current-directory is the right choice here.  It does
the wrong thing when point is in a subdir added with 'i' (it gives you
the subdir, not the dir of the current buffer).  I use:

  (car (ensure-list dired-directory))

Perhaps there's an even cleaner way to do that, but I don't know of one.


Best,

Eshel




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Wed, 06 Aug 2025 17:37:02 GMT) Full text and rfc822 format available.

Message #50 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Spencer Baugh <sbaugh <at> janestreet.com>, Dmitry Gutov <dmitry <at> gutov.dev>,
 Eshel Yaron <me <at> eshelyaron.com>,  79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Wed, 06 Aug 2025 18:36:01 +0100
Hello,

On Wed 06 Aug 2025 at 12:06pm -04, Spencer Baugh wrote:

> Dmitry Gutov <dmitry <at> gutov.dev> writes:
>
>> On 06/08/2025 17:08, Sean Whitton wrote:
>>> +;; The default value works for file-visiting and Dired buffers.
>>> +;; Non-file-visiting major modes (other than `dired-mode'), where there
>>> +;; is a sensible notion of a matching buffer, can set this.
>>> +;; File-visiting major modes shouldn't set it, except possibly some
>>> +;; highly specialized ones.
>>> +(defvar project-find-matching-buffer-function #'project-find-matching-file
>>> +  "Function to switch to a matching buffer in another project.
>>> +Usually set buffer-locally by non-file-visiting major modes.
>>> +The function will be called with no arguments.  If the other project is
>>> +already determined, `project-current-directory-override' will be bound
>>> +to a directory under that other project.  Otherwise the function should
>>> +prompt for the other project, usually with `project-read-project'.")
>>
>> How about we try to simplify that hook?
>>
>> The command will check whether there is an overriding project and pass
>> that value as an argument to project-find-matching-buffer-function. Or
>> just the root directory, is that is simpler.
>>
>> Or two arguments: current-root and new-root. That should cut the
>> default function's definition by about a third, and do even better for
>> the specialized ones.
>
> Yes, I agree with that, we should at least pass the new project as an
> argument.  Passing the current project too sounds even better.
>
> IMO, it's slightly nicer to pass project objects rather than the root
> file names, since that avoids duplicate filesystem accesses to find
> project information (e.g. the vc backend) when necessary, but either way
> is fine.
>
> (This is maybe overengineering, but: we could even make it take *either*
> a root file name or a project object, so that callers can pass whatever
> is most convenient for them.  Then the code inside could use some new
> helper function which when passed a file name, returns (project-current
> nil file-name), and when passed anything else, returns that thing.  That
> might be simple enough, and this function would be fairly useful I
> think)

Sounds good, I agree with factoring things out along these lines.

I think we might want a function which wraps the (funcall
project-find-matching-buffer-function), and that could handle ensuring a
project object.

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Wed, 06 Aug 2025 17:38:02 GMT) Full text and rfc822 format available.

Message #53 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Eshel Yaron <me <at> eshelyaron.com>
Cc: Dmitry Gutov <dmitry <at> gutov.dev>, 79126 <at> debbugs.gnu.org,
 Spencer Baugh <sbaugh <at> janestreet.com>
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Wed, 06 Aug 2025 18:37:44 +0100
Hello,

On Wed 06 Aug 2025 at 06:15pm +02, Eshel Yaron wrote:

> Hi,
>
> Sean Whitton <spwhitton <at> spwhitton.name> writes:
>
>> Hello,
>>
>> Thank you all for the comments.  Please find attached an implementation.
>
> [...]
>
>> From a458eb6a117408821c7ec304c7bef60cf4a544ab Mon Sep 17 00:00:00 2001
>> From: Sean Whitton <spwhitton <at> spwhitton.name>
>> Date: Wed, 6 Aug 2025 15:05:08 +0100
>> Subject: [PATCH] Generalize project-find-matching-file to other major modes
>>
>> * lisp/progmodes/project.el (dired-current-directory): Declare.
>> (project-find-matching-file): Handle Dired buffers (bug#79126).
>
> Any good reason to special-case Dired?  Wouldn't it be nicer to have
> Dired set project-find-matching-buffer-function appropriately, as I do
> in my implementation with vc-switch-working-tree-function? :)

Heh.  I tried that first, but found myself duplicating code, so decided
that folding it into project-find-matching-file was neatest.

> [...]
>
>> +                               (dirp (dired-current-directory))
>
> I don't think dired-current-directory is the right choice here.  It does
> the wrong thing when point is in a subdir added with 'i' (it gives you
> the subdir, not the dir of the current buffer).

This was deliberate.  To me it seems desirable to look for the matching
subdirectory.  Sounds like you disagree?

-- 
Sean Whitton




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Thu, 07 Aug 2025 01:36:02 GMT) Full text and rfc822 format available.

Message #56 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: Eshel Yaron <me <at> eshelyaron.com>, 79126 <at> debbugs.gnu.org,
 Sean Whitton <spwhitton <at> spwhitton.name>
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Thu, 7 Aug 2025 04:35:12 +0300
On 06/08/2025 19:06, Spencer Baugh wrote:
> (This is maybe overengineering, but: we could even make it take*either*
> a root file name or a project object, so that callers can pass whatever
> is most convenient for them.

Not sure there will be other callers for it. Or not many anyway.

> Then the code inside could use some new
> helper function which when passed a file name, returns (project-current
> nil file-name), and when passed anything else, returns that thing.  That
> might be simple enough, and this function would be fairly useful I
> think)

If the value needs to be passed through a helper, we could just pass it 
through 'project-root'. The project values must be available in the 
caller already, so let's just standardize on those.

(We're probably coming from different schools of design: you're thinking 
in ADTs where it's normal to have something like "Thing | String" as a 
parameter type, and I'm thinking more in OOP where you pass a type, or a 
supertype - like a general protocol - but rarely a union of disjoint 
types, and if that happens, they are usually all primitive types).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Thu, 07 Aug 2025 05:52:02 GMT) Full text and rfc822 format available.

Message #59 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Eshel Yaron <me <at> eshelyaron.com>
To: Sean Whitton <spwhitton <at> spwhitton.name>
Cc: Dmitry Gutov <dmitry <at> gutov.dev>, 79126 <at> debbugs.gnu.org,
 Spencer Baugh <sbaugh <at> janestreet.com>
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Thu, 07 Aug 2025 07:51:26 +0200
Sean Whitton <spwhitton <at> spwhitton.name> writes:
>
> On Wed 06 Aug 2025 at 06:15pm +02, Eshel Yaron wrote:
>>
>> Sean Whitton <spwhitton <at> spwhitton.name> writes:
>>>
>>> * lisp/progmodes/project.el (dired-current-directory): Declare.
>>> (project-find-matching-file): Handle Dired buffers (bug#79126).
>>
>> Any good reason to special-case Dired?  Wouldn't it be nicer to have
>> Dired set project-find-matching-buffer-function appropriately, as I do
>> in my implementation with vc-switch-working-tree-function? :)
>
> Heh.  I tried that first, but found myself duplicating code, so decided
> that folding it into project-find-matching-file was neatest.

I see.  Note that if you stumbled upon such need to duplicate code,
others trying to use this variable to support additional buffers (say,
Shell buffers) will likely have similar difficulties.  In other words,
it's an indication that the extension mechanism could be more convenient
or could benefit from some helper function(s) to avoid duplication.

>>> +                               (dirp (dired-current-directory))
>>
>> I don't think dired-current-directory is the right choice here.  It does
>> the wrong thing when point is in a subdir added with 'i' (it gives you
>> the subdir, not the dir of the current buffer).
>
> This was deliberate.  To me it seems desirable to look for the matching
> subdirectory.  Sounds like you disagree?

It's nothing crucial, but IMO getting a different result depending on
the position of point in the Dired buffer is slightly non-intuitive.
Few will probably experience this difference in practice, so it doesn't
matter to much either way.


Best,

Eshel





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Thu, 07 Aug 2025 12:39:01 GMT) Full text and rfc822 format available.

Message #62 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Dmitry Gutov <dmitry <at> gutov.dev>, Spencer Baugh <sbaugh <at> janestreet.com>,
 Eshel Yaron <me <at> eshelyaron.com>
Cc: 79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Thu, 07 Aug 2025 13:38:44 +0100
[Message part 1 (text/plain, inline)]
Hello,

Thanks again all.  Here's the revised patch.

-- 
Sean Whitton
[v2-0001-Generalize-finding-project-matching-files-to-othe.patch (text/x-diff, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79126; Package emacs. (Fri, 08 Aug 2025 00:36:02 GMT) Full text and rfc822 format available.

Message #65 received at 79126 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Sean Whitton <spwhitton <at> spwhitton.name>,
 Spencer Baugh <sbaugh <at> janestreet.com>, Eshel Yaron <me <at> eshelyaron.com>
Cc: 79126 <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Fri, 8 Aug 2025 03:35:05 +0300
On 07/08/2025 15:38, Sean Whitton wrote:
> Thanks again all.  Here's the revised patch.

Nice! Looking good.

> +;; The default value works for file-visiting and Dired buffers.
> +;; Non-file-visiting major modes (other than `dired-mode'), where there
> +;; is a sensible notion of a matching buffer, can set this.
> +;; File-visiting major modes shouldn't set it, except possibly some
> +;; highly specialized ones.
> +(defvar project-find-matching-buffer-function
> +  #'project-find-matching-file-or-directory
> +  "Function to switch to a matching buffer in another project.
> +Usually set buffer-locally by non-file-visiting major modes.
> +The function will be called with two arguments, the project instance for
> +this buffer's project, and the project instance for the matching buffer.")

I suggest to try to get more of the info from the comment into the 
docstring.

> +         (dirp (derived-mode-p 'dired-mode))

One more thing to try is not to specialize on Dired mode: and default to 
assuming that any buffer without buffer-file-name is "dirp". The default 
implementation would either find/create a Dired buffer in the same dir, 
or even search through the buffer list for a buffer with matching values 
of major-mode and default-directory.

This is optional, just something that came to mind.




Reply sent to Sean Whitton <spwhitton <at> spwhitton.name>:
You have taken responsibility. (Fri, 08 Aug 2025 10:19:02 GMT) Full text and rfc822 format available.

Notification sent to Dmitry Gutov <dmitry <at> gutov.dev>:
bug acknowledged by developer. (Fri, 08 Aug 2025 10:19:02 GMT) Full text and rfc822 format available.

Message #70 received at 79126-done <at> debbugs.gnu.org (full text, mbox):

From: Sean Whitton <spwhitton <at> spwhitton.name>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: Spencer Baugh <sbaugh <at> janestreet.com>, Eshel Yaron <me <at> eshelyaron.com>,
 79126-done <at> debbugs.gnu.org
Subject: Re: bug#79126: vc-switch-working-tree does not work if there is no
 matching file
Date: Fri, 08 Aug 2025 11:18:45 +0100
Hello,

On Fri 08 Aug 2025 at 03:35am +03, Dmitry Gutov wrote:

> On 07/08/2025 15:38, Sean Whitton wrote:
>> Thanks again all.  Here's the revised patch.
>
> Nice! Looking good.
>
>> +;; The default value works for file-visiting and Dired buffers.
>> +;; Non-file-visiting major modes (other than `dired-mode'), where there
>> +;; is a sensible notion of a matching buffer, can set this.
>> +;; File-visiting major modes shouldn't set it, except possibly some
>> +;; highly specialized ones.
>> +(defvar project-find-matching-buffer-function
>> +  #'project-find-matching-file-or-directory
>> +  "Function to switch to a matching buffer in another project.
>> +Usually set buffer-locally by non-file-visiting major modes.
>> +The function will be called with two arguments, the project instance for
>> +this buffer's project, and the project instance for the matching buffer.")
>
> I suggest to try to get more of the info from the comment into the docstring.

Thanks yeah, I think it's fine to just move it all in, as a second
paragraph.

>> +         (dirp (derived-mode-p 'dired-mode))
>
> One more thing to try is not to specialize on Dired mode: and default to
> assuming that any buffer without buffer-file-name is "dirp".

This seems like a useful fallback -- it gets you into a buffer with the
default-directory you wanted, so you could conveniently run some other
command in the right place, even if the dired buffer isn't much use.

> The default implementation would either find/create a Dired buffer in
> the same dir, or even search through the buffer list for a buffer with
> matching values of major-mode and default-directory.

I believe that find-file/dired already handle reusing buffers if they
already exist, so we don't need to search.

Installed and closing the bug.

-- 
Sean Whitton




This bug report was last modified 2 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.