Skip to content

Commit 178b520

Browse files
committed
dap-mouse: support triggering manually
Refactor the value rendering of `dap-mouse' into a new function: `dap-ui-render-value'. The new `dap-tooltip-at-point' function creates a dap-mouse posframe under the cursor, and can be used without `dap-tooltip-mode'. Extend `dap--resp-handler' to take an error callback. which is leveraged in `dap-tooltip-at-point' to make the error handling more explicit. Add functions to evaluate expressions in a new `treemacs' buffer: `dap-ui-eval-in-buffer', `dap-ui-eval-variable-in-buffer', based on the new `dap-ui-render-value' function.
1 parent d385752 commit 178b520

File tree

3 files changed

+99
-52
lines changed

3 files changed

+99
-52
lines changed

dap-mode.el

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,17 +315,18 @@ The hook will be called with the session file and the new set of breakpoint loca
315315
"Get currently active `dap--debug-session'."
316316
(lsp-workspace-get-metadata "default-session"))
317317

318-
(defun dap--resp-handler (&optional success-callback)
318+
(defun dap--resp-handler (&optional success-callback error-callback)
319319
"Generate a response handler, for use in `dap--send-message'.
320320
321321
If the request is successful, call SUCCESS-CALLBACK with the
322322
entire resulting messsage.
323323
324-
The handler will call `error' on failure."
324+
The handler will call ERROR-CALLBACK with the message or `error'
325+
on failure."
325326
(-lambda ((result &as &hash "success" "message"))
326327
(if success
327328
(when success-callback (funcall success-callback result))
328-
(error message))))
329+
(if error-callback (funcall error-callback message) (error message)))))
329330

330331
(defun dap--session-init-resp-handler (debug-session &optional success-callback)
331332
"Returned handler will mark the DEBUG-SESSION as failed if call return error.

dap-mouse.el

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ ACTIVATEP non-nil means activate mouse motion events."
114114
(kill-local-variable 'track-mouse))))
115115

116116
(defun dap-tooltip-mouse-motion (event)
117-
"Command handler for mouse movement events in `dap-mode-map'."
117+
"Command handler for mouse movement events in `dap-mode-map'.
118+
EVENT is the last mouse movement event."
118119
(interactive "e")
119120
(tooltip-hide)
120121
(when (car (mouse-pixel-position))
@@ -168,22 +169,17 @@ If there is an active selection - return it."
168169
(setq dap-mouse--hide-timer nil)
169170
(remove-hook 'post-command-hook #'dap-tooltip-post-tooltip)))))))
170171

