Don't cancel on input during remote file completion - #53
Merged
Merged
Conversation
For a remote file name the completion table call is a Tramp connection attempt. Aborting it with while-no-input unwinds out of the middle of the remote shell handshake, and Tramp is then left in tramp-wait-for-regexp with a nil timeout, waiting for a prompt marker the half-configured shell never prints. Emacs blocks until the connection process is killed. Vertico declines to interrupt completion for remote paths for this reason; make fussy-cancel-on-input-fn default to the same rule. Gating on minibuffer-completing-file-name keeps everything but file completion abortable while a remote directory is current.
Owner
|
Thanks, I attempted to figure this out a while back but like you mentioned it's hard to reproduce. I mostly use fzfa-tramp or fzfa-ssh these days for any tramp related mechanisms so it's rare for me to exercise this path. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Typing
/ssh:user@host:/srv/at normal speed on a cold connection hangs Emacs until I killthe ssh process.
C-gdoesn't help.fussy-all-completionswraps the table call inwhile-no-input. For a remote file name thatcall is a Tramp connection attempt, so aborting it doesn't just throw away a result, it
interrupts the remote shell handshake partway through.
SIGUSR2 backtrace:
The timeout there is nil, which per tramp.el:6547-6574 means wait forever. The connection
buffer contained:
That's a plain sh prompt, not Tramp's
///<hash>#$marker. The throw happened beforePS1got set, so the marker never arrives.
Vertico avoids this on its side (vertico.el:374-379 skips
while-no-inputandnon-essentialfor remote paths, minad/vertico#23), but fussy's wrap is inside the completion style, so that
guard doesn't apply.
#48
Probably the same line.
while-no-inputis(or (input-pending-p) (progn ,@body)), so wheninput is already pending the body never runs and you get
tback, which matches "looks frozenuntil you press down". f582245/1cb4bb4 made that branch return
fussy--current-resultinsteadof nil, which fixes the display. It doesn't help here, since the damage is the abort rather
than the return value. I opened this separately because the failure mode is different, but
feel free to fold them together.
The change
fussy-cancel-on-input-fngoes fromminibufferptofussy-cancel-on-input-p, which is thesame thing minus remote file name completion. Gating on
minibuffer-completing-file-namekeepseverything else abortable when
default-directoryis remote.I used vertico's regexp instead of
file-remote-p: it matches once the method is typed, whichis earlier, and it skips the file name handler.
Downside is that scoring can't be interrupted while completing in a remote directory, so a huge
remote directory will feel slower.
(setq fussy-cancel-on-input-fn #'minibufferp)gets the oldbehaviour back.
Repro
vertico + fussy, any host you can ssh to:
M-x tramp-cleanup-all-connectionsand delete~/.cache/emacs/tramp.*so the connection isactually cold.
C-x C-f, then type/ssh:user@host:/srv/by hand at normal speed.You have to be typing while the connection is coming up. Pasting the whole path never triggers
it, which is probably why it feels random.
I tested by driving a TUI Emacs through a pty at 0.15s/char. Hangs every time on current main,
passes every time on this branch, and hangs again if I set the default back to
minibufferponthe branch.
/scp:and/ssh:behave the same, so the method isn't relevant. Emacs 31.1,Tramp 2.8.2, fuz-bin.
compile/lint/test pass, same four warnings as main. Added tests, plus a paragraph in
architecture.org since it currently describes the wrap as unconditional.
If you'd rather leave the default alone I can just add the predicate and document it.