From be11c1b34ab8b4b6138440aba5a013e54a8441f9 Mon Sep 17 00:00:00 2001 From: Zachary Romero Date: Wed, 22 Jun 2022 07:36:04 -0700 Subject: [PATCH] [Fix #3200] Add private var listing below public vars Adds a second "ns-vars-with-meta" nrepl call to fetch the private variables. Adds a new param to `cider-browse-ns--list` to be able to provide a list of the private items and have this function format accordingly. --- CHANGELOG.md | 1 + cider-browse-ns.el | 33 +++++++++++++++++++++++++++------ cider-client.el | 9 +++++++++ cider-debug.el | 3 +-- test/cider-browse-ns-tests.el | 26 ++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5da369b03..cc62fb9ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ## Changes * Upgrade injected `cider-nrepl` to [0.28.5](https://github.com/clojure-emacs/cider-nrepl/releases/tag/v0.28.5). +* [#3200](https://github.com/clojure-emacs/cider/issues/3200): cider-browse-ns additionally displays the list of private vars. ## 1.4.1 (2022-05-25) diff --git a/cider-browse-ns.el b/cider-browse-ns.el index 8c864cc87..44e7c97a7 100644 --- a/cider-browse-ns.el +++ b/cider-browse-ns.el @@ -44,6 +44,17 @@ (require 'easymenu) (require 'thingatpt) + +(defgroup cider-browse-ns nil + "Display contents of namespaces for CIDER." + :prefix "cider-browse-ns-" + :group 'cider) + +(defface cider-browse-ns-info-face + '((t (:inherit shadow))) + "Face for displaying headers for sections of browse-ns buffer." + :package-version '(cider . "1.4.0")) + (defconst cider-browse-ns-buffer "*cider-ns-browser*") (defvar-local cider-browse-ns-current-ns nil) @@ -106,9 +117,10 @@ VAR-META is used to decide a font-lock face." 'mouse-face 'highlight 'keymap cider-browse-ns-mouse-map))) -(defun cider-browse-ns--list (buffer title items &optional ns noerase) +(defun cider-browse-ns--list (buffer title items &optional private-items ns noerase) "Reset contents of BUFFER. -Display TITLE at the top and ITEMS are indented underneath. +Display TITLE at the top and ITEMS are indented underneath. PRIVATE-ITEMS +is displayed as a separate section under the public items. If NS is non-nil, it is added to each item as the `cider-browse-ns-current-ns' text property. If NOERASE is non-nil, the contents of the buffer are not reset before inserting TITLE and ITEMS." @@ -121,6 +133,11 @@ contents of the buffer are not reset before inserting TITLE and ITEMS." (dolist (item items) (insert (propertize (concat " " item "\n") 'cider-browse-ns-current-ns ns))) + (when private-items + (insert (propertize "\n Private:\n" 'face 'cider-browse-ns-info-face)) + (dolist (item private-items) + (insert (propertize (concat " " item "\n") + 'cider-browse-ns-current-ns ns)))) (goto-char (point-min))))) (defun cider-browse-ns--first-doc-line (doc) @@ -137,10 +154,13 @@ string is returned." (t (concat first-line "...")))) "Not documented.")) -(defun cider-browse-ns--items (namespace) +(defun cider-browse-ns--items (namespace &optional private) "Return the items to show in the namespace browser of the given NAMESPACE. -Each item consists of a ns-var and the first line of its docstring." - (let* ((ns-vars-with-meta (cider-sync-request:ns-vars-with-meta namespace)) +Each item consists of a ns-var and the first line of its docstring. If +PRIVATE is non-nil, return only the items with :private metadata." + (let* ((ns-vars-with-meta (if private + (cider-sync-request:private-ns-vars-with-meta namespace) + (cider-sync-request:ns-vars-with-meta namespace))) (propertized-ns-vars (nrepl-dict-map #'cider-browse-ns--properties ns-vars-with-meta))) (mapcar (lambda (ns-var) (let* ((doc (nrepl-dict-get-in ns-vars-with-meta (list ns-var "doc"))) @@ -160,7 +180,8 @@ Each item consists of a ns-var and the first line of its docstring." (with-current-buffer (cider-popup-buffer cider-browse-ns-buffer 'select nil 'ancillary) (cider-browse-ns--list (current-buffer) namespace - (cider-browse-ns--items namespace)) + (cider-browse-ns--items namespace) + (cider-browse-ns--items namespace t)) (setq-local cider-browse-ns-current-ns namespace))) ;;;###autoload diff --git a/cider-client.el b/cider-client.el index a8c159955..d4b883289 100644 --- a/cider-client.el +++ b/cider-client.el @@ -743,6 +743,15 @@ returned." (cider-nrepl-send-sync-request) (nrepl-dict-get "ns-vars-with-meta"))) +(defun cider-sync-request:private-ns-vars-with-meta (ns) + "Get a map of the vars in NS to its metadata information." + (thread-first `("op" "ns-vars-with-meta" + "ns" ,ns + "var-query" ,(nrepl-dict "private?" "t" + "include-meta-key" '("private"))) + (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 '("op" "ns-load-all") diff --git a/cider-debug.el b/cider-debug.el index cc6b1bc3b..73cbc2939 100644 --- a/cider-debug.el +++ b/cider-debug.el @@ -121,8 +121,7 @@ configure `cider-debug-prompt' instead." (seq-mapn #'cider-browse-ns--properties (cdr list) instrumented-meta) - - ns 'noerase) + nil ns 'noerase) (goto-char (point-max)) (insert "\n")))) (goto-char (point-min))) diff --git a/test/cider-browse-ns-tests.el b/test/cider-browse-ns-tests.el index 13775a2ab..2b9773c6d 100644 --- a/test/cider-browse-ns-tests.el +++ b/test/cider-browse-ns-tests.el @@ -50,6 +50,7 @@ '(dict "blank?" (dict "arglists" "fn arg list" "doc" "\"True if s is nil, empty, or contains only whitespace.\""))) + (spy-on 'cider-sync-request:private-ns-vars-with-meta :and-return-value '(dict)) (with-temp-buffer (setq cider-browse-ns-buffer (buffer-name (current-buffer))) @@ -59,6 +60,31 @@ (search-forward "blank") (expect (get-text-property (point) 'font-lock-face) :to-equal 'font-lock-function-name-face) (search-forward "True") + (expect (get-text-property (point) 'font-lock-face) :to-equal 'font-lock-doc-face) + (expect (not (search-forward "Private" nil t))))) + (it "correctly displays private vars below regular vars" + (spy-on 'cider-sync-request:ns-vars-with-meta :and-return-value + '(dict "blank?" + (dict "arglists" "fn arg list" + "doc" "\"True if s is nil, empty, or contains only whitespace.\""))) + (spy-on 'cider-sync-request:private-ns-vars-with-meta :and-return-value + '(dict "secret-blank?" + (dict "arglists" "fn arg list" + "doc" "\"False if s is nil, empty, or contains only whitespace.\""))) + + (with-temp-buffer + (setq cider-browse-ns-buffer (buffer-name (current-buffer))) + (cider-browse-ns "clojure.string") + (search-forward "clojure") + (expect (get-text-property (point) 'face) :to-equal 'font-lock-type-face) + (search-forward "blank") + (expect (get-text-property (point) 'font-lock-face) :to-equal 'font-lock-function-name-face) + (search-forward "True") + (expect (get-text-property (point) 'font-lock-face) :to-equal 'font-lock-doc-face) + (search-forward "Private") + (search-forward "secret-blank") + (expect (get-text-property (point) 'font-lock-face) :to-equal 'font-lock-function-name-face) + (search-forward "False") (expect (get-text-property (point) 'font-lock-face) :to-equal 'font-lock-doc-face)))) (describe "cider-browse-ns--first-doc-line"