Skip to content

Commit 2c4ae72

Browse files
committed
Merge pull request #1155 from Malabarba/debugger-overlays
Add overlays to the debugger.
2 parents 2cce721 + b1be163 commit 2c4ae72

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## master (unreleased)
44

5+
### New features
6+
7+
* [#1155](https://github.com/clojure-emacs/cider/pull/1155): The debugger displays overlays highlighting the current sexp and its return value.
8+
59
### Bugs fixed
610

711
* [#1142](https://github.com/clojure-emacs/cider/issues/1142): Don't retrive nrepl ports when `cider-known-endpoints` entry already contains the port.

cider-debug.el

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,31 @@
2828
(require 'nrepl-client)
2929
(require 'cider-interaction)
3030

31+
(defface cider-result-overlay-face
32+
'((((class color) (background light)) :foreground "firebrick")
33+
(((class color) (background dark)) :foreground "orange red"))
34+
"Face used to display result of debug step at point."
35+
:group 'cider
36+
:package-version "0.9.1")
37+
38+
(defface cider-debug-code-overlay-face
39+
'((((class color) (background light)) :background "grey80")
40+
(((class color) (background dark)) :background "grey20"))
41+
"Face used to mark code being debugged."
42+
:group 'cider
43+
:package-version "0.9.1")
44+
45+
(defcustom cider-debug-use-overlays 'end-of-line
46+
"Whether to higlight debugging information with overlays.
47+
Only applies to \"*cider-debug ...*\" buffers, which are used in debugging
48+
sessions.
49+
Possible values are inline, end-of-line, or nil."
50+
:type '(choice (const :tag "End of line" end-of-line)
51+
(const :tag "Inline" inline)
52+
(const :tag "No overlays" nil))
53+
:group 'cider
54+
:package-version "0.9.1")
55+
3156
(defconst cider--instrument-format
3257
(concat "(cider.nrepl.middleware.debug/instrument-and-eval"
3358
;; filename and point are passed in a map. Eventually, this should be
@@ -49,6 +74,59 @@
4974
nrepl-completed-requests)
5075
(remhash id nrepl-pending-requests))))))
5176

77+
78+
;;; Overlay logic
79+
(defun cider--delete-overlay (ov &rest _)
80+
"Safely delete overlay OV.
81+
Never throws errors, and can be used in an overlay's modification-hooks."
82+
(ignore-errors (delete-overlay ov)))
83+
84+
(defun cider--make-overlay (l r type &rest props)
85+
"Place an overlay between L and R and return it.
86+
TYPE is a symbol put on the overlay's cider-type property. It is used to
87+
easily remove all overlays from a region with:
88+
(remove-overlays start end 'cider-type TYPE)
89+
PROPS is a plist of properties and values to add to the overlay."
90+
(let ((o (make-overlay l r (current-buffer))))
91+
(overlay-put o 'cider-type type)
92+
(overlay-put o 'modification-hooks (list #'cider--delete-overlay))
93+
(while props (overlay-put o (pop props) (pop props)))
94+
o))
95+
96+
(defun cider--make-result-overlay (value type &optional where)
97+
"Place an overlay displaying VALUE at the end of the line.
98+
TYPE is passed to `cider--make-overlay'.
99+
The overlay is placed from beginning to end of current line.
100+
If WHERE is the symbol inline, instead, the overlay ends at point and VALUE
101+
is displayed at point."
102+
(cider--make-overlay
103+
(line-beginning-position)
104+
(if (eq where 'inline) (point) (line-end-position))
105+
'debug-result
106+
'after-string
107+
(propertize (concat (propertize " " 'cursor 1000)
108+
cider-interactive-eval-result-prefix
109+
(format "%s" value))
110+
'face 'cider-result-overlay-face)))
111+
112+
(defun cider--debug-display-result-overlay (value)
113+
"Place an overlay at point displaying VALUE."
114+
(when cider-debug-use-overlays
115+
;; This is cosmetic, let's ensure it doesn't break the session no matter what.
116+
(ignore-errors
117+
(remove-overlays nil nil 'cider-type 'debug-result)
118+
(remove-overlays nil nil 'cider-type 'debug-code)
119+
;; Result
120+
(cider--make-result-overlay value 'debug-result cider-debug-use-overlays)
121+
;; Code
122+
(cider--make-overlay (save-excursion (forward-sexp -1) (point))
123+
(point) 'debug-code
124+
'face 'cider-debug-code-overlay-face
125+
;; Higher priority than `show-paren'.
126+
'priority 2000))))
127+
128+
129+
;;; Movement logic
52130
(defun cider--forward-sexp (n)
53131
"Move forward N logical sexps.
54132
This will skip over sexps that don't represent objects, such as ^{}."
@@ -84,7 +162,7 @@ sexp."
84162

85163
(defun cider--handle-debug (response)
86164
"Handle debugging notification.
87-
RESPONSE is a message received form the nrepl describing the input
165+
RESPONSE is a message received from the nrepl describing the input
88166
needed. It is expected to contain at least \"key\", \"input-type\", and
89167
\"prompt\", and possibly other entries depending on the input-type."
90168
(nrepl-dbind-response response (debug-value key coor filename point input-type prompt locals)
@@ -97,6 +175,7 @@ needed. It is expected to contain at least \"key\", \"input-type\", and
97175
((pred sequencep)
98176
(when (and filename point)
99177
(cider--debug-move-point filename point coor))
178+
(cider--debug-display-result-overlay debug-value)
100179
(cider--debug-read-command input-type debug-value prompt locals))))
101180
;; No matter what, we want to send this request or the session will stay
102181
;; hanged.

0 commit comments

Comments
 (0)