Subject: Re: bug#41412: 27.0.90; Value of default directory in completions buffer

From: Lars Ingebrigtsen <[email-masked]>
Date: Fri, 22 Jan 2021 21:28:14 +0100

Omar Antolín Camarena <[email-masked]> writes:

> There is a bit of logic in `complete-setup-function' (from simple.el)
> to set the default directory in the *Completions* buffer:
>
> ;; FIXME: This is a bad hack.  We try to set the default-directory
> ;; in the *Completions* buffer so that the relative file names
> ;; displayed there can be treated as valid file names, independently
> ;; from the completion context.  But this suffers from many problems:
> ;; - It's not clear when the completions are file names.  With some
> ;;   completion tables (e.g. bzr revision specs), the listed
> ;;   completions can mix file names and other things.
> ;; - It doesn't pay attention to possible quoting.
> ;; - With fancy completion styles, the code below will not always
> ;;   find the right base directory.
> (if minibuffer-completing-file-name
>     (file-name-as-directory
>      (expand-file-name
>       (buffer-substring (minibuffer-prompt-end)
>                         (- (point) (or completion-base-size 0))))))
>
> As the comment says, this is brittle, but better than nothing. I
> believe, however, that the `file-name-as-directory' is a typo and
> probably `file-name-directory' was intended instead.

I think that sounds likely.  The patch that introduced this code is
below, and it indeed changes the `file-name-directory' to
`file-name-as-directory' (among other things).

I've added Stafan M to the CCs -- was this done on purpose, or should we
go back to `file-name-directory' here?

diff --git a/lisp/simple.el b/lisp/simple.el
index 082605f659..13c75c4d7b 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5851,20 +5851,22 @@ completion-root-regexp
 ;; after the text of the completion list buffer is written.
 (defun completion-setup-function ()
   (let* ((mainbuf (current-buffer))
-         (mbuf-contents (minibuffer-completion-contents))
-         common-string-length)
-    ;; When reading a file name in the minibuffer,
-    ;; set default-directory in the minibuffer
-    ;; so it will get copied into the completion list buffer.
-    (if minibuffer-completing-file-name
-	(with-current-buffer mainbuf
-	  (setq default-directory
-                (file-name-directory (expand-file-name mbuf-contents)))))
+         (base-dir
+          ;; When reading a file name in the minibuffer,
+          ;; try and find the right default-directory to set in the
+          ;; completion list buffer.
+          ;; FIXME: Why do we do that, actually?  --Stef
+          (if minibuffer-completing-file-name
+              (file-name-as-directory
+               (expand-file-name
+                (substring (minibuffer-completion-contents)
+                           0 (or completion-base-size 0)))))))
     (with-current-buffer standard-output
       (let ((base-size completion-base-size)) ;Read before killing localvars.
         (completion-list-mode)
         (set (make-local-variable 'completion-base-size) base-size))
       (set (make-local-variable 'completion-reference-buffer) mainbuf)
+      (if base-dir (setq default-directory base-dir))
       (unless completion-base-size
         ;; This shouldn't be needed any more, but further analysis is needed
         ;; to make sure it's the case.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no