Skip to content

Commit c4e55e2

Browse files
committed
New feature: Enlighten
Handle :enlighten messages through the debug channel. Define cider-enlighten-mode. Font-lock enlightened defns. Document Enlighten.
1 parent 55aba3d commit c4e55e2

File tree

7 files changed

+93
-6
lines changed

7 files changed

+93
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### New features
66

7+
* [#1545](https://github.com/clojure-emacs/cider/pull/1545): New feature: Enlighten. See the new Readme section for more information.
78
* [#1169](https://github.com/clojure-emacs/cider/pull/1169): New command `cider-eval-defun-to-comment`.
89
* Change default value of `cider-overlays-use-font-lock` to `t`. Unlike before, a value of `t`, causes `cider-result-overlay-face` is to be prepended to the font-lock faces (instead of just not being used).
910
* `cider-result-overlay-face` default value changed to a background and a box, so it can be prepended to other faces without overriding the foreground.

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ specific CIDER release.**
5555
- [Value Inspection](#value-inspection)
5656
- [Running Tests](#running-tests)
5757
- [Navigating Stacktraces](#navigating-stacktraces)
58+
- [Enlighten (display local values)](#enlighten-display-local-values)
5859
- [Debugging](#debugging)
5960
- [Code reloading](#code-reloading)
6061
- [Managing multiple connections](#managing-multiple-connections)
@@ -808,6 +809,26 @@ will be used.
808809
(setq cider-stacktrace-fill-column 80)
809810
```
810811

812+
### Enlighten (display local values)
813+
814+
This feature displays the value of locals in realtime, as your code is being
815+
executed. This is somewhat akin to one of the features of the Light Table
816+
editor.
817+
818+
- To turn it on, issue `M-x cider-enlighten-mode`.
819+
- To use it, evaluate your functions one at a time (e.g., use `C-M-x` or `C-x C-e`, because `C-c C-k` won't work).
820+
821+
That's it! Once your code executes, the regular old buffer on the left will turn
822+
into the brilliant show of lights on the right.
823+
824+
<p align="center">
825+
<img src="doc/images/enlighten-off.png" />
826+
<img src="doc/images/enlighten-on.png" />
827+
</p>
828+
829+
You can also trigger this on specific functions (without having to turn on the
830+
minor mode) by writing `#light` before the `(def` and reevaluating it.
831+
811832
### Debugging
812833

813834
The debugger can be invoked in several ways, the simplest one is to type

cider-debug.el

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,23 @@
6363
:group 'cider-debug
6464
:package-version '(cider . "0.10.0"))
6565

66+
(defface cider-enlightened
67+
'((((class color) (background light)) :inherit cider-result-overlay-face
68+
:box (:color "darkorange" :line-width -1))
69+
(((class color) (background dark)) :inherit cider-result-overlay-face
70+
;; "#dd0" is a dimmer yellow.
71+
:box (:color "#dd0" :line-width -1)))
72+
"Face used to mark enlightened sexps and their return values."
73+
:group 'cider-debug
74+
:package-version '(cider . "0.11.0"))
75+
76+
(defface cider-enlightened-local
77+
'((((class color) (background light)) :weight bold :foreground "darkorange")
78+
(((class color) (background dark)) :weight bold :foreground "yellow"))
79+
"Face used to mark enlightened locals (not their values)."
80+
:group 'cider-debug
81+
:package-version '(cider . "0.11.0"))
82+
6683
(defcustom cider-debug-prompt 'overlay
6784
"If and where to show the keys while debugging.
6885
If `minibuffer', show it in the minibuffer along with the return value.
@@ -127,6 +144,8 @@ This variable must be set before starting the repl connection."
127144
(defun cider--debug-response-handler (response)
128145
"Handle responses from the cider.debug middleware."
129146
(nrepl-dbind-response response (status id causes)
147+
(when (member "enlighten" status)
148+
(cider--handle-enlighten response))
130149
(when (or (member "eval-error" status)
131150
(member "stack" status))
132151
;; TODO: Make the error buffer a bit friendlier when we're just printing
@@ -585,6 +604,36 @@ needed. It is expected to contain at least \"key\", \"input-type\", and
585604
(error (cider-debug-mode-send-reply ":quit" key)
586605
(message "Error encountered while handling the debug message: %S" e)))))
587606

607+
(defun cider--handle-enlighten (response)
608+
"Handle an enlighten notification.
609+
RESPONSE is a message received from the nrepl describing the value and
610+
coordinates of a sexp. Create an overlay after the specified sexp
611+
displaying its value."
612+
(when-let ((marker (cider--debug-find-source-position response)))
613+
(with-current-buffer (marker-buffer marker)
614+
(save-excursion
615+
(goto-char marker)
616+
(clojure-backward-logical-sexp 1)
617+
(nrepl-dbind-response response (debug-value erase-previous)
618+
(when erase-previous
619+
(remove-overlays (point) marker 'cider-type 'enlighten))
620+
(when debug-value
621+
(if (memq (char-before marker) '(?\) ?\] ?}))
622+
;; Enlightening a sexp looks like a regular return value, except
623+
;; for a different border.
624+
(cider--make-result-overlay (cider-font-lock-as-clojure debug-value)
625+
:where (cons marker marker)
626+
:type 'enlighten
627+
:prepend-face 'cider-enlightened)
628+
;; Enlightening a symbol uses a more abbreviated format. The
629+
;; result face is the same as a regular result, but we also color
630+
;; the symbol with `cider-enlightened-local'.
631+
(cider--make-result-overlay (cider-font-lock-as-clojure debug-value)
632+
:format "%s"
633+
:where (cons (point) marker)
634+
:type 'enlighten
635+
'face 'cider-enlightened-local))))))))
636+
588637

589638
;;; Move here command
590639
;; This is the inverse of `cider--debug-move-point'. However, that algorithm is

cider-mode.el

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -360,14 +360,18 @@ The value can also be t, which means to font-lock as much as possible."
360360
(let ((cider-font-lock-dynamically (if (eq cider-font-lock-dynamically t)
361361
'(function var macro core deprecated)
362362
cider-font-lock-dynamically))
363-
deprecated
363+
deprecated enlightened
364364
macros functions vars instrumented traced)
365365
(when (memq 'core cider-font-lock-dynamically)
366366
(while core-plist
367367
(let ((sym (pop core-plist))
368368
(meta (pop core-plist)))
369-
(when (nrepl-dict-get meta "cider.nrepl.middleware.util.instrument/breakfunction")
370-
(push sym instrumented))
369+
(pcase (nrepl-dict-get meta "cider.nrepl.middleware.util.instrument/breakfunction")
370+
(`nil nil)
371+
(`"#'cider.nrepl.middleware.debug/breakpoint-if-interesting"
372+
(push sym instrumented))
373+
(`"#'cider.nrepl.middleware.enlighten/light-form"
374+
(push sym enlightened)))
371375
(when (or (nrepl-dict-get meta "clojure.tools.trace/traced")
372376
(nrepl-dict-get meta "cider.inlined-deps.clojure.tools.trace/traced"))
373377
(push sym traced))
@@ -383,8 +387,12 @@ The value can also be t, which means to font-lock as much as possible."
383387
(while symbols-plist
384388
(let ((sym (pop symbols-plist))
385389
(meta (pop symbols-plist)))
386-
(when (nrepl-dict-get meta "cider.nrepl.middleware.util.instrument/breakfunction")
387-
(push sym instrumented))
390+
(pcase (nrepl-dict-get meta "cider.nrepl.middleware.util.instrument/breakfunction")
391+
(`nil nil)
392+
(`"#'cider.nrepl.middleware.debug/breakpoint-if-interesting"
393+
(push sym instrumented))
394+
(`"#'cider.nrepl.middleware.enlighten/light-form"
395+
(push sym enlightened)))
388396
(when (or (nrepl-dict-get meta "clojure.tools.trace/traced")
389397
(nrepl-dict-get meta "cider.inlined-deps.clojure.tools.trace/traced"))
390398
(push sym traced))
@@ -414,6 +422,9 @@ The value can also be t, which means to font-lock as much as possible."
414422
,@(when deprecated
415423
`((,(regexp-opt deprecated 'symbols) 0
416424
(cider--unless-local-match cider-deprecated-properties) append)))
425+
,@(when enlightened
426+
`((,(regexp-opt enlightened 'symbols) 0
427+
(cider--unless-local-match 'cider-enlightened) append)))
417428
,@(when instrumented
418429
`((,(regexp-opt instrumented 'symbols) 0
419430
(cider--unless-local-match 'cider-instrumented-face) append)))
@@ -423,7 +434,7 @@ The value can also be t, which means to font-lock as much as possible."
423434

424435
(defconst cider--static-font-lock-keywords
425436
(eval-when-compile
426-
`((,(regexp-opt '("#break" "#dbg") 'symbols) 0 font-lock-warning-face)))
437+
`((,(regexp-opt '("#break" "#dbg" "#light") 'symbols) 0 font-lock-warning-face)))
427438
"Default expressions to highlight in CIDER mode.")
428439

429440
(defvar-local cider--dynamic-font-lock-keywords nil)

doc/images/enlighten-off.png

7.97 KB
Loading

doc/images/enlighten-on.png

10.7 KB
Loading

nrepl-client.el

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,9 @@ Register CALLBACK as the response handler."
999999
callback
10001000
connection))
10011001

1002+
(define-minor-mode cider-enlighten-mode nil nil (cider-mode " light")
1003+
:global t)
1004+
10021005
(defun nrepl--eval-request (input session &optional ns line column)
10031006
"Prepare :eval request message for INPUT.
10041007
SESSION and NS provide context for the request.
@@ -1008,6 +1011,8 @@ If LINE and COLUMN are non-nil and current buffer is a file buffer, \"line\",
10081011
(list "op" "eval"
10091012
"session" session
10101013
"code" input)
1014+
(when cider-enlighten-mode
1015+
(list "enlighten" "true"))
10111016
(let ((file (or (buffer-file-name) (buffer-name))))
10121017
(when (and line column file)
10131018
(list "file" file

0 commit comments

Comments
 (0)