GNU bug report logs -
#79236
30.1; file-directory-p in read-file-name prevents TRAMP protocol, user, and host completions
Previous Next
To reply to this bug, email your comments to 79236 AT debbugs.gnu.org.
There is no need to reopen the bug first.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#79236
; Package
emacs
.
(Thu, 14 Aug 2025 13:38:02 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
"Timothy J. Miller" <tmiller <at> mitre.org>
:
New bug report received and forwarded. Copy sent to
bug-gnu-emacs <at> gnu.org
.
(Thu, 14 Aug 2025 13:38:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From `emacs -Q`:
(require 'tramp)
(read-file-name "With file-directory-p: " default-directory nil t
nil 'file-directory-p)
- Type "/<TAB>" at the prompt. TRAMP protocols are missing from
the completions list.
- Type "/ssh:<TAB>" at the prompt. TRAMP username & hostname are
missing from the completion list.
By way of contrast:
(read-file-name "Without file-directory-p: " default-directory nil
t nil nil)
Repeating the two test cases above, TRAMP suggestions are present.
read-directory-name calls read-file-name with file-directory-p as
the match predicate, and project.el project-prompt-project-dir
loads new projects with read-directory-name. This bug prevents
easy selection of projects on remote servers. Because find-file
works correctly with the same emacs configuration, this breaks
user expectations.
In GNU Emacs 30.1 (build 1, aarch64-apple-darwin21.6.0, NS
appkit-2113.65 Version 12.7.6 (Build 21H1320)) of 2025-02-24
built on armbob.lan
Windowing system distributor 'Apple', version 10.3.2575
System Description: macOS 15.6
Configured using:
'configure --with-ns
'--enable-locallisppath=/Library/Application
Support/Emacs/${version}/site-lisp:/Library/Application
Support/Emacs/site-lisp' --with-modules
'CFLAGS=-DFD_SETSIZE=10000 -DDARWIN_UNLIMITED_SELECT'
--with-x-toolkit=no'
Configured features:
ACL GLIB GMP GNUTLS JPEG LIBXML2 MODULES NOTIFY KQUEUE NS PDUMPER
PNG RSVG SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER
WEBP XIM ZLIB
Important settings:
value of $LANG: en_US.UTF-8
locale-coding-system: utf-8-unix
Major mode: ELisp/l
Minor modes in effect:
pixel-scroll-precision-mode: t
mu4e-modeline-mode: t
delete-selection-mode: t
vertico-mouse-mode: t
vertico-mode: t
nerd-icons-completion-mode: t
marginalia-mode: t
corfu-history-mode: t
savehist-mode: t
corfu-popupinfo-mode: t
global-corfu-mode: t
corfu-mode: t
global-hl-todo-mode: t
hl-todo-mode: t
doom-modeline-mode: t
yas-global-mode: t
yas-minor-mode: t
csv-field-index-mode: t
pdf-occur-global-minor-mode: t
global-fish-completion-mode: t
fish-completion-mode: t
override-global-mode: t
global-auto-revert-mode: t
auto-insert-mode: t
electric-pair-mode: t
which-key-mode: t
xterm-mouse-mode: t
global-eldoc-mode: t
eldoc-mode: t
show-paren-mode: t
electric-layout-mode: t
electric-indent-mode: t
mouse-wheel-mode: t
tab-bar-mode: t
menu-bar-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
minibuffer-regexp-mode: t
line-number-mode: t
indent-tabs-mode: t
transient-mark-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
Load-path shadows:
/Users/tmiller/.emacs.d/elpa/ef-themes-1.10.0/theme-loaddefs hides
/Applications/Emacs.app/Contents/Resources/lisp/theme-loaddefs
Features:
(mailalias mailclient textsec uni-scripts idna-mapping
uni-confusable textsec-check shadow mail-extr emacsbug shortdoc
comp-common epa-file pixel-scroll cua-base flyspell ispell
log-edit add-log vc-src vc-sccs vc-svn vc-cvs vc-rcs log-view
pcvs-util vc-dir vc dired-aux nerd-icons-dired mu4e-icalendar
gnus-icalendar org-capture icalendar diary-lib diary-loaddefs
cus-start mu4e mu4e-org mu4e-notification notifications mu4e-main
smtpmail mu4e-view mu4e-mime-parts crm mu4e-headers mu4e-thread
mu4e-actions mu4e-compose mu4e-draft gnus-msg gnus-art mm-uu
mml2015 mm-view mml-smime smime dig gnus-sum gnus-group gnus-undo
gnus-start gnus-dbus dbus gnus-cloud nnimap nnmail mail-source
utf7 nnoo gnus-spec gnus-int gnus-range gnus-win gnus nnheader
range mu4e-search mu4e-lists mu4e-bookmarks mu4e-mark
mu4e-message shr pixel-fill kinsoku url-file svg xml dom
flow-fill hl-line mu4e-contacts mu4e-update mu4e-folders
mu4e-context mu4e-query-items mu4e-server mu4e-modeline mu4e-vars
mu4e-helpers mu4e-config mu4e-window ido message sendmail rfc822
mml mml-sec epa epg rfc6068 epg-config gnus-util mm-decode
mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 mm-util
ietf-drums mail-prsvr mailabbrev mail-utils gmm-utils mailheader
mu4e-obsolete em-unix em-term term disp-table ehelp em-script
em-prompt em-pred em-ls em-hist em-glob em-extpipe em-basic
em-banner em-alias em-tramp em-rebind em-smart misearch
multi-isearch pdf-sync pdf-annot facemenu pdf-outline pdf-links
pdf-history vertico-directory embark-consult consult yank-media
markdown-mode vc-hg vc-bzr pyvenv vc-git vc-dispatcher tramp-cmds
vertico-sort tramp-cache time-stamp tramp-sh face-remap pulse
color eglot external-completion jsonrpc flymake diff ert ewoc
warnings combobulate-autoloads combobulate-go combobulate-json
combobulate-yaml combobulate-css combobulate-js-ts
combobulate-python combobulate-html combobulate-toml
combobulate-cursor combobulate-query derived xref scheme
combobulate-ui transient delsel vertico-mouse vertico
nerd-icons-completion marginalia nerd-icons-corfu corfu-history
savehist corfu-popupinfo corfu hl-todo doom-modeline
doom-modeline-segments doom-modeline-env doom-modeline-core
shrink-path my-email embark-org embark ffap my-prog-modes my-rego
rego-mode reformatter my-lua my-yaml my-python yasnippet-snippets
yasnippet my-text my-markdown my-org ox-odt rng-loc rng-uri
rng-parse rng-match rng-dt rng-util rng-pttrn nxml-parse nxml-ns
nxml-enc xmltok nxml-util ox-latex ox-icalendar org-agenda
ox-html table ox-ascii ox-publish ox org-attach org-glossary
org-element org-persist org-id org-refile org-element-ast inline
org ob ob-tangle ob-ref ob-lob ob-table org-macro org-src
sh-script smie executable ob-comint org-pcomplete org-list
org-footnote org-faces org-entities noutline outline org-version
ob-emacs-lisp org-table org-keys org-loaddefs thingatpt cal-menu
calendar cal-loaddefs avl-tree ol oc ob-exp ob-core org-cycle
org-fold org-fold-core org-compat ob-eval org-macs csv-mode sort
auctex pdf-occur ibuf-ext ibuffer ibuffer-loaddefs tablist advice
tablist-filter semantic/wisent/comp semantic/wisent
semantic/wisent/wisent semantic/util-modes semantic/util semantic
semantic/tag semantic/lex semantic/fw mode-local cedet
pdf-isearch pdf-misc pdf-loader pdf-tools compile pdf-view
bookmark text-property-search jka-compr pdf-cache pdf-info tq
pdf-util pdf-macs image-mode dired dired-loaddefs exif my-dired
my-eshell fish-completion em-cmpl em-dirs esh-mode esh-var eshell
esh-cmd esh-ext esh-opt esh-proc esh-io esh-arg esh-module
esh-module-loaddefs esh-util my-look nerd-icons nerd-icons-faces
nerd-icons-data nerd-icons-data-mdicon nerd-icons-data-flicon
nerd-icons-data-codicon nerd-icons-data-devicon
nerd-icons-data-sucicon nerd-icons-data-wicon
nerd-icons-data-faicon nerd-icons-data-powerline
nerd-icons-data-octicon nerd-icons-data-pomicon
nerd-icons-data-ipsicon modus-operandi-theme modus-themes
my-emacs tramp trampver tramp-integration files-x tramp-message
tramp-compat xdg shell pcomplete parse-time iso8601 time-date
tramp-loaddefs cape orderless helpful cc-langs cc-vars cc-defs
imenu trace cl-print edebug debug backtrace info-look find-func f
help-fns radix-tree elisp-refs s dash use-package-bind-key
bind-key autorevert filenotify autoinsert elec-pair which-key
xt-mouse cus-edit pp cus-load wid-edit exec-path-from-shell
gnutls puny cl-extra help-mode use-package-ensure
use-package-core auth-source-pass finder-inf async-autoloads
auctex-autoloads tex-site bash-completion-autoloads
cape-autoloads format-spec edmacro kmacro combobulate-display
let-alist combobulate-ztree combobulate-envelope
combobulate-manipulation python project compat comint ansi-osc
ring ansi-color combobulate-procedure combobulate-navigation rx
combobulate-misc combobulate-setup tempo combobulate-interface
pcase combobulate-settings diff-mode track-changes easy-mmode
treesit generator combobulate-rules consult-eglot-autoloads
consult-flyspell-autoloads corfu-terminal-autoloads
corfu-autoloads csv-mode-autoloads dired-subtree-autoloads
dired-hacks-utils-autoloads doom-modeline-autoloads
edwina-autoloads ef-themes-autoloads ein-autoloads
deferred-autoloads anaphora-autoloads embark-consult-autoloads
consult-autoloads embark-autoloads esh-autosuggest-autoloads
company-autoloads exec-path-from-shell-autoloads
fish-completion-autoloads flymake-vale-autoloads
helpful-autoloads elisp-refs-autoloads hl-todo-autoloads
ht-autoloads lorem-ipsum-autoloads marginalia-autoloads
markdown-mode-autoloads mermaid-mode-autoloads
nerd-icons-completion-autoloads nerd-icons-corfu-autoloads
nerd-icons-dired-autoloads nerd-icons-autoloads
ob-mermaid-autoloads orderless-autoloads org-glossary-autoloads
org-modern-autoloads pdf-tools-autoloads plantuml-mode-autoloads
deflate-autoloads plz-autoloads polymode-autoloads
popon-autoloads python-pytest-autoloads pyvenv-autoloads
rego-mode-autoloads reformatter-autoloads request-autoloads
shrink-path-autoloads f-autoloads dash-autoloads s-autoloads
spacious-padding-autoloads tablist-autoloads
transpose-frame-autoloads trashed-autoloads vertico-autoloads
websocket-autoloads info with-editor-autoloads yaml-autoloads
yaml-mode-autoloads yasnippet-snippets-autoloads
yasnippet-autoloads package browse-url url url-proxy url-privacy
url-expand url-methods url-history url-cookie generate-lisp-file
url-domsuf url-util mailcap url-handlers url-parse auth-source
cl-seq eieio eieio-core cl-macs icons password-cache json subr-x
map byte-opt gv bytecomp byte-compile url-vars cl-loaddefs cl-lib
rmc iso-transl tooltip cconv eldoc paren electric uniquify
ediff-hook vc-hooks lisp-float-type elisp-mode mwheel term/ns-win
ns-win ucs-normalize mule-util term/common-win tool-bar dnd
fontset image regexp-opt fringe tabulated-list replace newcomment
text-mode lisp-mode prog-mode register page tab-bar menu-bar
rfn-eshadow isearch easymenu timer select scroll-bar mouse
jit-lock font-lock syntax font-core term/tty-colors frame
minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai
tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button
loaddefs theme-loaddefs faces cus-face macroexp files window
text-properties overlay sha1 md5 base64 format env code-pages
mule custom widget keymap hashtable-print-readable backquote
threads kqueue cocoa ns multi-tty make-network-process emacs)
Memory information:
((conses 16 850905 233541) (symbols 48 55383 12) (strings 32
246882 9426) (string-bytes 1 25975776) (vectors 16 94951)
(vector-slots 8 969100 119219) (floats 8 5747 6798) (intervals 56
13062 3693) (buffers 992 47))
--
-- T
--
-- T
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#79236
; Package
emacs
.
(Fri, 15 Aug 2025 01:45:01 GMT)
Full text and
rfc822 format available.
Message #8 received at 79236 <at> debbugs.gnu.org (full text, mbox):
Timothy, thanks for the report.
Michael, what do you think? Could this be fixed in Tramp's completion,
or is there maybe a better way to use read-directory-name from
project-prompt-project-dir?
On 14/08/2025 16:34, Timothy J. Miller wrote:
> From `emacs -Q`:
>
> (require 'tramp)
> (read-file-name "With file-directory-p: " default-directory nil t
> nil 'file-directory-p)
>
> - Type "/<TAB>" at the prompt. TRAMP protocols are missing from
> the completions list.
>
> - Type "/ssh:<TAB>" at the prompt. TRAMP username & hostname are
> missing from the completion list.
>
> By way of contrast:
>
> (read-file-name "Without file-directory-p: " default-directory nil
> t nil nil)
>
> Repeating the two test cases above, TRAMP suggestions are present.
>
> read-directory-name calls read-file-name with file-directory-p as
> the match predicate, and project.el project-prompt-project-dir
> loads new projects with read-directory-name. This bug prevents
> easy selection of projects on remote servers. Because find-file
> works correctly with the same emacs configuration, this breaks
> user expectations.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#79236
; Package
emacs
.
(Fri, 15 Aug 2025 06:09:01 GMT)
Full text and
rfc822 format available.
Message #11 received at 79236 <at> debbugs.gnu.org (full text, mbox):
> Date: Fri, 15 Aug 2025 04:44:05 +0300
> From: Dmitry Gutov <dmitry <at> gutov.dev>
>
> Timothy, thanks for the report.
>
> Michael, what do you think? Could this be fixed in Tramp's completion,
> or is there maybe a better way to use read-directory-name from
> project-prompt-project-dir?
Careful: there be dragons. We don't want Tramp to load and do its
thing when there's no reason to expect remote files and directories
are relevant, because that slows down completion when the user only
wants to visit a local file or directory. There was such a problem
some years ago, and Michael fixed it.
So whatever you do for this case, be sure not to cause regressions in
the use cases where the user just wants to visit local files: Tramp
should neither load nor attempt to connect to remote servers in that
case.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#79236
; Package
emacs
.
(Sun, 17 Aug 2025 11:27:01 GMT)
Full text and
rfc822 format available.
Message #14 received at 79236 <at> debbugs.gnu.org (full text, mbox):
Eli Zaretskii <eliz <at> gnu.org> writes:
Hi,
>> Michael, what do you think? Could this be fixed in Tramp's completion,
>> or is there maybe a better way to use read-directory-name from
>> project-prompt-project-dir?
>
> Careful: there be dragons. We don't want Tramp to load and do its
> thing when there's no reason to expect remote files and directories
> are relevant, because that slows down completion when the user only
> wants to visit a local file or directory. There was such a problem
> some years ago, and Michael fixed it.
>
> So whatever you do for this case, be sure not to cause regressions in
> the use cases where the user just wants to visit local files: Tramp
> should neither load nor attempt to connect to remote servers in that
> case.
Indeed, this is mined area.
I've debugged the recipe, and the problem isn't Tramp related. It seems
to be in function completion-file-name-table, which contains the
following code:
--8<---------------cut here---------------start------------->8---
;; 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))))
--8<---------------cut here---------------end--------------->8---
Hmmm. Every hit like "/ssh:" is discarded, when the predicate is file-directory-p.
Best regards, Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#79236
; Package
emacs
.
(Mon, 18 Aug 2025 07:04:01 GMT)
Full text and
rfc822 format available.
Message #17 received at 79236 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Michael Albinus <michael.albinus <at> gmx.de> writes:
Hi,
I'm adding Stefan.
> I've debugged the recipe, and the problem isn't Tramp related. It seems
> to be in function completion-file-name-table, which contains the
> following code:
>
> ;; 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))))
>
> Hmmm. Every hit like "/ssh:" is discarded, when the predicate is file-directory-p.
The appended patch seems to fix it. But I don't know whether this is the
way to go. Stefan?
Best regards, Michael.
[Message part 2 (text/x-patch, attachment)]
Added tag(s) patch.
Request was from
Michael Albinus <michael.albinus <at> gmx.de>
to
control <at> debbugs.gnu.org
.
(Mon, 18 Aug 2025 07:04:02 GMT)
Full text and
rfc822 format available.
Reply sent
to
Michael Albinus <michael.albinus <at> gmx.de>
:
You have taken responsibility.
(Fri, 29 Aug 2025 11:54:02 GMT)
Full text and
rfc822 format available.
Notification sent
to
"Timothy J. Miller" <tmiller <at> mitre.org>
:
bug acknowledged by developer.
(Fri, 29 Aug 2025 11:54:03 GMT)
Full text and
rfc822 format available.
Message #24 received at 79236-done <at> debbugs.gnu.org (full text, mbox):
Version: 31.1
Michael Albinus <michael.albinus <at> gmx.de> writes:
Hi,
> The appended patch seems to fix it. But I don't know whether this is the
> way to go. Stefan?
No comment, so I've pushed the patch to master (plus some needed changes
in Tramp). Closing the bug.
Best regards, Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#79236
; Package
emacs
.
(Fri, 29 Aug 2025 14:54:02 GMT)
Full text and
rfc822 format available.
Message #27 received at 79236 <at> debbugs.gnu.org (full text, mbox):
> The appended patch seems to fix it. But I don't know whether this is the
> way to go. Stefan?
That looks ugly since the completion code should be "above" the
`file-name-handler-alist` abstraction and thus shouldn't have
Tramp-specific code.
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#79236
; Package
emacs
.
(Fri, 29 Aug 2025 15:23:02 GMT)
Full text and
rfc822 format available.
Message #30 received at 79236 <at> debbugs.gnu.org (full text, mbox):
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
Hi Stefan,
>> The appended patch seems to fix it. But I don't know whether this is the
>> way to go. Stefan?
>
> That looks ugly since the completion code should be "above" the
> `file-name-handler-alist` abstraction and thus shouldn't have
> Tramp-specific code.
We're speaking about completion of Tramp method, user and host
names. Something like "/ssh: user@ host:" - I've shown the word
boundaries as space.
`file-directory-p' does TRT in Tramp in this case. But it isn't called,
because of the bypass in `completion-file-name-table', which simply
looks for a trailing "/". `file-name-handler-alist' abstraction broken.
> Stefan
Best regards, Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#79236
; Package
emacs
.
(Sun, 31 Aug 2025 04:33:03 GMT)
Full text and
rfc822 format available.
Message #33 received at 79236 <at> debbugs.gnu.org (full text, mbox):
>>> The appended patch seems to fix it. But I don't know whether this is the
>>> way to go. Stefan?
>>
>> That looks ugly since the completion code should be "above" the
>> `file-name-handler-alist` abstraction and thus shouldn't have
>> Tramp-specific code.
>
> We're speaking about completion of Tramp method, user and host
> names. Something like "/ssh: user@ host:" - I've shown the word
> boundaries as space.
AFAICT the patch changes `completion-file-name-table` which knows
nothing about Tramp, so I don't understand what you mean by "We're
speaking about completion of Tramp ...".
> `file-directory-p' does TRT in Tramp in this case. But it isn't called,
> because of the bypass in `completion-file-name-table', which simply
> looks for a trailing "/". `file-name-handler-alist' abstraction broken.
Ah... right, here the code assumes that the elements returned by
`file-name-all-completions` which are directories all end in `/`, and
indeed that's not guaranteed to hold when we go through
`file-name-handler-alist`.
How 'bout the patch below instead (which generalizes your patch to
all file name handlers)?
Stefan
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 122459be062..e2920d76d92 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -3437,7 +3437,9 @@ completion-file-name-table
(unless (memq pred '(nil file-exists-p))
(let ((comp ())
(pred
- (if (eq pred 'file-directory-p)
+ (if (and (eq pred 'file-directory-p)
+ (not (find-file-name-handler
+ realdir 'file-name-all-completions)))
;; Brute-force speed up for directory checking:
;; Discard strings which don't end in a slash.
(lambda (s)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#79236
; Package
emacs
.
(Sun, 31 Aug 2025 08:21:02 GMT)
Full text and
rfc822 format available.
Message #36 received at 79236 <at> debbugs.gnu.org (full text, mbox):
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
Hi Stefan,
> How 'bout the patch below instead (which generalizes your patch to
> all file name handlers)?
That works, too. Thanks!
> Stefan
Best regards, Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#79236
; Package
emacs
.
(Mon, 01 Sep 2025 05:04:01 GMT)
Full text and
rfc822 format available.
Message #39 received at 79236-done <at> debbugs.gnu.org (full text, mbox):
>> How 'bout the patch below instead (which generalizes your patch to
>> all file name handlers)?
> That works, too. Thanks!
Pushed to master, thank you,
Stefan
This bug report was last modified 8 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.