diff options
-rw-r--r-- | cider-browse-ns.el | 45 | ||||
-rw-r--r-- | cider-client.el | 21 | ||||
-rw-r--r-- | cider-debug.el | 12 | ||||
-rw-r--r-- | test/cider-browse-ns-tests.el | 37 | ||||
-rw-r--r-- | test/cider-client-tests.el | 19 |
5 files changed, 78 insertions, 56 deletions
diff --git a/cider-browse-ns.el b/cider-browse-ns.el index b734f8c1..06179d0c 100644 --- a/cider-browse-ns.el +++ b/cider-browse-ns.el @@ -74,25 +74,25 @@ (setq-local truncate-lines t) (setq-local cider-browse-ns-current-ns nil)) -(defun cider-browse-ns--text-face (namespace text) - "Return font-lock-face for TEXT. -The var info is fetched from the running repl and a font-lock face is decided. +(defun cider-browse-ns--text-face (var-meta) + "Return font-lock-face for a var. +VAR-META contains the metadata information used to decide a face. Presence of \"arglists-str\" and \"macro\" indicates a macro form. Only \"arglists-str\" indicates a function. Otherwise, its a variable. If the NAMESPACE is not loaded in the REPL, assume TEXT is a fn." - (let ((var-info (cider-resolve-var namespace text))) - (cond - ((not var-info) 'font-lock-function-name-face) - ((and (nrepl-dict-contains var-info "arglists") - (string= (nrepl-dict-get var-info "macro") "true")) - 'font-lock-keyword-face) - ((nrepl-dict-contains var-info "arglists") 'font-lock-function-name-face) - (t 'font-lock-variable-name-face)))) - -(defun cider-browse-ns--properties (namespace text) - "Decorate TEXT with a clickable keymap and a face." - (let ((face (cider-browse-ns--text-face namespace text))) - (propertize (or text namespace) + (cond + ((not var-meta) 'font-lock-function-name-face) + ((and (nrepl-dict-contains var-meta "arglists") + (string= (nrepl-dict-get var-meta "macro") "true")) + 'font-lock-keyword-face) + ((nrepl-dict-contains var-meta "arglists") 'font-lock-function-name-face) + (t 'font-lock-variable-name-face))) + +(defun cider-browse-ns--properties (var var-meta) + "Decorate VAR with a clickable keymap and a face. +VAR-META is used to decide a font-lock face." + (let ((face (cider-browse-ns--text-face var-meta))) + (propertize var 'font-lock-face face 'mouse-face 'highlight 'keymap cider-browse-ns-mouse-map))) @@ -121,14 +121,11 @@ contents of the buffer are not reset before inserting TITLE and ITEMS." "List all NAMESPACE's vars in BUFFER." (interactive (list (completing-read "Browse namespace: " (cider-sync-request:ns-list)))) (with-current-buffer (cider-popup-buffer cider-browse-ns-buffer t) - (let ((vars (cider-sync-request:ns-vars namespace))) - (cider-browse-ns--list (current-buffer) - namespace - (mapcar (lambda (var) - (format "%s" - (cider-browse-ns--properties namespace var))) - vars)) - (setq-local cider-browse-ns-current-ns namespace)))) + (cider-browse-ns--list (current-buffer) + namespace + (nrepl-dict-map #'cider-browse-ns--properties + (cider-ns-vars-with-meta namespace))) + (setq-local cider-browse-ns-current-ns namespace))) ;;;###autoload (defun cider-browse-ns-all () diff --git a/cider-client.el b/cider-client.el index 46a7deae..55e83312 100644 --- a/cider-client.el +++ b/cider-client.el @@ -892,6 +892,14 @@ CONTEXT represents a completion context for compliment." (cider-nrepl-send-sync-request) (nrepl-dict-get "ns-vars"))) +(defun cider-sync-request:ns-vars-with-meta (ns) + "Get a map of the vars in NS to its metadata information." + (thread-first (list "op" "ns-vars-with-meta" + "session" (cider-current-session) + "ns" ns) + (cider-nrepl-send-sync-request) + (nrepl-dict-get "ns-vars-with-meta"))) + (defun cider-sync-request:ns-load-all () "Load all project namespaces." (thread-first (list "op" "ns-load-all" @@ -937,6 +945,19 @@ CONTEXT represents a completion context for compliment." (nrepl-dict-get response "formatted-edn"))) +;;; Cache helpers + +(declare-function cider-resolve-ns-symbols "cider-resolve") + +(defun cider-ns-vars-with-meta (ns) + "Return a map of the vars in NS to its metadata information. +Get the data from `cider-repl-ns-cache' if available. +Otherwise, perform a middleware call to get the data." + (if-let ((ns-symbols (cider-resolve-ns-symbols ns))) + (apply #'nrepl-dict ns-symbols) + (cider-sync-request:ns-vars-with-meta ns))) + + ;;; Connection info (defun cider--java-version () "Retrieve the underlying connection's Java version." diff --git a/cider-debug.el b/cider-debug.el index 860802fb..dda27351 100644 --- a/cider-debug.el +++ b/cider-debug.el @@ -126,10 +126,16 @@ This variable must be set before starting the repl connection." (let ((inhibit-read-only t)) (erase-buffer) (dolist (list all) - (let ((ns (car list))) + (let* ((ns (car list)) + (ns-vars-with-meta (cider-ns-vars-with-meta ns)) + ;; seq of metadata maps of the instrumented vars + (instrumented-meta (mapcar (apply-partially #'nrepl-dict-get ns-vars-with-meta) + (cdr list)))) (cider-browse-ns--list (current-buffer) ns - (mapcar (apply-partially #'cider-browse-ns--properties ns) - (cdr list)) + (seq-mapn #'cider-browse-ns--properties + (cdr list) + instrumented-meta) + ns 'noerase) (goto-char (point-max)) (insert "\n")))) diff --git a/test/cider-browse-ns-tests.el b/test/cider-browse-ns-tests.el index ce520b22..0e6d9587 100644 --- a/test/cider-browse-ns-tests.el +++ b/test/cider-browse-ns-tests.el @@ -2,38 +2,23 @@ (require 'cider-browse-ns) (describe "cider-browse-ns--text-face" - :var (cider-resolve-var) - (describe "when the namespace is not loaded in the REPL" - (spy-on 'cider-resolve-var :and-return-value nil) - (it "returns font-lock-function-name-face" - (expect (cider-browse-ns--text-face "clojure.string" "blank?") - :to-equal 'font-lock-function-name-face))) + (it "identifies a function" + (expect (cider-browse-ns--text-face '(dict "arglists" "fn arg list")) + :to-equal 'font-lock-function-name-face)) - (describe "when the namespace is loaded in the REPL" - (it "identifies a function" - (spy-on 'cider-resolve-var :and-return-value - '(dict "arglists" "fn arg list")) - (expect (cider-browse-ns--text-face "clojure.core" "reduce") - :to-equal 'font-lock-function-name-face)) + (it "identifies a macro" + (expect (cider-browse-ns--text-face '(dict "arglists" "fn arg list" "macro" "true")) + :to-equal 'font-lock-keyword-face)) - (it "identifies a macro" - (spy-on 'cider-resolve-var :and-return-value - '(dict "arglists" "fn arg list" "macro" "true")) - (expect (cider-browse-ns--text-face "clojure.core" "defn") - :to-equal 'font-lock-keyword-face)) - - (it "identifies a variable" - (spy-on 'cider-resolve-var :and-return-value - '(dict)) - (expect (cider-browse-ns--text-face "clojure.core" "*clojure-version*") - :to-equal 'font-lock-variable-name-face)))) + (it "identifies a variable" + (expect (cider-browse-ns--text-face '(dict)) + :to-equal 'font-lock-variable-name-face))) (describe "cider-browse-ns" :var (cider-browse-ns-buffer) (it "lists out all forms of a namespace with correct font-locks" - (spy-on 'cider-sync-request:ns-vars :and-return-value - '("blank?")) - (spy-on 'cider-resolve-var :and-return-value '(dict "arglists" "fn arg list")) + (spy-on 'cider-ns-vars-with-meta :and-return-value + '(dict "blank?" (dict "arglists" "fn arg list"))) (with-temp-buffer (setq cider-browse-ns-buffer (buffer-name (current-buffer))) diff --git a/test/cider-client-tests.el b/test/cider-client-tests.el index c3a48bc4..f3e8b2c4 100644 --- a/test/cider-client-tests.el +++ b/test/cider-client-tests.el @@ -19,7 +19,6 @@ SYMBOL is locally let-bound to the current buffer." (,symbol (current-buffer))) ,@body))) - (describe "cider-current-connection" (describe "when there are no active connections" @@ -30,7 +29,6 @@ SYMBOL is locally let-bound to the current buffer." (expect (cider-current-connection "clj") :not :to-be-truthy) (expect (cider-current-connection "cljs") :not :to-be-truthy))) - (describe "when active connections are available" (it "always returns the latest connection" @@ -106,7 +104,6 @@ SYMBOL is locally let-bound to the current buffer." (setq major-mode 'clojure-mode) (expect (cider-current-connection) :to-equal b2)))))))) - (describe "cider-other-connection" (describe "when there are no active connections" :var (cider-connections) @@ -162,3 +159,19 @@ SYMBOL is locally let-bound to the current buffer." ;; older connections still work (expect (cider-other-connection bb1) :to-equal b2) (expect (cider-other-connection bb2) :to-equal b1))))))))) + +(describe "cider-ns-vars-with-meta" + (describe "when the data is available in the cache" + (it "returns the map of the vars in ns to their metadata" + (spy-on 'cider-resolve-ns-symbols :and-return-value + '("fn1" (dict "arglists" "([x])"))) + (expect (cider-ns-vars-with-meta "blah") + :to-equal '(dict "fn1" (dict "arglists" "([x])"))))) + + (describe "when the data is not available in the cache" + (it "returns data by calling `ns-vars-with-meta` op on the nREPL middleware" + (spy-on 'cider-resolve-ns-symbols :and-return-value nil) + (spy-on 'cider-sync-request:ns-vars-with-meta :and-return-value + '(dict "fn2" (dict "arglists" "([x y])"))) + (expect (cider-ns-vars-with-meta "blah") + :to-equal '(dict "fn2" (dict "arglists" "([x y])")))))) |