diff options
author | Artur Malabarba <bruce.connor.am@gmail.com> | 2015-09-02 16:04:31 +0100 |
---|---|---|
committer | Artur Malabarba <bruce.connor.am@gmail.com> | 2015-09-09 23:05:46 +0100 |
commit | 33c026ce87d5d28e1efb20aa6514d86d354b8433 (patch) | |
tree | 3b47910371461219a615649db527335c450b3cbd /cider-resolve.el | |
parent | 7c186a0f11394ef459a524bf16b0dc62fcc9ef36 (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.el | 96 |
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 |