Skip to content

Commit 36737a9

Browse files
authored
Introduce cider-enable-flex-completion (#3509)
Replaces `cider-company-enable-fuzzy-completion`, which is now deprecated.
1 parent 181bbcc commit 36737a9

File tree

4 files changed

+101
-10
lines changed

4 files changed

+101
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050

5151
- Ensure that `cider` completion isn't used with completion styles that are currently unsupported (`initials`, `partial-completion`, `orderless`, etc).
5252
- This restores completions for users that favor those styles - otherwise the would see bad or no completions.
53+
- Relatedly, `cider-company-enable-fuzzy-completion` is now deprecated in favor of `cider-enable-flex-completion`.
5354
- Improve support for multiple forms in the same line by replacing `beginning-of-defun` fn.
5455
- [#3390](https://github.com/clojure-emacs/cider/issues/3390): Enhance `cider-connect` to show all nREPLs available ports, instead of only Leiningen ones.
5556
- [#3408](https://github.com/clojure-emacs/cider/issues/3408): `cider-connect`: check `.nrepl-port`-like files for liveness, hiding them if they don't reflect an active port.

cider-completion.el

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
(require 'cider-docstring)
3737
(require 'cider-eldoc)
3838
(require 'nrepl-dict)
39+
(require 'seq)
3940

4041
(defcustom cider-annotate-completion-candidates t
4142
"When true, annotate completion candidates with some extra information."
@@ -193,7 +194,7 @@ performed by `cider-annotate-completion-function'."
193194
;;
194195
;; This api is better described in the section
195196
;; '21.6.7 Programmed Completion' of the elisp manual.
196-
(cond ((eq action 'metadata) `(metadata (category . cider)))
197+
(cond ((eq action 'metadata) `(metadata (category . cider))) ;; defines a completion category named 'cider, used later in our `completion-category-overrides` logic.
197198
((eq (car-safe action) 'boundaries) nil)
198199
(t (with-current-buffer (current-buffer)
199200
(complete-with-action action
@@ -243,6 +244,12 @@ in the buffer."
243244
"Return CIDER completion candidates for STRING as is, unfiltered."
244245
(cider-complete string))
245246

247+
;; defines a completion style named `cider' (which ideally would have been named `cider-fuzzy').
248+
;; note that there's already a completion category named `cider' (grep for `(metadata (category . cider))` in this file),
249+
;; which can be confusing given the identical name.
250+
;; The `cider' completion style should be removed because the `flex' style is essentially equivalent.
251+
;; (To be fair, `flex' was introduced in Emacs 27, 3 years in after our commit 04e428b
252+
;; which introduced `cider-company-enable-fuzzy-completion')
246253
(add-to-list 'completion-styles-alist
247254
'(cider
248255
cider-company-unfiltered-candidates
@@ -252,11 +259,35 @@ in the buffer."
252259
;; Currently CIDER completions only work for `basic`, and not `initials`, `partial-completion`, `orderless`, etc.
253260
;; So we ensure that those other styles aren't used with CIDER, otherwise one would see bad or no completions at all.
254261
;; This `add-to-list` call can be removed once we implement the other completion styles.
255-
(add-to-list 'completion-category-overrides '(cider (styles basic flex)))
262+
;; (When doing that, please refactor `cider-enable-flex-completion' as well)
263+
(add-to-list 'completion-category-overrides '(cider (styles basic)))
256264

257265
(defun cider-company-enable-fuzzy-completion ()
258-
"Enable backend-driven fuzzy completion in the current buffer."
266+
"Enable backend-driven fuzzy completion in the current buffer.
267+
268+
DEPRECATED: please use `cider-enable-flex-completion' instead."
259269
(setq-local completion-styles '(cider)))
260270

271+
(make-obsolete 'cider-company-enable-fuzzy-completion 'cider-enable-flex-completion "1.8.0")
272+
273+
(defun cider-enable-flex-completion ()
274+
"Enables `flex' (fuzzy) completion for CIDER in all buffers.
275+
276+
Only affects the `cider' completion category.`"
277+
(interactive)
278+
(when (< emacs-major-version 27)
279+
(user-error "`cider-enable-flex-completion' requires Emacs 27 or later"))
280+
(let ((found-styles (when-let ((cider (assq 'cider completion-category-overrides)))
281+
(assq 'styles cider)))
282+
(found-cycle (when-let ((cider (assq 'cider completion-category-overrides)))
283+
(assq 'cycle cider))))
284+
(setq completion-category-overrides (seq-remove (lambda (x)
285+
(equal 'cider (car x)))
286+
completion-category-overrides))
287+
(unless (member 'flex found-styles)
288+
(setq found-styles (append found-styles '(flex))))
289+
(add-to-list 'completion-category-overrides (apply #'list 'cider found-styles (when found-cycle
290+
(list found-cycle))))))
291+
261292
(provide 'cider-completion)
262293
;;; cider-completion.el ends here

doc/modules/ROOT/pages/usage/code_completion.adoc

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,17 @@ is already properly indented.
3939

4040
CIDER defines (via the `completion-styles-alist` Elisp variable) a completion category named `cider`.
4141

42-
The `cider` completion category currently only supports `basic` and `flex` completion styles (and not `partial-completion`, `orderless`, etc).
42+
The `cider` completion category currently only supports `basic` completion styles (and not `partial-completion`, `orderless`, etc),
43+
and `flex`, optionally (read more below).
4344

4445
CIDER declares so in this fashion:
4546

4647
[source,lisp]
4748
----
48-
(add-to-list 'completion-category-overrides '(cider (styles basic flex)))
49+
(add-to-list 'completion-category-overrides '(cider (styles basic)))
4950
----
5051

51-
Note that `flex` will only work if you also enabled xref:usage/code_completion.adoc#fuzzy-candidate-matching[fuzzy candidate matching].
52+
You can also enable the `flex` completion style by activating xref:usage/code_completion.adoc#fuzzy-candidate-matching[fuzzy candidate matching].
5253

5354
== Auto-completion
5455

@@ -130,27 +131,30 @@ without needing to hit an extra key, please customize:
130131

131132
=== Fuzzy candidate matching
132133

133-
By default `company-mode` will provide completion candidates with the
134+
By default, CIDER will provide completion candidates with the
134135
assumption that whatever you've typed so far is a prefix of what
135136
you're really trying to type. For example, if you type `map-` then
136137
you'll only get completion candidates that have `map-` as the
137138
beginning of their names. Sometimes, you don't know the exact prefix
138139
for the item you want to type. In this case, you can get
139-
CIDER-specific "fuzzy completion" by adding:
140+
CIDER-specific "fuzzy completion" by setting up in your Emacs init file:
140141

141142
[source,lisp]
142143
----
143-
(add-hook 'cider-repl-mode-hook #'cider-company-enable-fuzzy-completion)
144-
(add-hook 'cider-mode-hook #'cider-company-enable-fuzzy-completion)
144+
(cider-enable-flex-completion)
145145
----
146146

147+
This adds the `flex` completion style, as introduced in Emacs 27.
148+
147149
Now, `company-mode` will accept certain fuzziness when matching
148150
candidates against the prefix. For example, typing `mi` will show you
149151
`map-indexed` as one of the possible completion candidates and `cji`
150152
will complete to `clojure.java.io`. Different completion examples are
151153
shown
152154
https://github.com/alexander-yakushev/compliment/wiki/Examples[here].
153155

156+
NOTE: `cider-company-enable-fuzzy-completion` (now deprecated) should be used for Emacs < 27.
157+
154158
=== Completion annotations
155159

156160
Completion candidates will be annotated by default with an abbreviation

test/cider-completion-tests.el

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
;;; cider-completion-tests.el -*- lexical-binding: t; -*-
2+
3+
;; Copyright © 2012-2023 Bozhidar Batsov
4+
5+
;; Author: Bozhidar Batsov <[email protected]>
6+
7+
;; This file is NOT part of GNU Emacs.
8+
9+
;; This program is free software: you can redistribute it and/or
10+
;; modify it under the terms of the GNU General Public License as
11+
;; published by the Free Software Foundation, either version 3 of the
12+
;; License, or (at your option) any later version.
13+
;;
14+
;; This program is distributed in the hope that it will be useful, but
15+
;; WITHOUT ANY WARRANTY; without even the implied warranty of
16+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
;; General Public License for more details.
18+
;;
19+
;; You should have received a copy of the GNU General Public License
20+
;; along with this program. If not, see `http://www.gnu.org/licenses/'.
21+
22+
;;; Commentary:
23+
24+
;; This file is part of CIDER
25+
26+
;;; Code:
27+
28+
(require 'buttercup)
29+
(require 'cider-completion)
30+
31+
;; Please, for each `describe', ensure there's an `it' block, so that its execution is visible in CI.
32+
33+
(describe "cider-enable-flex-completion"
34+
(when (>= emacs-major-version 27)
35+
(cl-assert (not (member 'flex (assq 'styles (assq 'cider completion-category-overrides)))))
36+
(let ((old-value completion-category-overrides))
37+
(unwind-protect
38+
(progn
39+
(it "adds `flex'"
40+
(cider-enable-flex-completion)
41+
(expect (member 'flex (assq 'styles (assq 'cider completion-category-overrides)))
42+
:to-be-truthy))
43+
44+
(it "doesn't add `cycle'"
45+
(expect (assq 'cycle (assq 'cider completion-category-overrides))
46+
:to-be nil))
47+
48+
(it "doesn't re-add `flex' if already present, preserving `cycle' as well"
49+
(let ((with-flex-and-cycle '((cider (styles basic flex)
50+
(cycle t)))))
51+
(setq completion-category-overrides with-flex-and-cycle)
52+
(cider-enable-flex-completion)
53+
(expect completion-category-overrides
54+
:to-equal with-flex-and-cycle))))
55+
(setq completion-category-overrides old-value)))))

0 commit comments

Comments
 (0)