summaryrefslogtreecommitdiff
path: root/cider-resolve.el
diff options
context:
space:
mode:
authorArtur Malabarba <bruce.connor.am@gmail.com>2015-09-02 16:04:31 +0100
committerArtur Malabarba <bruce.connor.am@gmail.com>2015-09-09 23:05:46 +0100
commit33c026ce87d5d28e1efb20aa6514d86d354b8433 (patch)
tree3b47910371461219a615649db527335c450b3cbd /cider-resolve.el
parent7c186a0f11394ef459a524bf16b0dc62fcc9ef36 (diff)
Implement dynamic font-locking
Ditch instrumented defs overlay for the new font-locking. All macros are now font-locked. This is configurable via the cider-font-lock-dynamically variable.
Diffstat (limited to 'cider-resolve.el')
-rw-r--r--cider-resolve.el96
1 files changed, 77 insertions, 19 deletions
diff --git a/cider-resolve.el b/cider-resolve.el
index 84542853..fdcb67d5 100644
--- a/cider-resolve.el
+++ b/cider-resolve.el
@@ -19,19 +19,61 @@
;;; Commentary:
+;; The ns cache is a dict of namespaces stored in the connection buffer. This
+;; file offers functions to easily get information about variables from this
+;; cache, given the variable's name and the file's namespace. This
+;; functionality is similar to that offered by the `cider-var-info' function
+;; (and others). The difference is that all functions in this file operate
+;; without contacting the server (they still rely on an active connection
+;; buffer, but no messages are actually exchanged).
+
+;; For this reason, the functions here are well suited for very
+;; performance-sentitive operations, such as font-locking or
+;; indentation. Meanwhile, operations like code-jumping are better off
+;; communicating with the middleware, just in the off chance that the cache is
+;; outdated.
+
+;; Below is a typical entry on this cache dict. Note that clojure.core symbols
+;; are excluded from the refers to save space.
+
+;; "cider.nrepl.middleware.track-state"
+;; (dict "aliases"
+;; (dict "cljs" "cider.nrepl.middleware.util.cljs"
+;; "misc" "cider.nrepl.middleware.util.misc"
+;; "set" "clojure.set")
+;; "interns" (dict a
+;; "assoc-state" (dict "arglists"
+;; (("response"
+;; (dict "as" "msg" "keys"
+;; ("session")))))
+;; "filter-core" (dict "arglists"
+;; (("refers")))
+;; "make-transport" (dict "arglists"
+;; (((dict "as" "msg" "keys"
+;; ("transport")))))
+;; "ns-as-map" (dict "arglists"
+;; (("ns")))
+;; "ns-cache" (dict)
+;; "relevant-meta" (dict "arglists"
+;; (("var")))
+;; "update-vals" (dict "arglists"
+;; (("m" "f")))
+;; "wrap-tracker" (dict "arglists"
+;; (("handler"))))
+;; "refers" (dict "set-descriptor!" "#'clojure.tools.nrepl.middleware/set-descriptor!"))
+
;;; Code:
(require 'nrepl-client)
(require 'cider-interaction)
-(require 'cider-repl)
+
+(defvar cider-repl-ns-cache)
(defun cider-resolve--get-in (&rest keys)
- "Return (nrepl-dict-get-in cider-repl-ns-cache keys)."
+ "Return (nrepl-dict-get-in cider-repl-ns-cache KEYS)."
(when cider-connections
- (nrepl-dict-get-in
- (with-current-buffer (cider-current-connection)
- cider-repl-ns-cache)
- keys)))
+ (with-current-buffer (cider-current-connection)
+ (nrepl-dict-get-in cider-repl-ns-cache keys))))
(defun cider-resolve-alias (ns alias)
"Return the namespace that ALIAS refers to in namespace NS.
@@ -39,14 +81,15 @@ If it doesn't point anywhere, returns ALIAS."
(or (cider-resolve--get-in ns "aliases" alias)
alias))
+(defconst cider-resolve--prefix-regexp "\\`\\(?:#'\\)?\\([^/]+\\)/")
+
(defun cider-resolve-var (ns var)
"Return a dict of the metadata of a clojure var VAR in namespace NS.
VAR is a string.
Return nil only if VAR cannot be resolved."
- (let* ((prefix-regexp "\\`\\([^/]+\\)/")
- (var-ns (when (string-match prefix-regexp var)
+ (let* ((var-ns (when (string-match cider-resolve--prefix-regexp var)
(cider-resolve-alias ns (match-string 1 var))))
- (name (replace-regexp-in-string prefix-regexp "" var)))
+ (name (replace-regexp-in-string cider-resolve--prefix-regexp "" var)))
(or
(cider-resolve--get-in (or var-ns ns) "interns" name)
(unless var-ns
@@ -57,16 +100,31 @@ Return nil only if VAR cannot be resolved."
(unless (equal ns "clojure.core")
(cider-resolve-var "clojure.core" name)))))))
-(defun cider-match-instrumented-symbol (n face)
- "Return a face specification for font-locking.
-If (match-string N) is an instrumented symbol, return
- (face cider-instrumented-face FACE)
-otherwise, return (face FACE)."
- (cons 'face
- (if (nrepl-dict-get (cider-resolve-var (cider-current-ns) (match-string n))
- "cider-instrumented")
- `((cider-instrumented-face ,face))
- (list face))))
+(defun cider-resolve-core-ns ()
+ "Return a dict of the core namespace for current connection.
+This will be clojure.core or cljs.core depending on `cider-repl-type'."
+ (when (cider-connected-p)
+ (with-current-buffer (cider-current-connection)
+ (cider-resolve--get-in (if (equal cider-repl-type "cljs")
+ "cljs.core"
+ "clojure.core")))))
+
+(defun cider-resolve-ns-symbols (ns)
+ "Return a dict of all valid symbols in NS.
+Each entry's value is the metadata of the var that the symbol refers to.
+NS can be the namespace name, or a dict of the namespace itself."
+ (-when-let (dict (if (stringp ns)
+ (cider-resolve--get-in ns)
+ ns))
+ (nrepl-dbind-response dict (interns refers aliases)
+ (append interns
+ (nrepl-dict-flat-map (lambda (sym var) (list sym (cider-resolve-var ns var)))
+ refers)
+ (nrepl-dict-flat-map (lambda (alias namespace)
+ (nrepl-dict-flat-map (lambda (sym meta)
+ (list (concat alias "/" sym) meta))
+ (cider-resolve--get-in namespace "interns")))
+ aliases)))))
(provide 'cider-resolve)
;;; cider-resolve.el ends here