emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

emacs-29 f1675df3d0c: Fido-mode: never shadow 'external' completion styl


From: João Távora
Subject: emacs-29 f1675df3d0c: Fido-mode: never shadow 'external' completion style
Date: Tue, 9 May 2023 04:41:22 -0400 (EDT)

branch: emacs-29
commit f1675df3d0c6ea723693dedc2c2b9ae39e1be339
Author: João Távora <joaotavora@gmail.com>
Commit: João Távora <joaotavora@gmail.com>

    Fido-mode: never shadow 'external' completion style
    
    As explained in the manual (20.7.2 Fast minibuffer selection)
    'fido-mode' and 'fido-vertical-mode' give priority the "flex"
    completion style.
    
    In fact, bug#62015 was recently fixed in commit because that priority
    was not taking place correctly and some completions were missed.
    
    However, an exception must be made for the 'external' completion
    style.
    
    That style, made available by the lisp/external-completion.el library,
    is specifically designed to work with backends that provide only a
    partial view of all completions.  If we allow 'flex' to step in front
    of 'external' it could mean that 'flex' matches something and
    'external' isn't triggered as it probably should.
    
    To reproduce have the rust-mode ELPA package and the rust-analyzer LSP
    server handy.  Then:
    
      emacs -Q -f package-initialize main.rs
    
    Where main.rs is this content:
    
      fn foo1()    {} fn foo2()    {} fn foo3() {}
      fn foobar1() {} fn foobar2() {} fn foobar3() {}
    
    The rust-analyzer server can be quickly configured to return only 3
    workspace symbols max, so evaluate:
    
      (setq-default eglot-workspace-configuration
                    '(:rust-analyzer
                        (:workspace (:symbol (:search (:limit 3))))))
    
    Now start M-x eglot and M-x fido-vertical-mode and type C-u M-. to
    find an arbitrary symbol in this one-file project.
    
    Type 'f'.  You will see the three foo's are listed, correctly.
    
    Now type '3'.   You will only see "foo3".
    
    But that's wrong because "foobar3" was available, if only the server
    had been asked for it.  This commit fixes the situation and no
    completions are lost.
    
    As an unfortunate side-effect of this commit, the fontification of
    completions-common-part on the matches is lost, but that is not worse
    than missing out on completions and there are better ways to recover
    the fontification anyway (in external-completion.el).
    
    See also:
    
https://github.com/joaotavora/eglot/discussions/1219#discussioncomment-5818336
    
    * lisp/icomplete.el (icomplete--fido-ccd): Do not touch entries
    with 'external in them.
    
    Do not merge to master.
    Backport:
    
    (cherry picked from commit 0e8d8a72284f6b3aaa1bbce73d41c7d84bbc4d3c)
---
 lisp/icomplete.el | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lisp/icomplete.el b/lisp/icomplete.el
index f46127a20e0..cfe6244b511 100644
--- a/lisp/icomplete.el
+++ b/lisp/icomplete.el
@@ -425,7 +425,10 @@ if that doesn't produce a completion match."
    for (cat . alist) in completion-category-defaults collect
    `(,cat . ,(cl-loop
               for entry in alist for (prop . val) = entry
-              if (eq prop 'styles)
+              if (and (eq prop 'styles)
+                      ;; Never step in front of 'external', as that
+                      ;; might lose us completions.
+                      (not (memq 'external val)))
               collect `(,prop . (flex ,@(delq 'flex val)))
               else collect entry))))
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]