Replies: 9 comments 36 replies
-
In Emacs version 26.1, the docstring at the end of try-completion says: Additionally to this predicate, ‘completion-regexp-list’ I'm guessing here, but appropriately changing cl-remove-if-not to all-completion after the "all-completion" comment might just fix the issue. |
Beta Was this translation helpful? Give feedback.
-
I've converted this to a discussion. It can be a issue again once all the elements required to make one are provided, as per the template. |
Beta Was this translation helpful? Give feedback.
-
Thanks for your thoughts. My apologies for not including a reproduction recipe, this did not seem to me a "BUG" but rather a "FEATURE REQUEST". Here are the requested elements: Minimal configuration (mandatory) # Type this in a shell to start an Emacs with Eglot configured
$ emacs -Q -f package-initialize -L /path/to/git-cloned/eglot -l eglot.el ;; Eval in *scratch* as directed
;;; Here we demonstrate the role of completion-regexp-list
(eglot-lsp-server- ; hit M-Tab here, notice 5 results
(setq completion-regexp-list '("-c[hm]")) ; eval this, then re-try above completion: 3 results
(setq completion-regexp-list nil) ; reset to avoid issues Now open a temporary python file and import os
os.l # Hit M-Tab: 10 results
# Now M-: (setq completion-regexp-list '("d")) And try completion again:
# still 10 results. This is incorrect behavior
# Now try with M-: (setq completion-regexp-list '("i")) : 4 results starting li
# Don't forget to reset completion-regexp-list! This demonstrates how eglot is not filtering based on What I discovered in preparing this example is that eglot does however, seem to be doing prefix matching based on the Obviously this is a contrived example that would have little practical purpose. The real purpose is to support completion styles such as orderless, which use That said, before we could proceed with a fix, I think the first order of business is understanding how and where the incorrect prefix filtering is getting triggered. Any thoughts you had on this would be appreciated. |
Beta Was this translation helpful? Give feedback.
-
@nemethf I've finally understood your point, thank you! The documentation regarding collection functions is correct, but elgot's CAPF collection function queries the LSP server and then caches a normal collection list. It then re-calls try/test-completion with this list. When called with such a normal (non-function) collection, try/test-completion do respect @joaotavora We can keep it a discussion for now, no worries. |
Beta Was this translation helpful? Give feedback.
-
I find replacing the ((eq action t) ; all-completions
(all-completions "" (funcall proxies)
(lambda (cand)
(let* ((item (get-text-property 0 'eglot--lsp-item cand))
(text (or (plist-get item :filterText) cand)))
(and (string-prefix-p probe text completion-ignore-case)
(or (not pred) (funcall pred cand))))))))) As a bonus, all-completions is much faster as it's in C. |
Beta Was this translation helpful? Give feedback.
-
The speedup comes primarily from searching through a number of regexps, which all-completions does internally. Orderless benefits the most from this, as it reruns this type of search over and over on every character input. And since it compiles regexps from user input with a custom dispatcher, they do tend to get some length and complexity. The general vertico/embark/consult/orderless group of packages all use native completion internally for speed. Here's an example that shows a bit more than 3x speedup for me: (let ((candidates (cl-loop
repeat 10000
for len = (+ 5 (random 12))
for word = (cl-loop repeat len concat (string (+ ?a (random 26))))
collect word))
(completion-regexp-list '("[a-d]$"
"r..[pqr]"
"\\([^mpqr]\\)\\{3\\}.*[b-n]\\1[a-x]"
"[a-k][k-z]\\{5\\}.*?[a-m]")))
(list
(benchmark-run 100 (length (all-completions "" candidates)))
(benchmark-run 100 (length
(cl-remove-if-not
(lambda (cand)
(cl-every (lambda (regexp)
(string-match-p regexp cand))
completion-regexp-list))
candidates)))))
|
Beta Was this translation helpful? Give feedback.
-
All completion tools I know use "native" completion (which I think is what you mean by calling into C code) to a certain degree. Here you are grouping completion UIs and completion tables and completion styles, if I'm not mistaken. I understand that your general perception is that this combo is "fast", but as I said, I would like to see objective benchmarks and numbers, preferably measuring each of these in isolated and controlled conditions. But not need to provide this to for this particular matter regarding |
Beta Was this translation helpful? Give feedback.
-
Again without benchmarks, the quantitive (but broad) category is: how to rapidly select from a large number of possibilities by prefix, sub-string, multiple-regexps, etc. Those possibilities could be "things to insert in the buffer" aka completion, but also many many others. I think my example above proves that at least for some limited aspects of this problem space, using the internal completion (written in C) is a faster solution than reasonably efficient Elisp. And I really don't find that surprising at all. But maybe your dentist's elephants can make some more benchmarks for her to investigate :). This is for Emacs 27; I haven't tried the new JIT compiled Emacs 28, which may reduce the distance between approaches. Consult is basically a tool that takes all kinds of Emacs selection problems, and runs them through mini-buffer completion (with all its configurability). Files (like ido/fido/etc.). Buffers. Macros to run. Bookmarks. Matching lines. Imenu items. Markers. Command history. (Rip)Grep search results. Yank history. Registers. You get the idea. Once I get it working well maybe I'll make a small video of eglot + corfu[1] + orderless doing their thing. [1] corfu is the vertico sibling which provides in-buffer completion, kind of like company |
Beta Was this translation helpful? Give feedback.
-
The basic completion docs for
try-completion
(also applying totest-completion
,all-completions
, etc.) state (emphasis added):The COLLECTION function provided by eglot does not appear to consider
completion-regexp-list
. This variable is important for completion styles such as orderless, which putcompletion-regexp-list
to heavy work for candidate refinement. Since most in-built completion tables are obarrays, alists, hashes, etc., the issue really only pertains to programmed completion, such as in eglot. I have a small patch to theproxies
lambda which implements this, and works well in my testing. Let me know if you'd like to see a PR. See also oantolin/orderless#78. Thanks for eglot!Beta Was this translation helpful? Give feedback.
All reactions