Subject: bug#53626: 28.0.91; project-find-regexp (C-x p g) twice results in searching different projects

From: Sean Whitton <[email-masked]>
Date: Sat, 29 Jan 2022 23:28:33 -0700

Hello,

On Sat 29 Jan 2022 at 07:11pm GMT, [email-masked] wrote:

> An existing *xref* buffer doesn't have its default-directory changed
> when running project-find-regexp.  Since project-find-regexp switches to
> *xref*, that means running project-find-regexp twice in a row may search
> two different projects, which is unexpected.

I think the problem is the let bindings for default-directory
established by project-find-regexp and also project-switch-project,
which latter I was using for testing.  These bindings hide the
buffer-local value for default-directory in *xref*, such that
xref--show-xref-buffer is only able to set the binding's value, not the
real buffer-local value, and so when the let forms unwind *xref*'s old
default-directory is restored.

Neither project-find-regexp nor project-switch-project should
special-case *xref*, because it looks like xref-show-xrefs-function
could be such as not to use that buffer.

One possible fix is the following patch, plus something similar in
project-find-regexp, but it feels whack-a-mole -- there are other
similar bindings of default-directory in project.el.  And it is not
really correct because perhaps the command would like to set
default-directory in whatever buffer the command was called in, without
knowing its name as xref--show-xref-buffer does.

> @@ -1605,9 +1605,12 @@
>    (let ((command (if (symbolp project-switch-commands)
>                       project-switch-commands
>                     (project--switch-project-command))))
> -    (let ((default-directory dir)
> -          (project-current-inhibit-prompt t))
> -      (call-interactively command))))
> +    ;; Switch to a temporary buffer to avoid shadowing a buffer-local value
> +    ;; for `default-directory' that command might want to set.
> +    (with-temp-buffer
> +      (let ((default-directory dir)
> +           (project-current-inhibit-prompt t))
> +       (call-interactively command)))))
>
>  (provide 'project)
>  ;;; project.el ends here

-- 
Sean Whitton