From 82009df4de536366097db9c28a139469b3e81ff0 Mon Sep 17 00:00:00 2001 From: Spencer Baugh Date: Wed, 1 Jul 2026 15:39:31 -0400 Subject: [PATCH] Fix initials completion style after // in file name * lisp/minibuffer.el (completion-initials-expand): Change the heuristic to check for an empty previous field, not total string length (bug#81241). * test/lisp/minibuffer-tests.el (completion-initials): New test. --- lisp/minibuffer.el | 8 +++++--- test/lisp/minibuffer-tests.el | 12 ++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 4db3d0d0bea..5b1486d2af4 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -5070,12 +5070,14 @@ usual. Returns (ALL PAT PREFIX SUFFIX)." ;; to /usr/share/a/e just because we mistyped "ae" for "ar", ;; so we probably don't want initials to touch anything that ;; looks like /usr/share/foo. As a heuristic, we just check that - ;; the text before the boundary char is at most 1 char. - ;; This allows both ~/eee and /eee and not much more. + ;; the previous completion field is empty. + ;; This allows ~/eee and /eee and /usr//eee and not much more. ;; FIXME: It sadly also disallows the use of ~/eee when that's ;; embedded within something else (e.g. "(~/eee" in Info node ;; completion or "ancestor:/eee" in bzr-revision completion). - (when (< (car bounds) 3) + (when (let ((str-without-last-field (substring str 0 (1- (car bounds))))) + (= (car (completion-boundaries str-without-last-field table pred "")) + (length str-without-last-field))) (let ((sep (substring str (1- (car bounds)) (car bounds)))) ;; FIXME: the above string-match checks the whole string, whereas ;; we end up only caring about the after-boundary part. diff --git a/test/lisp/minibuffer-tests.el b/test/lisp/minibuffer-tests.el index 1db0c07f510..59ae6ae3758 100644 --- a/test/lisp/minibuffer-tests.el +++ b/test/lisp/minibuffer-tests.el @@ -355,6 +355,18 @@ ("sources/clang" "sys/class") "pcm/" ""))))) +(ert-deftest completion-initials () + ;; Should expand initials: + (should (equal (completion-initials-expand "/ttab" #'read-file-name-internal nil) + "/t/t/a/b")) + (should (equal (completion-initials-expand "~/ttab" #'read-file-name-internal nil) + "~/t/t/a/b")) + (should (equal (completion-initials-expand "/home//ttab" #'read-file-name-internal nil) + "/home//t/t/a/b")) ; bug#81241 + ;; Should not expand initials: + (should-not (completion-initials-expand "/x/ttab" #'read-file-name-internal nil)) + (should-not (completion-initials-expand "/usr/share/ttab" #'read-file-name-internal nil))) + (ert-deftest completion-pcm-test-anydelim () ;; After each delimiter is a special wildcard which matches any ;; sequence of delimiters.