171-
(defun dap-tooltip-tips (event)
172-
"Show tip for identifier or selection under the mouse.
173-
The mouse must either point at an identifier or inside a selected
174-
region for the tip window to be shown. In the case of a C program
175-
controlled by GDB, show the associated #define directives when program is
176-
not executing.
177-
178-
This function must return nil if it doesn't handle EVENT."
179-
(setq dap-tooltip--request (1+ dap-tooltip--request))
180-
172+
(defun dap-tooltip-at-point (&optional pos)
173+
"Show information about the variable under point.
174+
The result is displayed in a `treemacs' `posframe'. POS,
175+
defaulting to `point', specifies where the cursor is and
176+
consequently where to show the `posframe'."
177+
(interactive)
178+
(cl-incf dap-tooltip--request)
181179
(let ((debug-session (dap--cur-session))
182-
(mouse-point (posn-point (event-end event)))
180+
(mouse-point (or pos (point)))
183181
(request-id dap-tooltip--request))
184-
(when (and (eventp event)
185-
(dap--session-running debug-session)
186-
dap-tooltip-mode
182+
(when (and (dap--session-running debug-session)
187183
mouse-point)
188184
(-when-let* ((active-frame-id (-some->> debug-session
189185
dap--debug-session-active-frame
@@ -197,38 +193,40 @@ This function must return nil if it doesn't handle EVENT."
197193
(list :expression expression
198194
:frameId active-frame-id
199195
:context "hover"))
200-
(-lambda ((&hash "success" "body"
201-
(&hash? "result"
202-
"variablesReference" variables-reference)))
203-
(when (and success
204-
;; REVIEW: hover failure will yield weird errors involving
205-
;; process filters, so I resorted to this hack; we should
206-
;; perhaps do proper error handling?
207-
(= request-id dap-tooltip--request))
208-
(add-text-properties
209-
start end '(mouse-face dap-mouse-eval-thing-face))
210-
;; REVIEW: I inherited this code; why kill the buffer first,
211-
;; then show it, and then initialize it?
212-
(when (get-buffer dap-mouse-buffer)
213-
(kill-buffer dap-mouse-buffer))
214-
(unless (and (zerop variables-reference) (string-empty-p result))
215-
(apply #'posframe-show dap-mouse-buffer
216-
:position start
217-
:accept-focus t
218-
dap-mouse-posframe-properties)
219-
(with-current-buffer (get-buffer-create dap-mouse-buffer)
220-
(lsp-treemacs-render
221-
`((:key ,expression
222-
:label ,result
223-
:icon dap-field
224-
,@(unless (zerop variables-reference)
225-
(list :children
226-
(-partial #'dap-ui-render-variables
227-
debug-session
228-
variables-reference)))))
229-
"" nil (buffer-name))))
230-
(add-hook 'post-command-hook 'dap-tooltip-post-tooltip)))
231-
debug-session))))
196+
(dap--resp-handler
197+
(-lambda ((&hash "body" (&hash? "result"
198+
"variablesReference" variables-reference)))
199+
(when (= request-id dap-tooltip--request)
200+
(add-text-properties
201+
start end '(mouse-face dap-mouse-eval-thing-face))
202+
;; Show a dead buffer so that the `posframe' size is consistent.
203+
(when (get-buffer dap-mouse-buffer)
204+
(kill-buffer dap-mouse-buffer))
205+
(unless (and (zerop variables-reference) (string-empty-p result))
206+
(apply #'posframe-show dap-mouse-buffer
207+
:position start
208+
:accept-focus t
209+
dap-mouse-posframe-properties)
210+
(with-current-buffer (get-buffer-create dap-mouse-buffer)
211+
(dap-ui-render-value debug-session expression
212+
result variables-reference)))
213+
(add-hook 'post-command-hook 'dap-tooltip-post-tooltip)))
214+
;; TODO: hover failure will yield weird errors involving process
215+
;; filters, so I resorted to this hack; we should proably do proper
216+
;; error handling, with a whitelist of allowable errors.
217+
#'ignore)
218+
debug-session)))))
219+
220+
(defun dap-tooltip-tips (event)
221+
"Show tip for identifier or selection under the mouse.
222+
The mouse must either point at an identifier or inside a selected
223+
region for the tip window to be shown. In the case of a C program
224+
controlled by GDB, show the associated #define directives when
225+
program is not executing.
226+
227+
This function must return nil if it doesn't handle EVENT."
228+
(when (and (eventp event) dap-tooltip-mode)
229+
(dap-tooltip-at-point (posn-point (event-end event))))
232230
"")
233231

234232
(provide 'dap-mouse)

dap-ui.el

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -785,8 +785,8 @@ DEBUG-SESSION is the debug session triggering the event."
785785

786786
(defun dap-ui-render-variables (debug-session variables-reference _node)
787787
"Render hierarchical variables for treemacs.
788-
Usable as the :children argument, when DEBUG-SESSION and
789-
VARIABLES-REFERENCE are applyied partially.
788+
Usable as the `treemacs' :children argument, when DEBUG-SESSION
789+
and VARIABLES-REFERENCE are applied partially.
790790
791791
DEBUG-SESSION specifies the debug session which will be used to
792792
issue requests.
@@ -817,6 +817,54 @@ adapter for acquiring nested variables and must not be 0."
817817
(list :children
818818
(-partial #'dap-ui-render-variables debug-session
819819
variables-reference)))))))))
820+
821+
(defun dap-ui-render-value
822+
(debug-session expression value variables-reference)
823+
"Render a hover result to the current buffer.
824+
VALUE is the evaluate result, DEBUG-SESSION the debug session as
825+
usual and EXPRESSION the expression that was originally
826+
evaluated. VARIABLES-REFERENCE is returned by the evaluate
827+
request."
828+
(lsp-treemacs-render
829+
`((:key ,expression
830+
:label ,value
831+
:icon dap-field
832+
,@(unless (zerop variables-reference)
833+
(list :children
834+
(-partial #'dap-ui-render-variables
835+
debug-session
836+
variables-reference)))))
837+
"" nil (buffer-name)))
838+
839+
(defun dap-ui-eval-in-buffer (expression)
840+
"Like `dap-eval', but in a new treemacs buffer."
841+
(interactive "sExpr: ")
842+
(let ((debug-session (dap--cur-active-session-or-die)))
843+
(if-let ((active-frame-id (-some->> debug-session
844+
dap--debug-session-active-frame
845+
(gethash "id"))))
846+
(dap--send-message
847+
(dap--make-request "evaluate"
848+
(list :expression expression
849+
:frameId active-frame-id
850+
:context "hover"))
851+
(dap--resp-handler
852+
(-lambda ((&hash "body" (&hash? "result" "variablesReference"
853+
variables-reference)))
854+
(with-current-buffer
855+
(get-buffer-create (format "*evaluate %s*" expression))
856+
(let ((inhibit-read-only t)) (erase-buffer))
857+
(dap-ui-render-value debug-session expression result
858+
variables-reference)
859+
(display-buffer (current-buffer)))))
860+
debug-session)
861+
(error "`dap-eval-in-buffer': no stopped debug session"))))
862+
863+
(defun dap-ui-eval-variable-in-buffer ()
864+
"Evaluate the symbol at point in a new buffer."
865+
(interactive)
866+
(dap-ui-eval-in-buffer (thing-at-point 'symbol)))
867+
820868
(defvar dap-ui--locals-timer nil)
821869

822870
(defun dap-ui-locals--refresh (&rest _)

0 commit comments

Comments
 (0)