cider-nrepl
cider-nrepl copied to clipboard
Incomplete specification of the info and eldoc ops
https://docs.cider.mx/cider-nrepl/nrepl-api/ops.html#info
The specification for the info
op only mentions the following keys in the return message:
:doc-block-tags-fragments - may be absent
:doc-first-sentence-fragments - may be absent
:doc-fragments - may be absent
:status - `done`
In reality, the frontend (Emacs / cider-doc) relies on various other compulsory (non-nil) keys in the map, such as :name
and :ns
.
When the info
op is requested for ill-formed input (eg. a non-existent var), the cider-nrepl implementation signals this by returning :no-info
in its status:
https://github.com/clojure-emacs/cider-nrepl/blob/11ae4eec39b3cffcb70088f7f153a8b8fb147e0e/src/cider/nrepl/middleware/info.clj#L129
This is also undocumented, but relied upon by the frontend to guard against parsing of an empty (malformed) var-info response.
https://github.com/clojure-emacs/cider/blob/810337cee931d9f14aa16550a74516f8337a47f3/cider-client.el#L691
(Relevant call stack: cider-doc-lookup
-> cider-create-doc-buffer
-> cider-var-info
-> cider-sync-request:info
)
Similarly, the eldoc
op implicitly relies on a :no-eldoc
status to signal an empty return value.
The problem occurs with the babashka.nrepl
implementation of the protocol, which also claims to provide the info
and eldoc
ops, but sometimes returns an map missing many 'required' keys such as :name
, and a done
status. This results in varying degrees of breakage when CIDER is connected to a babashka
-type REPL.
Clearly this would be a simple fix on the impl to return the appropriate :no-info
/ :no-eldoc
statuses, but I thought it would be worth properly pinning down the return contracts before raising an issue there.
Otherwise given the current underspecified docs, it could technically be seen as a well-formed response that requires additional logic on the frontend(s) to guard against nil values.
Steps to reproduce (Emacs / Cider 1.15)
- Create a standalone .bb file with the contents:
;; repro.bb
(ns repro)
(defn foo
"See also: `bar`"
[])
-
cider-jack-in with the
babashka
project type (C-u 3 C-c M-j
) -
cider-load-buffer
, thencider-doc
on thefoo
symbol. -
Click the xref link for
bar
in the doc buffer (a non-existent var). -
The elisp error is thrown:
Wrong type argument: stringp, nil
(Note:cider-doc
on a non-existent symbol is wrapped in a condition-case, and falls back to a minibuffer prompt on encountering this error) -
Also observe the broken eldoc displayed in calls to non-existent vars:
(oops ) ; <- with cursor in form
Environment & Version information
NA