emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/minibuffer-completion-enhancements f9c59caa378 13/35: Improve ha


From: Eshel Yaron
Subject: feature/minibuffer-completion-enhancements f9c59caa378 13/35: Improve handling of file name completion predicate
Date: Sun, 21 Jan 2024 03:54:30 -0500 (EST)

branch: feature/minibuffer-completion-enhancements
commit f9c59caa3782d8dd7737dcd113abf045117aa3c0
Author: Eshel Yaron <me@eshelyaron.com>
Commit: Eshel Yaron <me@eshelyaron.com>

    Improve handling of file name completion predicate
    
    * lisp/minibuffer.el (completion-file-name-table): Avoid hard-coding
    'file-exists-p', call predicate without directory name and set
    'default-directory' to that directory instead.
    (read-file-name): Update documentation.
    * lisp/pcomplete.el (pcomplete--entries): Handle zero-length arg.
    * doc/lispref/minibuf.texi (Reading File Names): Elaborate.
---
 doc/lispref/minibuf.texi |  4 +++-
 lisp/minibuffer.el       | 42 ++++++++++++++++--------------------------
 lisp/pcomplete.el        |  9 +++++----
 3 files changed, 24 insertions(+), 31 deletions(-)

diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi
index b565d4f095b..0c0365ca74c 100644
--- a/doc/lispref/minibuf.texi
+++ b/doc/lispref/minibuf.texi
@@ -1774,7 +1774,9 @@ current buffer visit no file using @kbd{M-x 
set-visited-file-name}.
 If @var{predicate} is non-@code{nil}, it specifies a function of one
 argument that decides which file names are acceptable completion
 alternatives.  A file name is an acceptable value if @var{predicate}
-returns non-@code{nil} for it.
+returns non-@code{nil} for it.  If @var{predicate} is @code{nil},
+@code{read-file-name} uses @code{file-exists-p}, so acceptable
+completions are existing file names.
 
 Here is an example of using @code{read-file-name}:
 
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 2722656c418..c288e421206 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -3431,11 +3431,6 @@ same as `substitute-in-file-name'."
             ;; into more such problematic cases.
             ,(min start (length string)) . ,end)))
 
-       ((eq action 'lambda)
-        (if (zerop (length string))
-            nil          ;Not sure why it's here, but it probably doesn't harm.
-          (funcall (or pred 'file-exists-p) string)))
-
        (t
         (let* ((name (file-name-nondirectory string))
                (specdir (file-name-directory string))
@@ -3448,26 +3443,17 @@ same as `substitute-in-file-name'."
                   (concat specdir comp)
                 comp)))
 
+           ((eq action 'lambda)
+            (or (not pred)
+                (let ((default-directory (expand-file-name realdir)))
+                  (funcall pred name))))
+
            ((eq action t)
             (let ((all (file-name-all-completions name realdir)))
-
-              ;; Check the predicate, if necessary.
-              (unless (memq pred '(nil file-exists-p))
-                (let ((comp ())
-                      (pred
-                       (if (eq pred 'file-directory-p)
-                           ;; Brute-force speed up for directory checking:
-                           ;; Discard strings which don't end in a slash.
-                           (lambda (s)
-                             (let ((len (length s)))
-                               (and (> len 0) (eq (aref s (1- len)) ?/))))
-                         ;; Must do it the hard (and slow) way.
-                         pred)))
-                  (let ((default-directory (expand-file-name realdir)))
-                    (dolist (tem all)
-                      (if (funcall pred tem) (push tem comp))))
-                  (setq all (nreverse comp))))
-
+              (when pred
+                (setq all
+                      (let ((default-directory (expand-file-name realdir)))
+                        (seq-filter pred all))))
               all))))))
     (file-error nil)))               ;PCM often calls with invalid directories.
 
@@ -3643,9 +3629,13 @@ full file name for INITIAL will usually lead to 
surprising
 results.
 
 Sixth arg PREDICATE, if non-nil, should be a function of one
-argument; then a file name is considered an acceptable completion
-alternative only if PREDICATE returns non-nil with the file name
-as its argument.
+argument; then a file name is considered existing (and hence an
+acceptable completion alternative) only if PREDICATE returns
+non-nil with the file name as its argument.  PREDICATE is called
+with `default-directory' bound to the direcotry part of the
+candidate file name, while the argument passed to PREDICATE does
+not include a directory part.  If PREDICATE is omitted or nil, it
+defaults to `file-exists-p'.
 
 If this command was invoked with the mouse, use a graphical file
 dialog if `use-dialog-box' is non-nil, and the window system or X
diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el
index 196c5f159cd..c6669c8d1db 100644
--- a/lisp/pcomplete.el
+++ b/lisp/pcomplete.el
@@ -897,10 +897,11 @@ this is `comint-dynamic-complete-functions'."
             (let ((file-ignore pcomplete-file-ignore)
                   (dir-ignore pcomplete-dir-ignore))
               (lambda (file)
-                (not
-                 (if (eq (aref file (1- (length file))) ?/)
-                     (and dir-ignore (string-match dir-ignore file))
-                   (and file-ignore (string-match file-ignore file))))))))
+                (and (< 0 (length file))
+                     (not
+                      (if (eq (aref file (1- (length file))) ?/)
+                          (and dir-ignore (string-match dir-ignore file))
+                        (and file-ignore (string-match file-ignore 
file)))))))))
          (reg-pred (if regexp (lambda (file) (string-match regexp file))))
          ;; `completion-file-name-table' calls `file-exists-p' when
          ;; the predicate is nil.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]