From feed6d4acf530ea2f3acc534cbac490f6674415e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Sun, 12 May 2024 21:05:00 -0300 Subject: [PATCH 01/20] Cache completion results and grab the completion prefix correctly This PR makes the CIDER completions behave correctly and minimizes round trips to nrepl to gather completions. Tested with the `flex` and `orderless` completion styles. What should we do with `cider-company-enable-fuzzy-completion`? With this we can remove the CIDER completion style. Should `cider-company-enable-fuzzy-completion` just mirror the behaviour of `cider-enable-flex-completion`? --- cider-completion.el | 53 +++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/cider-completion.el b/cider-completion.el index 9f83e4715..a2c0a9f3d 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -179,9 +179,39 @@ performed by `cider-annotate-completion-function'." (ns (cider-completion--get-candidate-ns symbol))) (funcall cider-annotate-completion-function type ns)))) +(defvar cider--completion-cache nil + "Cache used by `cider--complete-with-cache'. +this is a cons cell of (BOUNDS . COMPLETIONS).") + +(defun cider--complete-with-cache (bounds) + "Return completions to the symbol at `BOUNDS' with caching. +If the completion of `bounds' is cached, return the cached completions, +otherwise, call `cider-complete', set the cache, and return the completions." + (cdr-safe + (if (and (consp cider--completion-cache) + (eq bounds (car cider--completion-cache))) + cider--completion-cache + (setq cider--completion-cache + `(,bounds . ,(cider-complete (buffer-substring (car bounds) (cdr bounds)))))))) + +(defun cider-completion-flush-caches () + "Force Compliment to refill its caches. +This command should be used if Compliment fails to pick up new classnames +and methods from dependencies that were loaded dynamically after the REPL +has started." + (interactive) + (cider-sync-request:complete-flush-caches)) + +(defun cider--clear-completion-cache (&optional _ _) + "Clears the completion cache." + (cider-completion-flush-caches) + (setq cider--completion-cache nil)) + (defun cider-complete-at-point () "Complete the symbol at point." - (when-let* ((bounds (bounds-of-thing-at-point 'symbol))) + (when-let* ((bounds (or (bounds-of-thing-at-point 'symbol) + (cons (point) (point)))) + (bounds-string (buffer-substring (car bounds) (cdr bounds)))) (when (and (cider-connected-p) (not (or (cider-in-string-p) (cider-in-comment-p)))) (list (car bounds) (cdr bounds) @@ -196,22 +226,13 @@ performed by `cider-annotate-completion-function'." ;; '21.6.7 Programmed Completion' of the elisp manual. (cond ((eq action 'metadata) `(metadata (category . cider))) ;; defines a completion category named 'cider, used later in our `completion-category-overrides` logic. ((eq (car-safe action) 'boundaries) nil) - (t (with-current-buffer (current-buffer) - (complete-with-action action - (cider-complete prefix) prefix pred))))) + (t (complete-with-action action (cider--complete-with-cache bounds) bounds-string pred)))) :annotation-function #'cider-annotate-symbol :company-kind #'cider-company-symbol-kind :company-doc-buffer #'cider-create-compact-doc-buffer :company-location #'cider-company-location - :company-docsig #'cider-company-docsig)))) - -(defun cider-completion-flush-caches () - "Force Compliment to refill its caches. -This command should be used if Compliment fails to pick up new classnames -and methods from dependencies that were loaded dynamically after the REPL -has started." - (interactive) - (cider-sync-request:complete-flush-caches)) + :company-docsig #'cider-company-docsig + :exit-function #'cider--clear-completion-cache)))) (defun cider-company-location (var) "Open VAR's definition in a buffer. @@ -256,12 +277,6 @@ in the buffer." cider-company-unfiltered-candidates "CIDER backend-driven completion style.")) -;; Currently CIDER completions only work for `basic`, and not `initials`, `partial-completion`, `orderless`, etc. -;; So we ensure that those other styles aren't used with CIDER, otherwise one would see bad or no completions at all. -;; This `add-to-list` call can be removed once we implement the other completion styles. -;; (When doing that, please refactor `cider-enable-flex-completion' as well) -(add-to-list 'completion-category-overrides '(cider (styles basic))) - (defun cider-company-enable-fuzzy-completion () "Enable backend-driven fuzzy completion in the current buffer. From 3ee43779763e67aa537e3d6aa6a082b00a41ab0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Sun, 12 May 2024 21:33:07 -0300 Subject: [PATCH 02/20] Fix tests --- cider-completion.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cider-completion.el b/cider-completion.el index a2c0a9f3d..6be683dd4 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -299,6 +299,8 @@ Only affects the `cider' completion category.`" (setq completion-category-overrides (seq-remove (lambda (x) (equal 'cider (car x))) completion-category-overrides)) + (unless found-styles + (setq found-styles '(styles))) (unless (member 'flex found-styles) (setq found-styles (append found-styles '(flex)))) (add-to-list 'completion-category-overrides (apply #'list 'cider found-styles (when found-cycle From a20aa8de5951466950ca947c4fb82ee8e4982869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Mon, 13 May 2024 02:02:45 -0300 Subject: [PATCH 03/20] Make the caching smarter --- cider-completion.el | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/cider-completion.el b/cider-completion.el index 6be683dd4..b7738feba 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -187,12 +187,16 @@ this is a cons cell of (BOUNDS . COMPLETIONS).") "Return completions to the symbol at `BOUNDS' with caching. If the completion of `bounds' is cached, return the cached completions, otherwise, call `cider-complete', set the cache, and return the completions." - (cdr-safe - (if (and (consp cider--completion-cache) - (eq bounds (car cider--completion-cache))) - cider--completion-cache - (setq cider--completion-cache - `(,bounds . ,(cider-complete (buffer-substring (car bounds) (cdr bounds)))))))) + (let* ((prefix (or (buffer-substring-no-properties (car bounds) (cdr bounds)) "")) + (completions nil)) + (when (and (consp cider--completion-cache) + (equal prefix (car cider--completion-cache))) + (setq completions (cdr cider--completion-cache))) + (when (null completions) + (let ((resp (cider-complete prefix))) + (setq cider--completion-cache `(,prefix . ,resp) + completions resp))) + completions)) (defun cider-completion-flush-caches () "Force Compliment to refill its caches. @@ -202,7 +206,7 @@ has started." (interactive) (cider-sync-request:complete-flush-caches)) -(defun cider--clear-completion-cache (&optional _ _) +(defun cider--clear-completion-cache (_ _) "Clears the completion cache." (cider-completion-flush-caches) (setq cider--completion-cache nil)) @@ -215,7 +219,7 @@ has started." (when (and (cider-connected-p) (not (or (cider-in-string-p) (cider-in-comment-p)))) (list (car bounds) (cdr bounds) - (lambda (prefix pred action) + (lambda (pattern pred action) ;; When the 'action is 'metadata, this lambda returns metadata about this ;; capf, when action is (boundaries . suffix), it returns nil. With every ;; other value of 'action (t, nil, or lambda), 'action is forwarded to @@ -225,8 +229,13 @@ has started." ;; This api is better described in the section ;; '21.6.7 Programmed Completion' of the elisp manual. (cond ((eq action 'metadata) `(metadata (category . cider))) ;; defines a completion category named 'cider, used later in our `completion-category-overrides` logic. - ((eq (car-safe action) 'boundaries) nil) - (t (complete-with-action action (cider--complete-with-cache bounds) bounds-string pred)))) + ((eq (car-safe action) 'boundaries) nil) ; boundaries + ((eq action 'lambda) ; test-completion + (test-completion pattern (cider--complete-with-cache bounds))) + ((null action) ; try-completion + (try-completion pattern (cider--complete-with-cache bounds))) + ((eq action t) ; all-completions + (all-completions "" (cider--complete-with-cache bounds))))) :annotation-function #'cider-annotate-symbol :company-kind #'cider-company-symbol-kind :company-doc-buffer #'cider-create-compact-doc-buffer From 0488876edd62057e42d77e823dc04eaa96509f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Mon, 13 May 2024 02:38:15 -0300 Subject: [PATCH 04/20] pattern -> prefix --- cider-completion.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cider-completion.el b/cider-completion.el index b7738feba..fc7690709 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -219,7 +219,7 @@ has started." (when (and (cider-connected-p) (not (or (cider-in-string-p) (cider-in-comment-p)))) (list (car bounds) (cdr bounds) - (lambda (pattern pred action) + (lambda (prefix pred action) ;; When the 'action is 'metadata, this lambda returns metadata about this ;; capf, when action is (boundaries . suffix), it returns nil. With every ;; other value of 'action (t, nil, or lambda), 'action is forwarded to @@ -231,9 +231,9 @@ has started." (cond ((eq action 'metadata) `(metadata (category . cider))) ;; defines a completion category named 'cider, used later in our `completion-category-overrides` logic. ((eq (car-safe action) 'boundaries) nil) ; boundaries ((eq action 'lambda) ; test-completion - (test-completion pattern (cider--complete-with-cache bounds))) + (test-completion prefix (cider--complete-with-cache bounds))) ((null action) ; try-completion - (try-completion pattern (cider--complete-with-cache bounds))) + (try-completion prefix (cider--complete-with-cache bounds))) ((eq action t) ; all-completions (all-completions "" (cider--complete-with-cache bounds))))) :annotation-function #'cider-annotate-symbol From e909437dc65b6be2af7b638b3c814f72a142a92c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Mon, 13 May 2024 02:47:53 -0300 Subject: [PATCH 05/20] use unless instead of when null --- cider-completion.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cider-completion.el b/cider-completion.el index fc7690709..725bc3657 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -192,7 +192,7 @@ otherwise, call `cider-complete', set the cache, and return the completions." (when (and (consp cider--completion-cache) (equal prefix (car cider--completion-cache))) (setq completions (cdr cider--completion-cache))) - (when (null completions) + (unless completions (let ((resp (cider-complete prefix))) (setq cider--completion-cache `(,prefix . ,resp) completions resp))) From f3f8173cd3aa2d935f8c0e27d6e160a8a31e99fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Mon, 13 May 2024 02:49:22 -0300 Subject: [PATCH 06/20] equal -> string= --- cider-completion.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cider-completion.el b/cider-completion.el index 725bc3657..57d9cb146 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -190,7 +190,7 @@ otherwise, call `cider-complete', set the cache, and return the completions." (let* ((prefix (or (buffer-substring-no-properties (car bounds) (cdr bounds)) "")) (completions nil)) (when (and (consp cider--completion-cache) - (equal prefix (car cider--completion-cache))) + (string= prefix (car cider--completion-cache))) (setq completions (cdr cider--completion-cache))) (unless completions (let ((resp (cider-complete prefix))) From c653fabb60c6aaf4e4c08af61f533b14b6fa0ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Tue, 14 May 2024 06:43:32 -0300 Subject: [PATCH 07/20] Keep the cache inside the capf --- cider-completion.el | 95 +++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 55 deletions(-) diff --git a/cider-completion.el b/cider-completion.el index 57d9cb146..081a56433 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -179,24 +179,46 @@ performed by `cider-annotate-completion-function'." (ns (cider-completion--get-candidate-ns symbol))) (funcall cider-annotate-completion-function type ns)))) -(defvar cider--completion-cache nil - "Cache used by `cider--complete-with-cache'. -this is a cons cell of (BOUNDS . COMPLETIONS).") - -(defun cider--complete-with-cache (bounds) - "Return completions to the symbol at `BOUNDS' with caching. -If the completion of `bounds' is cached, return the cached completions, -otherwise, call `cider-complete', set the cache, and return the completions." - (let* ((prefix (or (buffer-substring-no-properties (car bounds) (cdr bounds)) "")) - (completions nil)) - (when (and (consp cider--completion-cache) - (string= prefix (car cider--completion-cache))) - (setq completions (cdr cider--completion-cache))) - (unless completions - (let ((resp (cider-complete prefix))) - (setq cider--completion-cache `(,prefix . ,resp) - completions resp))) - completions)) +(defun cider-complete-at-point () + "Complete the symbol at point." + (when-let* ((bounds (or (bounds-of-thing-at-point 'symbol) + (cons (point) (point)))) + (bounds-string (buffer-substring (car bounds) (cdr bounds)))) + (when (and (cider-connected-p) + (not (or (cider-in-string-p) (cider-in-comment-p)))) + (let* (last-bounds-string + last-result + (complete + (lambda () + ;; Not using the prefix extracted within the (prefix pred action) lambda. + ;; In certain completion styles, the prefix might be an empty string, + ;; which is unreliable. A more dependable method is to use the string + ;; defined by the bounds of the symbol at point. + ;; + ;; Caching just within the function is sufficient. Keeping it local ensures + ;; that it will not extend across diferent CIDER sessions. + (unless (string= bounds-string last-bounds-string) + (setq last-bounds-string bounds-string) + (setq last-result (cider-complete bounds-string))) + last-result))) + (list (car bounds) (cdr bounds) + (lambda (prefix pred action) + ;; When the 'action is 'metadata, this lambda returns metadata about this + ;; capf, when action is (boundaries . suffix), it returns nil. With every + ;; other value of 'action (t, nil, or lambda), 'action is forwarded to + ;; (complete-with-action), together with (cider-complete), prefix and pred. + ;; And that function performs the completion based on those arguments. + ;; + ;; This api is better described in the section + ;; '21.6.7 Programmed Completion' of the elisp manual. + (cond ((eq action 'metadata) `(metadata (category . cider))) ;; defines a completion category named 'cider, used later in our `completion-category-overrides` logic. + ((eq (car-safe action) 'boundaries) nil) ; boundaries + (t (complete-with-action action (funcall complete) prefix pred)))) + :annotation-function #'cider-annotate-symbol + :company-kind #'cider-company-symbol-kind + :company-doc-buffer #'cider-create-compact-doc-buffer + :company-location #'cider-company-location + :company-docsig #'cider-company-docsig))))) (defun cider-completion-flush-caches () "Force Compliment to refill its caches. @@ -206,43 +228,6 @@ has started." (interactive) (cider-sync-request:complete-flush-caches)) -(defun cider--clear-completion-cache (_ _) - "Clears the completion cache." - (cider-completion-flush-caches) - (setq cider--completion-cache nil)) - -(defun cider-complete-at-point () - "Complete the symbol at point." - (when-let* ((bounds (or (bounds-of-thing-at-point 'symbol) - (cons (point) (point)))) - (bounds-string (buffer-substring (car bounds) (cdr bounds)))) - (when (and (cider-connected-p) - (not (or (cider-in-string-p) (cider-in-comment-p)))) - (list (car bounds) (cdr bounds) - (lambda (prefix pred action) - ;; When the 'action is 'metadata, this lambda returns metadata about this - ;; capf, when action is (boundaries . suffix), it returns nil. With every - ;; other value of 'action (t, nil, or lambda), 'action is forwarded to - ;; (complete-with-action), together with (cider-complete), prefix and pred. - ;; And that function performs the completion based on those arguments. - ;; - ;; This api is better described in the section - ;; '21.6.7 Programmed Completion' of the elisp manual. - (cond ((eq action 'metadata) `(metadata (category . cider))) ;; defines a completion category named 'cider, used later in our `completion-category-overrides` logic. - ((eq (car-safe action) 'boundaries) nil) ; boundaries - ((eq action 'lambda) ; test-completion - (test-completion prefix (cider--complete-with-cache bounds))) - ((null action) ; try-completion - (try-completion prefix (cider--complete-with-cache bounds))) - ((eq action t) ; all-completions - (all-completions "" (cider--complete-with-cache bounds))))) - :annotation-function #'cider-annotate-symbol - :company-kind #'cider-company-symbol-kind - :company-doc-buffer #'cider-create-compact-doc-buffer - :company-location #'cider-company-location - :company-docsig #'cider-company-docsig - :exit-function #'cider--clear-completion-cache)))) - (defun cider-company-location (var) "Open VAR's definition in a buffer. Returns the cons of the buffer itself and the location of VAR's definition From 8b06606ec3816733362dcc8215966fd65d9e86f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Tue, 14 May 2024 06:47:05 -0300 Subject: [PATCH 08/20] fix spelling --- cider-completion.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cider-completion.el b/cider-completion.el index 081a56433..3f7bfeff9 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -196,7 +196,7 @@ performed by `cider-annotate-completion-function'." ;; defined by the bounds of the symbol at point. ;; ;; Caching just within the function is sufficient. Keeping it local ensures - ;; that it will not extend across diferent CIDER sessions. + ;; that it will not extend across different CIDER sessions. (unless (string= bounds-string last-bounds-string) (setq last-bounds-string bounds-string) (setq last-result (cider-complete bounds-string))) From e61e7ba279e1a1037438e764b47b016c9f36d4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Wed, 15 May 2024 16:25:24 -0300 Subject: [PATCH 09/20] Fix comments --- cider-completion.el | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cider-completion.el b/cider-completion.el index 3f7bfeff9..3b85e949f 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -190,13 +190,13 @@ performed by `cider-annotate-completion-function'." last-result (complete (lambda () - ;; Not using the prefix extracted within the (prefix pred action) lambda. - ;; In certain completion styles, the prefix might be an empty string, - ;; which is unreliable. A more dependable method is to use the string - ;; defined by the bounds of the symbol at point. + ;; We are Not using the prefix extracted within the (prefix pred action) + ;; lambda. In certain completion styles, the prefix might be an empty + ;; string, which is unreliable. A more dependable method is to use the + ;; string defined by the bounds of the symbol at point. ;; - ;; Caching just within the function is sufficient. Keeping it local ensures - ;; that it will not extend across different CIDER sessions. + ;; Caching just within the function is sufficient. Keeping it local + ;; ensures that it will not extend across different CIDER sessions. (unless (string= bounds-string last-bounds-string) (setq last-bounds-string bounds-string) (setq last-result (cider-complete bounds-string))) @@ -212,7 +212,7 @@ performed by `cider-annotate-completion-function'." ;; This api is better described in the section ;; '21.6.7 Programmed Completion' of the elisp manual. (cond ((eq action 'metadata) `(metadata (category . cider))) ;; defines a completion category named 'cider, used later in our `completion-category-overrides` logic. - ((eq (car-safe action) 'boundaries) nil) ; boundaries + ((eq (car-safe action) 'boundaries) nil) (t (complete-with-action action (funcall complete) prefix pred)))) :annotation-function #'cider-annotate-symbol :company-kind #'cider-company-symbol-kind From fd03ee8d7e289150e762d9f83419c68b62871539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Wed, 15 May 2024 16:49:31 -0300 Subject: [PATCH 10/20] Add the basic style as fallback in cider-enable-flex-completion --- cider-completion.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cider-completion.el b/cider-completion.el index 3b85e949f..e1547c1c5 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -294,7 +294,7 @@ Only affects the `cider' completion category.`" (equal 'cider (car x))) completion-category-overrides)) (unless found-styles - (setq found-styles '(styles))) + (setq found-styles '(styles basic))) (unless (member 'flex found-styles) (setq found-styles (append found-styles '(flex)))) (add-to-list 'completion-category-overrides (apply #'list 'cider found-styles (when found-cycle From d017d2ac1f78b74faac3eb98b2c9a16f20776c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Wed, 15 May 2024 16:53:39 -0300 Subject: [PATCH 11/20] re-introduce with-current-buffer --- cider-completion.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cider-completion.el b/cider-completion.el index e1547c1c5..bd23c3859 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -213,7 +213,8 @@ performed by `cider-annotate-completion-function'." ;; '21.6.7 Programmed Completion' of the elisp manual. (cond ((eq action 'metadata) `(metadata (category . cider))) ;; defines a completion category named 'cider, used later in our `completion-category-overrides` logic. ((eq (car-safe action) 'boundaries) nil) - (t (complete-with-action action (funcall complete) prefix pred)))) + (t (with-current-buffer (current-buffer) + (complete-with-action action (funcall complete) prefix pred))))) :annotation-function #'cider-annotate-symbol :company-kind #'cider-company-symbol-kind :company-doc-buffer #'cider-create-compact-doc-buffer From ebd78665747bd9577df2e8a2be6e94d877c5baf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Wed, 15 May 2024 21:53:13 -0300 Subject: [PATCH 12/20] add flex completion style at the start of the style overrides --- cider-completion.el | 12 +++++++----- test/cider-completion-tests.el | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/cider-completion.el b/cider-completion.el index bd23c3859..b89cb0643 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -288,18 +288,20 @@ Only affects the `cider' completion category.`" (when (< emacs-major-version 27) (user-error "`cider-enable-flex-completion' requires Emacs 27 or later")) (let ((found-styles (when-let ((cider (assq 'cider completion-category-overrides))) - (assq 'styles cider))) + (cdr (assq 'styles cider)))) (found-cycle (when-let ((cider (assq 'cider completion-category-overrides))) (assq 'cycle cider)))) (setq completion-category-overrides (seq-remove (lambda (x) (equal 'cider (car x))) completion-category-overrides)) (unless found-styles - (setq found-styles '(styles basic))) + (setq found-styles '(basic))) (unless (member 'flex found-styles) - (setq found-styles (append found-styles '(flex)))) - (add-to-list 'completion-category-overrides (apply #'list 'cider found-styles (when found-cycle - (list found-cycle)))))) + (add-to-list 'found-styles 'flex)) + (add-to-list 'completion-category-overrides (apply #'list 'cider + (apply #'list 'styles found-styles) + (when found-cycle + (list found-cycle)))))) (provide 'cider-completion) ;;; cider-completion.el ends here diff --git a/test/cider-completion-tests.el b/test/cider-completion-tests.el index bfbba1ee7..e21c6457b 100644 --- a/test/cider-completion-tests.el +++ b/test/cider-completion-tests.el @@ -36,15 +36,27 @@ (let ((old-value completion-category-overrides)) (unwind-protect (progn - (it "adds `flex'" + (it "adds `flex' and `basic' as a fallback" (cider-enable-flex-completion) - (expect (member 'flex (assq 'styles (assq 'cider completion-category-overrides))) + (expect (car (cdr (assq 'styles (assq 'cider completion-category-overrides)))) + :to-be 'flex) + (expect (member 'basic (assq 'styles (assq 'cider completion-category-overrides))) :to-be-truthy)) (it "doesn't add `cycle'" (expect (assq 'cycle (assq 'cider completion-category-overrides)) :to-be nil)) + (it "adds just `flex' if there is another syle present" + (setq completion-category-overrides '((cider (styles partial-completion)))) + (cider-enable-flex-completion) + (expect (car (cdr (assq 'styles (assq 'cider completion-category-overrides)))) + :to-be 'flex) + (expect (member 'partial-completion (assq 'styles (assq 'cider completion-category-overrides))) + :to-be-truthy) + (expect (member 'basic (assq 'styles (assq 'cider completion-category-overrides))) + :to-be nil)) + (it "doesn't re-add `flex' if already present, preserving `cycle' as well" (let ((with-flex-and-cycle '((cider (styles basic flex) (cycle t))))) From c78b2d4d22b9d9e25e4569a84dc8d168c3dff7d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Wed, 15 May 2024 21:58:15 -0300 Subject: [PATCH 13/20] fix spelling --- test/cider-completion-tests.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cider-completion-tests.el b/test/cider-completion-tests.el index e21c6457b..5f79c089f 100644 --- a/test/cider-completion-tests.el +++ b/test/cider-completion-tests.el @@ -47,7 +47,7 @@ (expect (assq 'cycle (assq 'cider completion-category-overrides)) :to-be nil)) - (it "adds just `flex' if there is another syle present" + (it "adds just `flex' if there is another style present" (setq completion-category-overrides '((cider (styles partial-completion)))) (cider-enable-flex-completion) (expect (car (cdr (assq 'styles (assq 'cider completion-category-overrides)))) From 91245c42a482c195a9dfadfce6aacfb7e7ea463f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Wed, 15 May 2024 22:03:34 -0300 Subject: [PATCH 14/20] use cl-pushnew instead of add-to-list --- cider-completion.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cider-completion.el b/cider-completion.el index b89cb0643..9769bde95 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -296,8 +296,7 @@ Only affects the `cider' completion category.`" completion-category-overrides)) (unless found-styles (setq found-styles '(basic))) - (unless (member 'flex found-styles) - (add-to-list 'found-styles 'flex)) + (cl-pushnew 'flex found-styles) (add-to-list 'completion-category-overrides (apply #'list 'cider (apply #'list 'styles found-styles) (when found-cycle From 54ebdf02b2c2bb566b8cf3f29a812e283212d637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Thu, 16 May 2024 02:27:36 -0300 Subject: [PATCH 15/20] set flex completion style with less priority --- cider-completion.el | 13 ++++++------- test/cider-completion-tests.el | 10 +++++----- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/cider-completion.el b/cider-completion.el index 9769bde95..bd23c3859 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -288,19 +288,18 @@ Only affects the `cider' completion category.`" (when (< emacs-major-version 27) (user-error "`cider-enable-flex-completion' requires Emacs 27 or later")) (let ((found-styles (when-let ((cider (assq 'cider completion-category-overrides))) - (cdr (assq 'styles cider)))) + (assq 'styles cider))) (found-cycle (when-let ((cider (assq 'cider completion-category-overrides))) (assq 'cycle cider)))) (setq completion-category-overrides (seq-remove (lambda (x) (equal 'cider (car x))) completion-category-overrides)) (unless found-styles - (setq found-styles '(basic))) - (cl-pushnew 'flex found-styles) - (add-to-list 'completion-category-overrides (apply #'list 'cider - (apply #'list 'styles found-styles) - (when found-cycle - (list found-cycle)))))) + (setq found-styles '(styles basic))) + (unless (member 'flex found-styles) + (setq found-styles (append found-styles '(flex)))) + (add-to-list 'completion-category-overrides (apply #'list 'cider found-styles (when found-cycle + (list found-cycle)))))) (provide 'cider-completion) ;;; cider-completion.el ends here diff --git a/test/cider-completion-tests.el b/test/cider-completion-tests.el index 5f79c089f..4553b2628 100644 --- a/test/cider-completion-tests.el +++ b/test/cider-completion-tests.el @@ -38,8 +38,8 @@ (progn (it "adds `flex' and `basic' as a fallback" (cider-enable-flex-completion) - (expect (car (cdr (assq 'styles (assq 'cider completion-category-overrides)))) - :to-be 'flex) + (expect (member 'flex (assq 'styles (assq 'cider completion-category-overrides))) + :to-be-truthy) (expect (member 'basic (assq 'styles (assq 'cider completion-category-overrides))) :to-be-truthy)) @@ -47,11 +47,11 @@ (expect (assq 'cycle (assq 'cider completion-category-overrides)) :to-be nil)) - (it "adds just `flex' if there is another style present" + (it "adds just `flex' if there is another syle present" (setq completion-category-overrides '((cider (styles partial-completion)))) (cider-enable-flex-completion) - (expect (car (cdr (assq 'styles (assq 'cider completion-category-overrides)))) - :to-be 'flex) + (expect (member 'flex (assq 'styles (assq 'cider completion-category-overrides))) + :to-be-truthy) (expect (member 'partial-completion (assq 'styles (assq 'cider completion-category-overrides))) :to-be-truthy) (expect (member 'basic (assq 'styles (assq 'cider completion-category-overrides))) From 981669027fc715b8ce8d5ddec58e1d0a6650f242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Thu, 16 May 2024 03:18:41 -0300 Subject: [PATCH 16/20] fix spelling --- test/cider-completion-tests.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cider-completion-tests.el b/test/cider-completion-tests.el index 4553b2628..91b7a198d 100644 --- a/test/cider-completion-tests.el +++ b/test/cider-completion-tests.el @@ -47,7 +47,7 @@ (expect (assq 'cycle (assq 'cider completion-category-overrides)) :to-be nil)) - (it "adds just `flex' if there is another syle present" + (it "adds just `flex' if there is another style present" (setq completion-category-overrides '((cider (styles partial-completion)))) (cider-enable-flex-completion) (expect (member 'flex (assq 'styles (assq 'cider completion-category-overrides))) From a195f68e35ab6e88d57d743816c26b7a6e8b23d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Thu, 16 May 2024 21:08:45 -0300 Subject: [PATCH 17/20] Update docs --- .../ROOT/pages/usage/code_completion.adoc | 54 +++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/doc/modules/ROOT/pages/usage/code_completion.adoc b/doc/modules/ROOT/pages/usage/code_completion.adoc index c83dcc66e..ebe62349d 100644 --- a/doc/modules/ROOT/pages/usage/code_completion.adoc +++ b/doc/modules/ROOT/pages/usage/code_completion.adoc @@ -37,18 +37,27 @@ is already properly indented. == Completion styles -CIDER defines (via the `completion-styles-alist` Elisp variable) a completion category named `cider`. +CIDER defines a specialized completion category through the `cider-complete-at-point` function, +added to `completion-at-point-functions`, establishing a dedicated completion category named +`cider`. -The `cider` completion category currently only supports `basic` completion styles (and not `partial-completion`, `orderless`, etc), -and `flex`, optionally (read more below). +The CIDER completion at point function supports most completion styles, including +`partial-completion`, `orderless` and `flex` (read more below). -CIDER declares so in this fashion: + +Sometimes the user may want to use a different completion style just for the CIDER +complete at point function. That can be achieved by setting +`completion-category-overrides`, overriting the completion style of the CIDER +complete at point function. The following snippet accomplishes that: [source,lisp] ---- (add-to-list 'completion-category-overrides '(cider (styles basic))) ---- +This specifies that the `cider` completion category should employ the basic completion style by +default. + You can also enable the `flex` completion style by activating xref:usage/code_completion.adoc#fuzzy-candidate-matching[fuzzy candidate matching]. == Auto-completion @@ -131,13 +140,14 @@ without needing to hit an extra key, please customize: === Fuzzy candidate matching -By default, CIDER will provide completion candidates with the -assumption that whatever you've typed so far is a prefix of what -you're really trying to type. For example, if you type `map-` then -you'll only get completion candidates that have `map-` as the -beginning of their names. Sometimes, you don't know the exact prefix -for the item you want to type. In this case, you can get -CIDER-specific "fuzzy completion" by setting up in your Emacs init file: +By default, CIDER will use the completion styles defined in +`completion-styles`, the defaults being `(basic partial-completion +emacs22)` since Emacs 23. For a better description of how those +completion styles operates, refer to the official Emacs manual on +https://www.gnu.org/software/emacs/manual/html_node/emacs/Completion-Styles.html[how completion alternatives are chosen]. + +CIDER provides a function to enable the `flex` completion style for CIDER-specific +completions. If you wish to enable that, you can add this to your config: [source,lisp] ---- @@ -146,11 +156,11 @@ CIDER-specific "fuzzy completion" by setting up in your Emacs init file: This adds the `flex` completion style, as introduced in Emacs 27. -Now, `company-mode` will accept certain fuzziness when matching -candidates against the prefix. For example, typing `mi` will show you -`map-indexed` as one of the possible completion candidates and `cji` -will complete to `clojure.java.io`. Different completion examples are -shown +Now, `company-mode` (and other completion packages like `corfu`) will +accept certain fuzziness when matching candidates against the +prefix. For example, typing `mi` will show you `map-indexed` as one of +the possible completion candidates and `cji` will complete to +`clojure.java.io`. Different completion examples are shown https://github.com/alexander-yakushev/compliment/wiki/Examples[here]. NOTE: `cider-company-enable-fuzzy-completion` (now deprecated) should be used for Emacs < 27. @@ -189,18 +199,6 @@ keys to cancel the prompt by customizing: (funcall f a b)))) ---- -=== Changing the completion style - -Sometimes the user may want to use a different completion style just for the CIDER -complete at point function. That can be achieved by setting -`completion-category-defaults`, overriting the completion style of the CIDER -complete at point function. The following snippet accomplishes that: - -[source,lisp] ----- -(add-to-list 'completion-category-defaults '(cider (styles basic))) ----- - === Updating stale classes and methods cache Sometimes, the completion fails to recognize new classes that came with From 6cd296bafe522f4475346837ab9f42421b2f1529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Thu, 16 May 2024 23:30:22 -0300 Subject: [PATCH 18/20] update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1631660a..4ac25f90a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ ### Bugs fixed +- [#3659](https://github.com/clojure-emacs/cider/pull/3659): Fixes completions when using `flex`-like completion styles. - [#3600](https://github.com/clojure-emacs/cider/pull/3600): Fix scittle jack-in when using `cider-jack-in-clj`. ## 1.13.1 (2024-02-01) From 59ab7c88bbb5e8f99623577afe963c1ece149c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Thu, 16 May 2024 23:31:11 -0300 Subject: [PATCH 19/20] fix spelling --- doc/modules/ROOT/pages/usage/code_completion.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/modules/ROOT/pages/usage/code_completion.adoc b/doc/modules/ROOT/pages/usage/code_completion.adoc index ebe62349d..9665b99c7 100644 --- a/doc/modules/ROOT/pages/usage/code_completion.adoc +++ b/doc/modules/ROOT/pages/usage/code_completion.adoc @@ -47,7 +47,7 @@ The CIDER completion at point function supports most completion styles, includin Sometimes the user may want to use a different completion style just for the CIDER complete at point function. That can be achieved by setting -`completion-category-overrides`, overriting the completion style of the CIDER +`completion-category-overrides`, overwriting the completion style of the CIDER complete at point function. The following snippet accomplishes that: [source,lisp] From 86344430becc0509a2a88fd50720a791bc805b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20=C3=81vila?= Date: Thu, 16 May 2024 23:35:51 -0300 Subject: [PATCH 20/20] test if the completion-override it exactly as expected --- test/cider-completion-tests.el | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/cider-completion-tests.el b/test/cider-completion-tests.el index 91b7a198d..e80f4253a 100644 --- a/test/cider-completion-tests.el +++ b/test/cider-completion-tests.el @@ -37,11 +37,13 @@ (unwind-protect (progn (it "adds `flex' and `basic' as a fallback" - (cider-enable-flex-completion) - (expect (member 'flex (assq 'styles (assq 'cider completion-category-overrides))) - :to-be-truthy) - (expect (member 'basic (assq 'styles (assq 'cider completion-category-overrides))) - :to-be-truthy)) + (let ((expected-category-overrides '((cider (styles basic flex))))) + (cider-enable-flex-completion) + (expect (member 'flex (assq 'styles (assq 'cider completion-category-overrides))) + :to-be-truthy) + (expect (member 'basic (assq 'styles (assq 'cider completion-category-overrides))) + :to-be-truthy) + (expect completion-category-overrides :to-equal expected-category-overrides))) (it "doesn't add `cycle'" (expect (assq 'cycle (assq 'cider completion-category-overrides))