branch: externals/cape
commit bb1921b6245bd9c201b31893f0348db3463e947e
Author: Daniel Mendler <[email protected]>
Commit: Daniel Mendler <[email protected]>
Add cape-repair-misbehaving-capf
---
README.org | 14 ++++++++++++++
cape.el | 21 +++++++++++++++++++--
2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/README.org b/README.org
index dea6d1f661..4db0a7c94b 100644
--- a/README.org
+++ b/README.org
@@ -194,6 +194,20 @@ achieve a similarly refreshing strategy.
(list (cape-capf-buster #'some-caching-capf)))
#+end_src
+** Repair misbehaving Capfs
+
+Unfortunately some completion of point functions from Emacs show misbehavior.
+This is not a term I've made up, but minibuffer.el distinguishes old-style
+("misbehaving") Capfs and modern-style Capfs. The misbehaving Capfs do not
+return a completion table but just perform completion right away. Such behavior
+is particularily harmful for completion UIs like Company or Corfu in
+idle/auto-completion mode. There is at least one completion function, which
+affects the Eshell:
+
+#+begin_src emacs-lisp
+ (advice-add #'pcomplete-completions-at-point :around
#'cape-repair-misbehaving-capf)
+#+end_src
+
** Other Capf transformers
- ~cape-silent-capf~: Wrap a chatty Capf and silence it.
diff --git a/cape.el b/cape.el
index 0b1ef45319..368522e569 100644
--- a/cape.el
+++ b/cape.el
@@ -466,8 +466,10 @@ If INTERACTIVE is nil the function acts like a capf."
(interactive (list t))
(if interactive
(cape--interactive #'cape-symbol)
- (let ((bounds (cape--bounds 'symbol)))
- `(,(car bounds) ,(cdr bounds)
+ (pcase-let ((`(,beg . ,end) (cape--bounds 'symbol)))
+ (when (eq (char-after beg) ?')
+ (setq beg (1+ beg) end (max beg end)))
+ `(,beg ,end
,(cape--table-with-properties obarray :category 'symbol)
:exclusive no ,@cape--symbol-properties))))
@@ -1012,6 +1014,21 @@ case sensitive instead."
(`(,beg ,end ,table . ,plist)
`(,beg ,end ,(cape--noninterruptible-table table) ,@plist)))))
+;;;###autoload
+(defun cape-repair-misbehaving-capf (capf)
+ "Repair a misbehaving CAPF."
+ (catch 'cape--misbehaving-capf
+ (save-mark-and-excursion
+ (atomic-change-group
+ (pcase (funcall capf)
+ ((and res `(,beg ,end ,_table . ,_plist)
+ (guard (integer-or-marker-p beg))
+ (guard (integer-or-marker-p end)))
+ (ignore beg end)
+ res)
+ (_
+ (throw 'cape--misbehaving-capf nil)))))))
+
;;;###autoload
(defun cape-interactive-capf (capf)
"Create interactive completion function from CAPF."