summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mendler <mail@daniel-mendler.de>2026-04-19 20:31:18 +0200
committerDaniel Mendler <mail@daniel-mendler.de>2026-04-19 20:33:28 +0200
commit30372e41e8f8e92557ee9fd965d64b8fee8dc357 (patch)
tree246f45decd0f5cc7ddf3490291b9673b5a5cc86d
parent7a6a752bc694e81853d915281a73a9c3acc69757 (diff)
cape-capf-super: Disambiguate duplicates based on :exit-function
Duplicates created by Dabbrev and Dict are deduplicated, since they behave identically during completion: (setq-local completion-at-point-functions (list (cape-capf-super #'cape-dabbrev #'cape-dict))) However completion candidates which cause expansion due to an :exit-function (cape-abbrev or tempel-complete) are not deduplicated: (setq-local completion-at-point-functions (list (cape-capf-super #'cape-abbrev #'cape-dict)))
-rw-r--r--cape.el36
1 files changed, 21 insertions, 15 deletions
diff --git a/cape.el b/cape.el
index 1b936ca..715c051 100644
--- a/cape.el
+++ b/cape.el
@@ -985,22 +985,28 @@ turn."
;; candidates if we've already determined that
;; main candidates are available.
(cands (when (or main (or exclusive cand-ht candidates))
- (funcall sort (all-completions str table pr)))))
+ (funcall sort (all-completions str table pr))))
+ (cands (cons nil cands))
+ (ptr cands))
;; Handle duplicates with a hash table.
- (cl-loop
- for cand in-ref cands
- for dup = (gethash cand ht t) do
- (cond
- ((eq dup t)
- ;; Candidate does not yet exist.
- (puthash cand cand-plist ht))
- ((not (equal dup cand-plist))
- ;; Duplicate candidate. Candidate plist is
- ;; different, therefore disambiguate the
- ;; candidates.
- (setf cand (propertize cand 'cape-capf-super
- (cons cand cand-plist))))))
- (when cands (push cands candidates))))
+ (while (cdr ptr)
+ (let* ((cand (cadr ptr))
+ (dup (gethash cand ht t)))
+ (cond
+ ((eq dup t)
+ ;; Candidate is unique so far.
+ (puthash cand cand-plist ht)
+ (pop ptr))
+ ((not (equal (plist-get dup :exit-function)
+ (plist-get cand-plist :exit-function)))
+ ;; Disambiguate duplicate candidates with
+ ;; different exit functions.
+ (setf (cadr ptr) (propertize cand 'cape-capf-super
+ (cons cand cand-plist)))
+ (pop ptr))
+ (t ;; Delete duplicate candidate.
+ (setcdr ptr (cddr ptr))))))
+ (when (cdr cands) (push (cdr cands) candidates))))
(when (or cand-ht candidates)
(setq candidates (apply #'nconc (nreverse candidates))
cand-ht ht)