unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Dmitry Gutov <dgutov@yandex.ru>
To: Sean Devlin <spd@toadstyle.org>
Cc: 58784@debbugs.gnu.org
Subject: bug#58784: 28.2; project-buffers incorrect under let-bound default-directory
Date: Wed, 2 Nov 2022 01:35:58 +0200	[thread overview]
Message-ID: <208cd0a0-8244-9cac-ff16-9ef23b56ca9b@yandex.ru> (raw)
In-Reply-To: <938BB7EA-3902-4025-98B5-914D514B4A63@toadstyle.org>

Hi Sean,

On 31.10.2022 19:47, Sean Devlin wrote:

>>> In the last form, project-buffers includes the current buffer (i.e. the
>>> scratch buffer in our example) with the results. (This is true even if
>>> the current buffer is visiting a file in some unrelated directory.)
>>> This matters because the command project-switch-project let-binds
>>> default-directory before calling project-switch-commands. This means
>>> that if you set project-switch-commands to some function that calls
>>> project-buffers, you will get incorrect results.
>>> For example, evaluate the following forms in order:
>>> (defun my-list-project-buffers ()
>>>    "List the current project's buffers."
>>>    (interactive)
>>>    (let ((buffer-list (project-buffers (project-current t)))
>>> 	(buffer-name (project-prefixed-buffer-name "my-project-buffer-list")))
>>>      (with-current-buffer (get-buffer-create buffer-name)
>>>        (erase-buffer)
>>>        (save-excursion
>>> 	(dolist (buffer buffer-list)
>>> 	  (insert (buffer-name buffer))
>>> 	  (insert ?\n))))
>>>      (switch-to-buffer buffer-name)))
>>> (setq project-switch-commands #'my-list-project-buffers)
>>
>> Looks like a reimplementation of projectile-ibuffer, seems useful.
> 
> Yeah, in my real configuration, I defined this as an ibuffer filter, but I thought a simpler example would be better for the bug report.

Right, thanks.

>>> ;; list tmpfile but also scratch
>>> (project-switch-project "/tmp/")
>>
>> Not sure how to fix this, though. In bug#53626 we discussed a somewhat similar problem, and a let-binding seems impossible to "escape".
>>
>> What else can we do? One option is to change the signature of every compatible command to take the project object as its first argument. Might have been more realistic when the package was first written, too much breakage now, probably.
>>
>> Another would be to add a new var to help override the project choice without touch default-directory.
>>
>> Something like the attached. Please try it out.<project-current-directory-override.diff>
> 
> I agree, the fix is not obvious.
> 
> A workaround I used in my configuration is to add an advice to project-switch-project to wrap it in a with-temp-buffer form. This way, it’s only the default-directory of the temp buffer that gets corrupted. Not a very clean solution, but it seems to work. Unfortunately, you need to remember to do this in many places; for example, I had to do the same thing in my project-ibuffer command.
> 
> Your solution looks cleaner. I gave it a try (along with disabling my advice), and it seems to work pretty well. Thanks for the fix!

Actually I like your solution better. It might be less obvious when 
reading, but it's shorter and fully backward compatible.

So I just pushed that fix to master.

> There might be some more places where it needs to be applied. For example, project-prefixed-buffer-name still inspects the default-directory. (Maybe project-prefixed-buffer-name should just call project-root or similar?)

In both places where project-prefixed-buffer-name is currently invoked, 
default-directory is set a specific binding just before that. So I think 
it would have been fine even with the other fix.

Or on a higher level, it acts on the current buffer, so referencing 
default-directory seems okay.

> I think there’s still some fragility in the project-buffers function, since any callers need to be careful not to bind default-directory. It might be useful to call this out in the doc string or in the manual.

I suppose it could use improvement, but I'm not sure what phrasing would 
stop someone from making such a mistake. After all, I knew its 
implementation and made it anyway.

Perhaps the docstring should simply say that the buffers are matched on 
the basis of their default-directory value. In the default 
implementation, that is (custom backends could choose their own 
strategy). Would that help?





  reply	other threads:[~2022-11-01 23:35 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-26  0:13 bug#58784: 28.2; project-buffers incorrect under let-bound default-directory Sean Devlin
2022-10-29  0:49 ` Dmitry Gutov
2022-10-31 17:47   ` Sean Devlin
2022-11-01 23:35     ` Dmitry Gutov [this message]
2022-11-02 15:18       ` Sean Devlin
2022-11-04  1:18         ` Dmitry Gutov
2022-11-04 16:39           ` Sean Devlin
2022-11-21 18:24       ` Juri Linkov
2022-11-23  3:48         ` Dmitry Gutov
2022-11-24  2:37           ` 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=208cd0a0-8244-9cac-ff16-9ef23b56ca9b@yandex.ru \
    --to=dgutov@yandex.ru \
    --cc=58784@debbugs.gnu.org \
    --cc=spd@toadstyle.org \
    /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).