summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mendler <mail@daniel-mendler.de>2021-10-17 12:16:40 +0200
committerDaniel Mendler <mail@daniel-mendler.de>2021-10-17 12:19:10 +0200
commitc42760f51ce009ad45eb8715aaccdd7ab018fc04 (patch)
tree1479de16ee2d4e7d656bd1ebfef1e04dfaf1b778
parentaec6277571b49bd9fc6518b12b129a1484c9202f (diff)
Fix completion--capf-wrapper for non-exclusive capfs
Add corfu--capf-wrapper-advice around completion--capf-wrapper.
-rw-r--r--corfu.el35
1 files changed, 30 insertions, 5 deletions
diff --git a/corfu.el b/corfu.el
index 96b95fc..bf930c2 100644
--- a/corfu.el
+++ b/corfu.el
@@ -956,12 +956,37 @@ completion began less than that number of seconds ago."
(define-minor-mode corfu-mode
"Completion Overlay Region FUnction"
:global nil :group 'corfu
- (if corfu-mode
- (progn
- (and corfu-auto (add-hook 'post-command-hook #'corfu--auto-post-command nil 'local))
- (setq-local completion-in-region-function #'corfu--completion-in-region))
+ (cond
+ (corfu-mode
+ ;; FIXME: Install advice which fixes `completion--capf-wrapper', such that
+ ;; it respects the completion styles for non-exclusive capfs. See FIXME in
+ ;; the `completion--capf-wrapper' function in minibuffer.el, where the
+ ;; issue has been mentioned. We never uninstall this advice since the
+ ;; advice is active *globally*.
+ (advice-add #'completion--capf-wrapper :around #'corfu--capf-wrapper-advice)
+ (and corfu-auto (add-hook 'post-command-hook #'corfu--auto-post-command nil 'local))
+ (setq-local completion-in-region-function #'corfu--completion-in-region))
+ (t
(remove-hook 'post-command-hook #'corfu--auto-post-command 'local)
- (kill-local-variable 'completion-in-region-function)))
+ (kill-local-variable 'completion-in-region-function))))
+
+(defun corfu--capf-wrapper-advice (orig fun which)
+ "Around advice for `completion--capf-wrapper'.
+The ORIG function takes the FUN and WHICH arguments."
+ (if corfu-mode ;; Only enable the advice when Corfu is active
+ (let ((res (funcall fun)))
+ (when (and (consp res) (integer-or-marker-p (car res)) ;; Valid capf result
+ (pcase-let ((`(,beg ,end ,table . ,plist) res))
+ (and (<= beg (point) end) ;; Sanity checking
+ ;; For non-exclusive capfs, check for valid completion.
+ (or (not (eq 'no (plist-get plist :exclusive)))
+ (let* ((str (buffer-substring-no-properties beg end))
+ (pt (- (point) beg))
+ (pred (plist-get plist :predicate))
+ (md (completion-metadata (substring str 0 pt) table pred)))
+ (completion-try-completion str table pred pt md))))))
+ (cons fun res)))
+ (funcall orig fun which)))
;;;###autoload
(define-globalized-minor-mode corfu-global-mode corfu-mode corfu--on :group 'corfu)