Skip to content

Commit

Permalink
[Fix #1832] Add eldoc info for datomic query input parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
mallt authored and bbatsov committed Mar 22, 2017
1 parent d528100 commit 0816372
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* [#1731](https://github.com/clojure-emacs/cider/issues/1731): Change code in order to use the new `cider.tasks/add-middleware` boot tasks.
* [#1943](https://github.com/clojure-emacs/cider/pull/1943): Add interactive function to flush Compliment caches.
* [#1726](https://github.com/clojure-emacs/cider/issues/1726): Order keys in printed nrepl message objects.
* [#1832](https://github.com/clojure-emacs/cider/issues/1832): Add new customization variable `cider-eldoc-display-context-dependent-info` to control showing eldoc info for datomic query input parameters.

### Changes

Expand Down
10 changes: 10 additions & 0 deletions cider-client.el
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,16 @@ CONTEXT represents a completion context for compliment."
nil
eldoc)))

(defun cider-sync-request:eldoc-datomic-query (symbol)
"Send \"eldoc-datomic-query\" op with parameter SYMBOL."
(when-let ((eldoc (thread-first `("op" "eldoc-datomic-query"
"ns" ,(cider-current-ns)
,@(when symbol `("symbol" ,symbol)))
(cider-nrepl-send-sync-request nil 'abort-on-input))))
(if (member "no-eldoc" (nrepl-dict-get eldoc "status"))
nil
eldoc)))

(defun cider-sync-request:ns-list ()
"Get a list of the available namespaces."
(thread-first `("op" "ns-list"
Expand Down
48 changes: 44 additions & 4 deletions cider-eldoc.el
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ displayed. When nil, always display eldoc for first symbol of the sexp."
:group 'cider
:package-version '(cider . "0.13.0"))

(defcustom cider-eldoc-display-context-dependent-info nil
"When non-nil, display context dependent info in the eldoc where possible.
CIDER will try to add expected function arguments based on the current context,
for example for the datomic.api/q function where it will show the expected
inputs of the query at point."
:type 'boolean
:group 'cider
:package-version '(cider . "0.15.0"))

(defun cider--eldoc-format-class-names (class-names)
"Return a formatted CLASS-NAMES prefix string.
CLASS-NAMES is a list of classes to which a Java interop form belongs.
Expand Down Expand Up @@ -398,10 +407,23 @@ This includes the arglist and ns and symbol name (if available)."
"arglists" arglists
"docstring" docstring
"type" type)))
;; middleware eldoc lookups are expensive, so we
;; cache the last lookup. This eliminates the need
;; for extra middleware requests within the same sexp.
(setq cider-eldoc-last-symbol (list thing eldoc-plist))
;; add context dependent args if requested by defcustom
;; do not cache this eldoc info to avoid showing info
;: of the previous context
(if cider-eldoc-display-context-dependent-info
(cond
;; add inputs of datomic query
((and (equal ns-or-class "datomic.api")
(equal name-or-member "q"))
(let ((arglists (lax-plist-get eldoc-plist "arglists")))
(lax-plist-put eldoc-plist "arglists"
(cider--eldoc-add-datomic-query-inputs-to-arglists arglists))))
;; if none of the clauses is successful, do cache the eldoc
(t (setq cider-eldoc-last-symbol (list thing eldoc-plist))))
;; middleware eldoc lookups are expensive, so we
;; cache the last lookup. This eliminates the need
;; for extra middleware requests within the same sexp.
(setq cider-eldoc-last-symbol (list thing eldoc-plist)))
eldoc-plist))))))))

(defun cider--eldoc-remove-dot (sym)
Expand All @@ -413,6 +435,24 @@ Only useful for interop forms. Clojure forms would be returned unchanged."
"Check whether FILE-NAME is representing an EDN file."
(and file-name (equal (file-name-extension file-name) "edn")))

(defun cider--eldoc-add-datomic-query-inputs-to-arglists (arglists)
"Add the expected inputs of the datomic query to the ARGLISTS."
(if (cider-second-sexp-in-list)
(let* ((query (cider-second-sexp-in-list))
(query-inputs (nrepl-dict-get
(cider-sync-request:eldoc-datomic-query query)
"inputs")))
(if query-inputs
(thread-first
(thread-last arglists
(car)
(remove "&")
(remove "inputs"))
(append (car query-inputs))
(list))
arglists))
arglists))

(defun cider-eldoc ()
"Backend function for eldoc to show argument list in the echo area."
(when (and (cider-connected-p)
Expand Down
9 changes: 9 additions & 0 deletions cider-util.el
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,15 @@ Can only error if SKIP is non-nil."
(forward-sexp 1)
(cider-start-of-next-sexp))))

(defun cider-second-sexp-in-list ()
"Return the second sexp in the list at point."
(condition-case nil
(save-excursion
(backward-up-list)
(forward-char)
(forward-sexp 2)
(cider-sexp-at-point))
(error nil)))

;;; Text properties

Expand Down
9 changes: 9 additions & 0 deletions doc/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,15 @@ its behaviour.
| `nil` | Messages are always truncated to fit in a single line of display in the echo area. |
| `truncate-sym-name-if-fit` or anything non-nil | Symbol name may be truncated if it will enable the function arglist or documentation string to fit on a single line. Otherwise, behavior is just like `t` case. |

* CIDER will try to add expected function arguments based on the current context
(for example for the `datomic.api/q` function where it will show the expected
inputs of the query at point), if the variable `cider-eldoc-display-context-dependent-info`
is non-nil:

```el
(setq cider-eldoc-display-context-dependent-info t)
```

## Overlays

When you evaluate code in Clojure files, the result is displayed in the buffer
Expand Down
8 changes: 8 additions & 0 deletions test/cider-eldoc-tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -300,3 +300,11 @@
(it "returns tries to display the var with the first line"
(expect (cider-eldoc-format-sym-doc "kubaru.core/plane" "kubaru.core" "Line 1.\nLine 2.\nLine 3.")
:to-equal "kubaru.core/plane: Line 1."))))))

(describe "cider--eldoc-add-datomic-query-inputs-to-arglists"
(it "adds the datomic query inputs of the query at point to the arglist"
(spy-on 'cider-second-sexp-in-list :and-return-value t)
(spy-on 'cider-sync-request:eldoc-datomic-query
:and-return-value '(dict "inputs" (("$" "?first-name"))))
(expect (cider--eldoc-add-datomic-query-inputs-to-arglists '(("query" "&" "inputs")))
:to-equal '(("query" "$" "?first-name")))))
8 changes: 8 additions & 0 deletions test/cider-util-tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,11 @@
(it "returns the refcard correct url for snapshot cider versions"
(setq cider-version "0.11.0-snapshot")
(expect (cider-refcard-url) :to-equal "https://github.com/clojure-emacs/cider/raw/master/doc/cider-refcard.pdf")))

(describe "cider-second-sexp-in-list"
(it "returns the second sexp in the list"
(with-temp-buffer
(clojure-mode)
(insert "(test-function arg1 arg2 arg3)")
(backward-char 2)
(expect (cider-second-sexp-in-list) :to-equal "arg1"))))

0 comments on commit 0816372

Please sign in to comment.