Skip to content

[completion] Enable cider-completion-style by default #3797

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- [#3790](https://github.com/clojure-emacs/cider/issues/3790): Stacktrace: show messages and data for all exception causes by default.
- [#3789](https://github.com/clojure-emacs/cider/issues/3789): Refactor and simplify exception handling.
- [#3789](https://github.com/clojure-emacs/cider/issues/3796): Completion: disable client-side sorting (defer to backend-provided candidate order).
- [#3797](https://github.com/clojure-emacs/cider/issues/3797): Completion: enable `cider-completion-style` by default (this enables richer completion suggestions where candidates don't have to strictly match the prefix).

## 1.17.1 (2025-02-25)

Expand Down
42 changes: 22 additions & 20 deletions cider-completion.el
Original file line number Diff line number Diff line change
Expand Up @@ -283,27 +283,31 @@ DEPRECATED: please use `cider-enable-cider-completion-style' instead."
(interactive)
(cider-enable-cider-completion-style))

(defun cider-enable-cider-completion-style ()
"Enables `cider' completion style for CIDER in all buffers.
(defun cider-enable-cider-completion-style (&optional arg)
"Enables or disables `cider' completion style for CIDER in all buffers.

This style supports non-prefix completion candidates returned by the
completion backend. Only affects the `cider' completion category."
completion backend. Only affects the `cider' completion category. If ARG
is `1' or nil, enables the custom completion style; if `-1', disables it."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be more idiomatic for anything non-nil to enable it and for nil to disable it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that people currently have this function in their configs, and it now accepts zero arguments. To reuse the same function, we need to make ARG optional, and it means it arrives as nil when people want to enable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bbatsov So is this OK to leave as is or is there a better solution?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I guess it is.

(interactive)
(let* ((cider (assq 'cider completion-category-overrides))
(found-styles (assq 'styles cider))
(new-styles (if found-styles
(cons 'styles (cons 'cider (cdr found-styles)))
'(styles cider basic)))
(new-cider (if cider
(cons 'cider
(cons new-styles
(seq-remove (lambda (x) (equal 'styles (car x)))
(cdr cider))))
(list 'cider new-styles)))
(new-overrides (cons new-cider
(seq-remove (lambda (x) (equal 'cider (car x)))
completion-category-overrides))))
(setq completion-category-overrides new-overrides)))
(if (= arg -1)
(setq completion-category-overrides
(assq-delete-all 'cider completion-category-overrides))
(let* ((cider (assq 'cider completion-category-overrides))
(found-styles (assq 'styles cider))
(new-styles (if found-styles
(cons 'styles (cons 'cider (cdr found-styles)))
'(styles cider basic)))
(new-cider (if cider
(cons 'cider
(cons new-styles
(seq-remove (lambda (x) (equal 'styles (car x)))
(cdr cider))))
(list 'cider new-styles)))
(new-overrides (cons new-cider
(seq-remove (lambda (x) (equal 'cider (car x)))
completion-category-overrides))))
(setq completion-category-overrides new-overrides))))

(make-obsolete 'cider-company-enable-fuzzy-completion 'cider-enable-cider-completion-style "1.17.0")

Expand All @@ -312,8 +316,6 @@ completion backend. Only affects the `cider' completion category."

Only affects the `cider' completion category.`"
(interactive)
(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)))
(found-cycle (when-let ((cider (assq 'cider completion-category-overrides)))
Expand Down
1 change: 1 addition & 0 deletions cider-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,7 @@ property."
(setq-local clojure-expected-ns-function #'cider-expected-ns)
(when cider-use-xref
(add-hook 'xref-backend-functions #'cider--xref-backend cider-xref-fn-depth 'local))
(cider-enable-cider-completion-style 1)
(setq next-error-function #'cider-jump-to-compilation-error))
;; Mode cleanup
(mapc #'kill-local-variable '(next-error-function
Expand Down
86 changes: 41 additions & 45 deletions doc/modules/ROOT/pages/usage/code_completion.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,32 +35,6 @@ Normally kbd:[TAB] only indents, but now it will also do completion if the code
is already properly indented.
====

== Completion styles

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 at point function supports most completion styles,
including `partial-completion`, `orderless` and `flex`. It also supports a
custom completion style that is confusingly named `cider` too. Activating it
provides a richer set of completion candidates (see
xref:usage/code_completion.adoc#fuzzy-candidate-matching[fuzzy candidate
matching]).

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`, overwriting 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.

== Auto-completion

While the standard Emacs tooling works just fine, we suggest that
Expand Down Expand Up @@ -139,31 +113,30 @@ without needing to hit an extra key, please customize:
(custom-set-variables '(company-auto-update-doc t))
----

=== Fuzzy candidate matching
=== Rich candidate matching

Starting with version 1.18, CIDER by default enables a custom completion style
that provides richer and more useful candidate matching, for example:

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].
- Long vars that contain dashes by first characters of individual parts, e.g.
`mi` or `mai` complete to `map-indexed`.
- Namespaces by first characters of parts, e.g. `cji` completes to
`clojure.java.io`.
- Not imported classnames by their short name prefixes, e.g. `BiFun` completes
to `java.util.function.BiFunction`.

You can learn all completion scenarios and features
https://github.com/alexander-yakushev/compliment/wiki/Examples[here].

CIDER provides a function to enable the `cider` completion style for CIDER-specific
completions. If you wish to enable that, you can add this to your config:
If you only want to receive standard prefix-restricted completions (where the
candidate must contain the prefix at the beginning verbatim), you can disable
this feature by adding this to your config:

[source,lisp]
----
(cider-enable-cider-completion-style)
(cider-enable-cider-completion-style -1)
----

This adds the `cider` completion style for CIDER buffers.

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].

=== Completion annotations

Completion candidates will be annotated by default with an abbreviation
Expand All @@ -178,6 +151,29 @@ image::completion-annotations.png[Completion Annotations]
TIP: Completion annotations can be disabled by setting
`cider-annotate-completion-candidates` to `nil`.

=== Completion styles

The CIDER completion at point function supports most completion styles,
including `partial-completion`, `orderless`, `flex`, and its own custom
completion style named `cider`. The latter is enabled by default. Sometimes the
user may want to use a different completion style for the CIDER complete at
point function. That can be achieved by setting `completion-category-overrides`,
overwriting 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)))
----

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].

This specifies that the `cider` completion category should employ the basic completion style by
default.

=== Notes on class disambiguation

Sometimes, the completion user experience may be interrupted by a `completing-read`
Expand Down Expand Up @@ -212,6 +208,6 @@ NOTE: You don't really need to know any of this if you're using only `cider-jack

The bulk of the code completion logic resides in `cider-nrepl` https://github.com/clojure-emacs/cider-nrepl/blob/master/src/cider/nrepl/middleware/complete.clj[completion middleware]. Internally it delegates to `compliment` for the Clojure completion and `clj-suitable` for the ClojureScript completion.

Starting with nREPL 0.8, there's also a built-in `completions` nREPL op that CIDER will fallback to, in the absence of `cider-nrepl`. Its API is similar to that of the `complete` op in `cider-nrepl` and it can be configured to use different completion functions. The built-in op currently supports only Clojure. See the https://nrepl.org/nrepl/usage/misc.html#code-completion[nREPL docs] for more details.
nREPL also has a built-in `completions` op that CIDER will fallback to, in the absence of `cider-nrepl`. Its API is similar to that of the `complete` op in `cider-nrepl` and it can be configured to use different completion functions. The built-in op currently supports only Clojure. See the https://nrepl.org/nrepl/usage/misc.html#code-completion[nREPL docs] for more details.

Basically, you'll get great code completion in the presence of `cider-nrepl` and basic completion otherwise.