Skip to content

Commit ee1975d

Browse files
authored
Introduce Java doc comment rendering (#3472)
1 parent 5edfbc0 commit ee1975d

20 files changed

+657
-125
lines changed

.dir-locals.el

-4
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,10 @@
88
(fill-column . 80)
99
(sentence-end-double-space . t)
1010
(emacs-lisp-docstring-fill-column . 75)
11-
;; slightly increase the maximum (applies to checkdoc and the byte compiler alike)
12-
(byte-compile-docstring-max-column 100)
1311
(checkdoc-symbol-words . ("top-level" "major-mode" "macroexpand-all" "print-level" "print-length"))
1412
(checkdoc-package-keywords-flag)
1513
(checkdoc-arguments-in-order-flag)
1614
(checkdoc-verb-check-experimental-flag)
17-
;; allow commas to indicate that the first sentence continues, which enables longer first sentences
18-
(checkdoc-permit-comma-termination-flag t)
1915
(elisp-lint-indent-specs . ((if-let* . 2)
2016
(when-let* . 1)
2117
(let* . defun)

.github/workflows/test.yml

+10-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ jobs:
2323
matrix:
2424
os: [macos-latest, ubuntu-latest, windows-latest]
2525
emacs_version: ['26.3', '27.2', '28.2', '29.1']
26+
java_version: ['11', '17']
2627

2728
steps:
2829
- name: Set up Emacs
@@ -67,7 +68,7 @@ jobs:
6768
with:
6869
distribution: 'temurin'
6970
# shadow requires java 11
70-
java-version: 11
71+
java-version: ${{matrix.java_version}}
7172

7273
- name: Install Clojure Tools
7374
# Use SHA until
@@ -91,3 +92,11 @@ jobs:
9192
# be GH connectivity runner issues. We attempt to address this
9293
# problem by rerunning the tests more than once.
9394
eldev -p -dtTC test --test-type integration || eldev -p -dtTC test --test-type integration
95+
96+
- name: Run tests that need enrich-classpath
97+
if: "!startsWith(matrix.os, 'windows')"
98+
run: |
99+
cd dev; ../clojure.sh clojure -M:gen; cd -
100+
wc -l test/File.edn
101+
eldev -p -dtTC test --test-type enrich || eldev -p -dtTC test --test-type enrich
102+

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ cider-pkg.el
1616
cider-refcard.aux
1717
cider-refcard.log
1818
doc/auto/
19+
test/*.edn

Eldev

+9-2
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,32 @@
1111
(eldev-add-loading-roots 'test "test/utils")
1212
(eldev-add-extra-dependencies 'runtime '(:package logview :optional t))
1313

14+
;; slightly increase the maximum (applies to checkdoc and the byte compiler alike)
15+
(setq byte-compile-docstring-max-column 100)
16+
17+
;; allow commas to indicate that the first sentence continues, which enables longer first sentences
18+
(setq checkdoc-permit-comma-termination-flag t)
19+
1420
(defvar cider-test-type 'main)
1521
(setf eldev-standard-excludes `(:or ,eldev-standard-excludes
1622
;; Avoid including files in test "projects".
1723
(eldev-pcase-exhaustive cider-test-type
1824
(`main "./test/*/")
1925
(`integration '("./test/" "!./test/integration"))
26+
(`enrich '("./test/" "!./test/enrich"))
2027
(`all '("./test/*/" "!./test/integration")))
2128
"test/integration/projects"
2229
;; This file is _supposed_ to be excluded
2330
;; from automated testing.
2431
"test/cider-tests--no-auto.el"))
2532

2633
(eldev-defoption cider-test-selection (type)
27-
"Select tests to run; type can be `main', `integration' or `all'"
34+
"Select tests to run; type can be `main', `integration', `enrich' or `all'"
2835
:options (-T --test-type)
2936
:for-command test
3037
:value TYPE
3138
:default-value cider-test-type
32-
(unless (memq (intern type) '(main integration all))
39+
(unless (memq (intern type) '(main integration enrich all))
3340
(signal 'eldev-wrong-option-usage `("unknown test type `%s'" ,type)))
3441
(setf cider-test-type (intern type)))
3542

Makefile

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@ lint: clean
1919
compile: clean
2020
eldev -dtT compile --warnings-as-errors
2121

22-
test-all: clean
22+
test/File.edn:
23+
cd dev; ../clojure.sh clojure -M:gen
24+
25+
test-all: clean test/File.edn
2326
eldev -dtT -p test --test-type all
2427

28+
test-enrich: clean test/File.edn
29+
eldev -dtT -p test --test-type enrich
30+
2531
test-integration: clean
2632
eldev -dtT -p test --test-type integration
2733

cider-client.el

+11-8
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
(require 'spinner)
3535

3636
(require 'cider-connection)
37+
(require 'cider-completion-context)
3738
(require 'cider-common)
3839
(require 'cider-util)
3940
(require 'nrepl-client)
@@ -520,15 +521,15 @@ When multiple matching vars are returned you'll be prompted to select one,
520521
unless ALL is truthy."
521522
(when (and var (not (string= var "")))
522523
(let ((var-info (cond
523-
((cider-nrepl-op-supported-p "info") (cider-sync-request:info var))
524+
((cider-nrepl-op-supported-p "info") (cider-sync-request:info var nil nil (cider-completion-get-context t)))
524525
((cider-nrepl-op-supported-p "lookup") (cider-sync-request:lookup var))
525526
(t (cider-fallback-eval:info var)))))
526527
(if all var-info (cider--var-choice var-info)))))
527528

528529
(defun cider-member-info (class member)
529530
"Return the CLASS MEMBER's info as an alist with list cdrs."
530531
(when (and class member)
531-
(cider-sync-request:info nil class member)))
532+
(cider-sync-request:info nil class member (cider-completion-get-context t))))
532533

533534

534535
;;; Requests
@@ -646,13 +647,14 @@ CONTEXT represents a completion context for compliment."
646647
nil
647648
'abort-on-input))
648649

649-
(defun cider-sync-request:info (symbol &optional class member)
650-
"Send \"info\" op with parameters SYMBOL or CLASS and MEMBER."
650+
(defun cider-sync-request:info (symbol &optional class member context)
651+
"Send \"info\" op with parameters SYMBOL or CLASS and MEMBER, honor CONTEXT."
651652
(let ((var-info (thread-first `("op" "info"
652653
"ns" ,(cider-current-ns)
653654
,@(when symbol `("sym" ,symbol))
654655
,@(when class `("class" ,class))
655-
,@(when member `("member" ,member)))
656+
,@(when member `("member" ,member))
657+
,@(when context `("context" ,context)))
656658
(cider-nrepl-send-sync-request (cider-current-repl)))))
657659
(if (member "no-info" (nrepl-dict-get var-info "status"))
658660
nil
@@ -669,13 +671,14 @@ CONTEXT represents a completion context for compliment."
669671
nil
670672
(nrepl-dict-get var-info "info"))))
671673

672-
(defun cider-sync-request:eldoc (symbol &optional class member)
673-
"Send \"eldoc\" op with parameters SYMBOL or CLASS and MEMBER."
674+
(defun cider-sync-request:eldoc (symbol &optional class member context)
675+
"Send \"eldoc\" op with parameters SYMBOL or CLASS and MEMBER, honor CONTEXT."
674676
(when-let* ((eldoc (thread-first `("op" "eldoc"
675677
"ns" ,(cider-current-ns)
676678
,@(when symbol `("sym" ,symbol))
677679
,@(when class `("class" ,class))
678-
,@(when member `("member" ,member)))
680+
,@(when member `("member" ,member))
681+
,@(when context `("context" ,context)))
679682
(cider-nrepl-send-sync-request (cider-current-repl)
680683
'abort-on-input))))
681684
(if (member "no-eldoc" (nrepl-dict-get eldoc "status"))

cider-completion-context.el

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
;;; cider-completion-context.el --- Context parsing -*- lexical-binding: t -*-
2+
3+
;; Copyright © 2013-2023 Bozhidar Batsov, Artur Malabarba and CIDER contributors
4+
;;
5+
;; Author: Bozhidar Batsov <[email protected]>
6+
;; Artur Malabarba <[email protected]>
7+
8+
;; This program is free software: you can redistribute it and/or modify
9+
;; it under the terms of the GNU General Public License as published by
10+
;; the Free Software Foundation, either version 3 of the License, or
11+
;; (at your option) any later version.
12+
13+
;; This program is distributed in the hope that it will be useful,
14+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
;; GNU General Public License for more details.
17+
18+
;; You should have received a copy of the GNU General Public License
19+
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
20+
21+
;; This file is not part of GNU Emacs.
22+
23+
;;; Commentary:
24+
25+
;; Context-parsing utilities. Extracted from cider-completion.el.
26+
27+
;;; Code:
28+
29+
(defcustom cider-completion-use-context t
30+
"When true, uses context at point to improve completion suggestions."
31+
:type 'boolean
32+
:group 'cider
33+
:package-version '(cider . "0.7.0"))
34+
35+
(defun cider-completion--bounds-of-non-string-symbol-at-point ()
36+
"Returns the bounds of the symbol at point, unless it's inside a string."
37+
(let ((sap (symbol-at-point)))
38+
(when (and sap (not (nth 3 (syntax-ppss))))
39+
(bounds-of-thing-at-point 'symbol))))
40+
41+
(defun cider-completion-symbol-start-pos ()
42+
"Find the starting position of the symbol at point, unless inside a string."
43+
(car (cider-completion--bounds-of-non-string-symbol-at-point)))
44+
45+
(defun cider-completion-symbol-end-pos ()
46+
"Find the end position of the symbol at point, unless inside a string."
47+
(cdr (cider-completion--bounds-of-non-string-symbol-at-point)))
48+
49+
(defun cider-completion-get-info-context-at-point ()
50+
"Extract a context at point that is suitable for eldoc and info ops.
51+
Note that this context is slightly different than that of
52+
`cider-completion-get-context-at-point': this one does not include
53+
the current symbol at point."
54+
(when (save-excursion
55+
(condition-case _
56+
(progn
57+
(up-list)
58+
(check-parens)
59+
t)
60+
(scan-error nil)
61+
(user-error nil)))
62+
(save-excursion
63+
(let* ((pref-start (cider-completion-symbol-start-pos))
64+
(context (cider-defun-at-point))
65+
(end (cider-completion-symbol-end-pos))
66+
(_ (beginning-of-defun-raw))
67+
(expr-start (point))
68+
(_ (if (derived-mode-p 'cider-repl-mode)
69+
(goto-char (point-max))
70+
(end-of-defun)))
71+
(expr-end (point)))
72+
(string-remove-suffix "\n"
73+
(concat (when pref-start (substring context 0 (- pref-start expr-start)))
74+
"__prefix__"
75+
(substring context (- (- expr-end end)))))))))
76+
77+
(defun cider-completion-get-context-at-point ()
78+
"Extract the context at point.
79+
If point is not inside the list, returns nil; otherwise return \"top-level\"
80+
form, with symbol at point replaced by __prefix__."
81+
(when (save-excursion
82+
(condition-case _
83+
(progn
84+
(up-list)
85+
(check-parens)
86+
t)
87+
(scan-error nil)
88+
(user-error nil)))
89+
(save-excursion
90+
(let* ((pref-end (point))
91+
(pref-start (cider-completion-symbol-start-pos))
92+
(context (cider-defun-at-point))
93+
(_ (beginning-of-defun-raw))
94+
(expr-start (point)))
95+
(concat (when pref-start (substring context 0 (- pref-start expr-start)))
96+
"__prefix__"
97+
(substring context (- pref-end expr-start)))))))
98+
99+
(defvar cider-completion-last-context nil)
100+
101+
(defun cider-completion-get-context (&optional info)
102+
"Extract context depending (maybe of INFO type).
103+
104+
Output depends on `cider-completion-use-context' and the current major mode."
105+
(let ((context (if cider-completion-use-context
106+
;; We use ignore-errors here since grabbing the context
107+
;; might fail because of unbalanced parens, or other
108+
;; technical reasons, yet we don't want to lose all
109+
;; completions and throw error to user because of that.
110+
(or (ignore-errors
111+
(if info
112+
(cider-completion-get-info-context-at-point)
113+
(cider-completion-get-context-at-point)))
114+
"nil")
115+
"nil")))
116+
(if (string= cider-completion-last-context context)
117+
":same"
118+
(setq cider-completion-last-context context)
119+
context)))
120+
121+
(provide 'cider-completion-context)
122+
;;; cider-completion-context.el ends here

cider-completion.el

+7-61
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,12 @@
3131

3232
(require 'cider-client)
3333
(require 'cider-common)
34+
(require 'cider-completion-context)
3435
(require 'cider-doc)
36+
(require 'cider-docstring)
3537
(require 'cider-eldoc)
3638
(require 'nrepl-dict)
3739

38-
(defcustom cider-completion-use-context t
39-
"When true, uses context at point to improve completion suggestions."
40-
:type 'boolean
41-
:group 'cider
42-
:package-version '(cider . "0.7.0"))
43-
4440
(defcustom cider-annotate-completion-candidates t
4541
"When true, annotate completion candidates with some extra information."
4642
:type 'boolean
@@ -116,55 +112,6 @@ if the candidate is not namespace-qualified."
116112
:group 'cider
117113
:package-version '(cider . "0.9.0"))
118114

119-
(defvar cider-completion-last-context nil)
120-
121-
(defun cider-completion-symbol-start-pos ()
122-
"Find the starting position of the symbol at point, unless inside a string."
123-
(let ((sap (symbol-at-point)))
124-
(when (and sap (not (nth 3 (syntax-ppss))))
125-
(car (bounds-of-thing-at-point 'symbol)))))
126-
127-
(defun cider-completion-get-context-at-point ()
128-
"Extract the context at point.
129-
If point is not inside the list, returns nil; otherwise return \"top-level\"
130-
form, with symbol at point replaced by __prefix__."
131-
(when (save-excursion
132-
(condition-case _
133-
(progn
134-
(up-list)
135-
(check-parens)
136-
t)
137-
(scan-error nil)
138-
(user-error nil)))
139-
(save-excursion
140-
(let* ((pref-end (point))
141-
(pref-start (cider-completion-symbol-start-pos))
142-
(context (cider-defun-at-point))
143-
(_ (beginning-of-defun-raw))
144-
(expr-start (point)))
145-
(concat (when pref-start (substring context 0 (- pref-start expr-start)))
146-
"__prefix__"
147-
(substring context (- pref-end expr-start)))))))
148-
149-
(defun cider-completion-get-context ()
150-
"Extract context depending on `cider-completion-use-context' and major mode."
151-
(let ((context (if (and cider-completion-use-context
152-
;; Important because `beginning-of-defun' and
153-
;; `ending-of-defun' work incorrectly in the REPL
154-
;; buffer, so context extraction fails there.
155-
(derived-mode-p 'clojure-mode))
156-
;; We use ignore-errors here since grabbing the context
157-
;; might fail because of unbalanced parens, or other
158-
;; technical reasons, yet we don't want to lose all
159-
;; completions and throw error to user because of that.
160-
(or (ignore-errors (cider-completion-get-context-at-point))
161-
"nil")
162-
"nil")))
163-
(if (string= cider-completion-last-context context)
164-
":same"
165-
(setq cider-completion-last-context context)
166-
context)))
167-
168115
(defun cider-completion--parse-candidate-map (candidate-map)
169116
"Get \"candidate\" from CANDIDATE-MAP.
170117
Put type and ns properties on the candidate"
@@ -253,7 +200,7 @@ performed by `cider-annotate-completion-function'."
253200
(cider-complete prefix) prefix pred)))))
254201
:annotation-function #'cider-annotate-symbol
255202
:company-kind #'cider-company-symbol-kind
256-
:company-doc-buffer #'cider-create-doc-buffer
203+
:company-doc-buffer #'cider-create-compact-doc-buffer
257204
:company-location #'cider-company-location
258205
:company-docsig #'cider-company-docsig))))
259206

@@ -281,11 +228,10 @@ in the buffer."
281228

282229
(defun cider-company-docsig (thing)
283230
"Return signature for THING."
284-
(let* ((eldoc-info (cider-eldoc-info thing))
285-
(ns (lax-plist-get eldoc-info "ns"))
286-
(symbol (lax-plist-get eldoc-info "symbol"))
287-
(arglists (lax-plist-get eldoc-info "arglists")))
288-
(when eldoc-info
231+
(when-let ((eldoc-info (cider-eldoc-info thing)))
232+
(let* ((ns (lax-plist-get eldoc-info "ns"))
233+
(symbol (lax-plist-get eldoc-info "symbol"))
234+
(arglists (lax-plist-get eldoc-info "arglists")))
289235
(format "%s: %s"
290236
(cider-eldoc-format-thing ns symbol thing
291237
(cider-eldoc-thing-type eldoc-info))

0 commit comments

Comments
 (0)