# What does this fix? Currently, with non-exclusive completion functions, Emacs will do `try-completion` on the current text, and decide whether to try next completion function based on that. This makes completion functions that can do non-prefix completions fails when the current text only occurs in the middle of the candidates. This is a problem I found in a FIXME in the code. # How does this work? I use `completion-all-completions` instead. As far as I know, this respects the `completion-styles`. Here's a simple test. Eval this: ``` (require 'thingatpt) (defun my-completion-at-point () (let* ((symbol (thing-at-point 'symbol)) (bounds (bounds-of-thing-at-point 'symbol))) (list (car bounds) (cdr bounds) '("gnuemacs" "xemacs" "uemacs") :exclusive 'no))) (setq completion-at-point-functions '(my-completion-at-point elisp-completion-at-point)) (setq completion-styles '(substring)) ``` Now type "emacs" and press `C-M-i`, the candidates defined in `my-completion-at-point` will show up correctly. Now change `completion-styles` to `(basic)`, and complete "emacs" again, it fallbacks to `elisp-completion-at-point`. # The patch See the attachment. Since I don't know much about email, I'm not sure if gmail's attachment is permanent, so I'll also paste the diff and commit log here: ## Diff --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -2244,18 +2244,11 @@ completion--capf-wrapper (unless (member fun completion--capf-safe-funs) (push fun completion--capf-safe-funs)) (and (eq 'no (plist-get (nthcdr 3 res) :exclusive)) - ;; FIXME: Here we'd need to decide whether there are - ;; valid completions against the current text. But this depends - ;; on the actual completion UI (e.g. with the default completion - ;; it depends on completion-style) ;-( - ;; We approximate this result by checking whether prefix - ;; completion might work, which means that non-prefix completion - ;; will not work (or not right) for completion functions that - ;; are non-exclusive. - (null (try-completion (buffer-substring-no-properties - (car res) (point)) - (nth 2 res) - (plist-get (nthcdr 3 res) :predicate))) + (null (completion-all-completions + (buffer-substring-no-properties (car res) (point)) + (nth 2 res) + (plist-get (nthcdr 3 res) :predicate) + (- (point) (car res)))) (setq res nil))) ((not (or (listp res) (functionp res))) (unless (member fun completion--capf-misbehave-funs) ## Commit Log Fix handling for non-exclusive non-prefix completion functions * lisp/minibuffer.el (completion--capf-wrapper): use completion-all-completions to do the test.