Subject: bug#41423: 27.0.91; eshell file completion in tramp dir is slow (3 minutes) [regression on pretest]

From: Stefan Monnier <[email-masked]>
Date: Tue, 01 Sep 2020 09:04:27 -0400

>> `eshell-complete-commands-list` eagerly builds the list of possible
>> candidates and it takes a while whereas we should here return something
>> quickly and cheaply, e.g. by returning a function which will build and
>> return this list more lazily when completion is actually performed.
> No, the bug is in the completion mechanism, not in eshell.  I don't know
> exactly (because the mechanism is so complicated) where the completion
> functions should be fixed, but it is clear that there is no reason to call
> pcomplete-completions-at-point *three* times.

The reason why it does so, is that it wants to know when a "completion
session" terminates, e.g. to hide the *Completions* buffer or to run the
exit-function.

So it calls it:

- once to do the actual completion.
- once per command in post-command-hook to see if we're done.

Since in your example you have 2 commands (TAB and RET), that gives you
a total of 3.  This design relies on the fact that completion tables can
be lazy, so it should always be possible to make the
completion-at-point-function very cheap and harmless, so it's OK to call
it repeatedly (or even needlessly).

> There is no reason to call pcomplete-completions-at-point when RET
> is pressed.

If running that function is costly, it's a bug.

That's how completion-at-point-functions was designed.

If you want to change that design, be my guest, but it likely implies
changes to a fair bit of code, including outside Emacs.

>> Of course, the slowdown will presumably still be seen when you do actually
>> want to complete a command name, so we should probably try and figure out
>> more precisely where the slowdown comes from and how to avoid/reduce it.
> That's another, separate issue, and it is not relevant here.

Agreed.

        Stefan