summaryrefslogtreecommitdiff
path: root/dape.el
diff options
context:
space:
mode:
Diffstat (limited to 'dape.el')
-rw-r--r--dape.el541
1 files changed, 286 insertions, 255 deletions
diff --git a/dape.el b/dape.el
index bc79c33..a0cf3f0 100644
--- a/dape.el
+++ b/dape.el
@@ -844,13 +844,9 @@ Debug logging has an noticeable effect on performance."
(defvar dape--source-buffers nil
"Plist of sources reference to buffer.")
(defvar dape--breakpoints nil
- "List of `dape--breakpoint's.")
-(defvar dape--exceptions nil
- "List of available exceptions as plists.")
+ "List of `dape--breakpoint' objects (source, data, and exception).")
(defvar dape--watched nil
"List of watched expressions.")
-(defvar dape--data-breakpoints nil
- "List of data breakpoints.")
(defvar dape--connection nil
"Debug adapter connection.")
(defvar dape--connection-selected nil
@@ -1494,9 +1490,21 @@ See `dape--connection-selected'."
:documentation
"Represents a DAP debugger. Wraps a process for DAP communication.")
-(cl-defstruct (dape--breakpoint (:constructor dape--breakpoint-make))
- "Breakpoint object storing location and state."
- location type value disabled hits verified id)
+(cl-defstruct (dape--breakpoint (:constructor nil))
+ "Base breakpoint object."
+ disabled verified id)
+
+(cl-defstruct (dape--source-breakpoint (:include dape--breakpoint))
+ "Source/line breakpoint."
+ location type value hits)
+
+(cl-defstruct (dape--data-breakpoint (:include dape--breakpoint))
+ "Data/hardware breakpoint."
+ data-id access-type name)
+
+(cl-defstruct (dape--exception-breakpoint (:include dape--breakpoint))
+ "Exception filter breakpoint."
+ filter label default)
(cl-defmethod jsonrpc-convert-to-endpoint ((conn dape-connection)
message subtype)
@@ -1655,22 +1663,22 @@ See `dape-request' for expected CB signature."
(cl-flet
((objectify (breakpoint)
(let ((plist `(:line ,(dape--breakpoint-line breakpoint))))
- (pcase (dape--breakpoint-type breakpoint)
+ (pcase (dape--source-breakpoint-type breakpoint)
('log
(if (dape--capable-p conn :supportsLogPoints)
(plist-put plist :logMessage
- (dape--breakpoint-value breakpoint))
+ (dape--source-breakpoint-value breakpoint))
(dape--warn "Adapter does not support `dape-breakpoint-log'")))
('expression
(if (dape--capable-p conn :supportsConditionalBreakpoints)
(plist-put plist :condition
- (dape--breakpoint-value breakpoint))
+ (dape--source-breakpoint-value breakpoint))
(dape--warn
"Adapter does not support `dape-breakpoint-expression'")))
('hits
(if (dape--capable-p conn :supportsHitConditionalBreakpoints)
(plist-put plist :hitCondition
- (dape--breakpoint-value breakpoint))
+ (dape--source-breakpoint-value breakpoint))
(dape--warn
"Adapter does not support `dape-breakpoint-hits'"))))
plist)))
@@ -1679,7 +1687,8 @@ See `dape-request' for expected CB signature."
;; mutations while request in flight.
breakpoints
(cl-loop for b in dape--breakpoints
- when (and (equal (dape--breakpoint-source b) source)
+ when (and (dape--source-breakpoint-p b)
+ (equal (dape--breakpoint-source b) source)
(not (dape--breakpoint-disabled b)))
collect b))
(source-object
@@ -1714,41 +1723,44 @@ See `dape-request' for expected CB signature."
(defun dape--set-exception-breakpoints (conn &optional cb)
"Set the exception breakpoints for adapter CONN.
-The exceptions are derived from `dape--exceptions'.
See `dape-request' for expected CB signature."
- (if (not dape--exceptions)
- (dape--request-continue cb)
- (dape-request
- conn :setExceptionBreakpoints
- `(:filters
- ,(cl-map 'vector
- (lambda (exception)
- (plist-get exception :filter))
- (seq-filter (lambda (exception)
- (plist-get exception :enabled))
- dape--exceptions)))
- cb)))
+ (let ((exceptions (cl-remove-if-not #'dape--exception-breakpoint-p
+ dape--breakpoints)))
+ (if (not exceptions)
+ (dape--request-continue cb)
+ (dape-request
+ conn :setExceptionBreakpoints
+ `(:filters
+ ,(cl-map 'vector
+ #'dape--exception-breakpoint-filter
+ (cl-remove-if #'dape--breakpoint-disabled exceptions)))
+ cb))))
(defun dape--configure-exceptions (conn &optional cb)
"Configure exception breakpoints for adapter CONN.
-The exceptions are derived from `dape--exceptions'.
See `dape-request' for expected CB signature."
- (setq dape--exceptions
- (cl-map
- 'list
- (lambda (exception)
- (if-let* ((stored-exception
- (cl-find (plist-get exception :filter)
- dape--exceptions
- :key (lambda (ex) (plist-get ex :filter))
- :test #'equal)))
- ;; Exception is known, store old value
- (plist-put exception :enabled
- (plist-get stored-exception :enabled))
- ;; New exception use default
- (plist-put exception :enabled
- (eq (plist-get exception :default) t))))
- (plist-get (dape--capabilities conn) :exceptionBreakpointFilters)))
+ (let ((old-exceptions (cl-remove-if-not #'dape--exception-breakpoint-p
+ dape--breakpoints)))
+ (setq dape--breakpoints
+ (cl-remove-if #'dape--exception-breakpoint-p dape--breakpoints))
+ (dolist (filter (append (plist-get (dape--capabilities conn)
+ :exceptionBreakpointFilters)
+ nil))
+ (let* ((id (plist-get filter :filter))
+ (old (cl-find id old-exceptions
+ :key #'dape--exception-breakpoint-filter
+ :test #'equal))
+ (enabled (if old
+ (not (dape--breakpoint-disabled old))
+ (eq (plist-get filter :default) t))))
+ ;; XXX Append to keep exceptions at bottom of breakpoint list.
+ (setq dape--breakpoints
+ (nconc dape--breakpoints
+ (list (make-dape--exception-breakpoint
+ :filter id
+ :label (plist-get filter :label)
+ :default (plist-get filter :default)
+ :disabled (not enabled))))))))
(dape--with-request (dape--set-exception-breakpoints conn)
(run-hooks 'dape-update-ui-hook)
(dape--request-continue cb)))
@@ -1758,6 +1770,7 @@ See `dape-request' for expected CB signature."
See `dape-request' for expected CB signature."
(if-let* ((sources
(thread-last dape--breakpoints
+ (cl-remove-if-not #'dape--source-breakpoint-p)
(seq-group-by #'dape--breakpoint-source)
(mapcar #'car))))
(cl-loop with responses = 0
@@ -1771,37 +1784,38 @@ See `dape-request' for expected CB signature."
(defun dape--set-data-breakpoints (conn cb)
"Set data breakpoints for adapter CONN.
See `dape-request' for expected CB signature."
- (if (dape--capable-p conn :supportsDataBreakpoints)
- (dape--with-request-bind
- ((&key breakpoints &allow-other-keys) error)
- (dape-request conn :setDataBreakpoints
- (list
- :breakpoints
- (cl-loop
- for plist in dape--data-breakpoints
- collect (list :dataId (plist-get plist :dataId)
- :accessType (plist-get plist :accessType))
- into breakpoints
- finally return (apply #'vector breakpoints))))
- (when error
- (message "Failed to setup data breakpoints: %s" error))
- (cl-loop
- for req-breakpoint in dape--data-breakpoints
- for res-breakpoint across (or breakpoints [])
- if (eq (plist-get res-breakpoint :verified) t)
- collect req-breakpoint into verfied-breakpoints else
- collect req-breakpoint into unverfied-breakpoints
- finally do
- (when unverfied-breakpoints
- (dape--warn "Failed setting data breakpoints for %s"
- (mapconcat (lambda (plist) (plist-get plist :name))
- unverfied-breakpoints ", ")))
- ;; FIXME Should not remove unverified-breakpoints as they
- ;; might be verified by another live connection.
- (setq dape--data-breakpoints verfied-breakpoints))
- (dape--request-continue cb error))
- (setq dape--data-breakpoints nil)
- (dape--request-continue cb)))
+ (let ((data-breakpoints (cl-remove-if-not #'dape--data-breakpoint-p
+ dape--breakpoints)))
+ (if (dape--capable-p conn :supportsDataBreakpoints)
+ (dape--with-request-bind
+ ((&key breakpoints &allow-other-keys) error)
+ (dape-request conn :setDataBreakpoints
+ (list
+ :breakpoints
+ (cl-map 'vector
+ (lambda (bp)
+ (list :dataId (dape--data-breakpoint-data-id bp)
+ :accessType (dape--data-breakpoint-access-type bp)))
+ data-breakpoints)))
+ (when error
+ (message "Failed to setup data breakpoints: %s" error))
+ (cl-loop
+ for bp in data-breakpoints
+ for res across (or breakpoints [])
+ unless (eq (plist-get res :verified) t)
+ collect bp into unverified
+ finally do
+ (when unverified
+ (dape--warn "Failed setting data breakpoints for %s"
+ (mapconcat #'dape--data-breakpoint-name unverified ", ")))
+ ;; FIXME Should not remove unverified-breakpoints as they
+ ;; might be verified by another live connection.
+ (setq dape--breakpoints
+ (cl-set-difference dape--breakpoints unverified)))
+ (dape--request-continue cb error))
+ (setq dape--breakpoints
+ (cl-remove-if #'dape--data-breakpoint-p dape--breakpoints))
+ (dape--request-continue cb))))
(defun dape--update-threads (conn cb)
"Update threads for CONN in-place if possible.
@@ -2564,7 +2578,7 @@ CONN is inferred for interactive invocations."
"Add or remove breakpoint at current line."
(interactive)
(if (cl-member nil (dape--breakpoints-at-point)
- :key #'dape--breakpoint-type)
+ :key #'dape--source-breakpoint-type)
(dape-breakpoint-remove-at-point)
(dape--breakpoint-place)))
@@ -2576,8 +2590,8 @@ Expressions within {} are interpolated."
(read-string "Log (Expressions within {} are interpolated): "
(when-let* ((breakpoint
(cl-find 'log (dape--breakpoints-at-point)
- :key #'dape--breakpoint-type)))
- (dape--breakpoint-value breakpoint)))))
+ :key #'dape--source-breakpoint-type)))
+ (dape--source-breakpoint-value breakpoint)))))
(if (string-empty-p message)
(dape-breakpoint-remove-at-point)
(dape--breakpoint-place 'log message)))
@@ -2590,8 +2604,8 @@ Expressions within {} are interpolated."
(read-string "Condition: "
(when-let* ((breakpoint
(cl-find 'expression (dape--breakpoints-at-point)
- :key #'dape--breakpoint-type)))
- (dape--breakpoint-value breakpoint)))))
+ :key #'dape--source-breakpoint-type)))
+ (dape--source-breakpoint-value breakpoint)))))
(if (string-empty-p expression)
(dape-breakpoint-remove-at-point)
(dape--breakpoint-place 'expression expression)))
@@ -2626,8 +2640,10 @@ When SKIP-NOTIFY is non-nil, do not notify adapters about removal."
(defun dape-breakpoint-remove-all ()
"Remove all breakpoints."
(interactive)
- (let ((sources (mapcar #'dape--breakpoint-source dape--breakpoints)))
- (dolist (breakpoint dape--breakpoints)
+ (let* ((source-bps (cl-remove-if-not #'dape--source-breakpoint-p
+ dape--breakpoints))
+ (sources (mapcar #'dape--breakpoint-source source-bps)))
+ (dolist (breakpoint source-bps)
(dape--breakpoint-remove breakpoint 'skip-notify))
(apply #'dape--breakpoint-notify-changes sources)))
@@ -2641,7 +2657,8 @@ The thread is identified by THREAD-ID under adapter CONN."
(cl-loop with index = 0
for conn in (dape--live-connections) append
(cl-loop for thread in (dape--threads conn) collect
- (list (format "%s %s" (cl-incf index) (plist-get thread :name))
+ (list (format "%s %s" (cl-incf index)
+ (plist-get thread :name))
conn
(plist-get thread :id)))))
(thread-name
@@ -3091,26 +3108,26 @@ If DISPLAY-P is non-nil, display buffer."
(defun dape--breakpoint-buffer (breakpoint)
"Return buffer visiting BREAKPOINT if exists."
- (when-let* ((overlay (dape--breakpoint-location breakpoint))
+ (when-let* (((dape--source-breakpoint-p breakpoint))
+ (overlay (dape--source-breakpoint-location breakpoint))
((overlayp overlay)))
(overlay-buffer overlay)))
(defun dape--breakpoint-file-name (breakpoint)
"Return file name for BREAKPOINT."
- (let ((location (dape--breakpoint-location breakpoint)))
- (cond ((overlayp location)
- (buffer-file-name (overlay-buffer location)))
- ((consp location)
- (car location)))))
+ (when-let* (((dape--source-breakpoint-p breakpoint))
+ (location (dape--source-breakpoint-location breakpoint)))
+ (cond ((overlayp location) (buffer-file-name (overlay-buffer location)))
+ ((consp location) (car location)))))
(defun dape--breakpoint-line (breakpoint)
"Return line number for BREAKPOINT."
- (let ((location (dape--breakpoint-location breakpoint)))
+ (when-let* (((dape--source-breakpoint-p breakpoint))
+ (location (dape--source-breakpoint-location breakpoint)))
(cond ((overlayp location)
(with-current-buffer (overlay-buffer location)
(line-number-at-pos (overlay-start location))))
- ((consp location)
- (cdr location)))))
+ ((consp location) (cdr location)))))
(defun dape--breakpoint-source (breakpoint)
"Return the source of BREAKPOINT.
@@ -3120,7 +3137,7 @@ Source is either a buffer or file name."
(dape--breakpoint-file-name breakpoint)))
(defun dape--breakpoints-in-buffer ()
- "Return list of breakpoints in current buffer."
+ "Return list of source breakpoints in current buffer."
(cl-remove (current-buffer) dape--breakpoints
:key #'dape--breakpoint-buffer :test-not #'eq))
@@ -3137,14 +3154,14 @@ Source is either a buffer or file name."
(concat " "
(propertize
(format "%s: %s" label
- (dape--breakpoint-value breakpoint))
+ (dape--source-breakpoint-value breakpoint))
'face face
'mouse-face 'highlight
'help-echo (format "mouse-1: %s" mouse-1-help)
'keymap (let ((map (make-sparse-keymap)))
(define-key map [mouse-1] mouse-1-def)
map)))))
- (pcase (dape--breakpoint-type breakpoint)
+ (pcase (dape--source-breakpoint-type breakpoint)
('log
(overlay-put ov 'after-string
(make-after-string
@@ -3178,7 +3195,7 @@ Source is either a buffer or file name."
dape-breakpoint-margin-string
'breakpoint
(or disabled-face 'dape-breakpoint-face))))))
- (setf (dape--breakpoint-location breakpoint) ov)))
+ (setf (dape--source-breakpoint-location breakpoint) ov)))
(dape--mouse-command dape-mouse-breakpoint-toggle
"Toggle breakpoint at current line."
@@ -3223,8 +3240,9 @@ Source is either a buffer or file name."
turn-on-dape-breakpoint-mode)
(defun dape--breakpoint-maybe-remove-ff-hook ()
- "Remove the `find-file-hook' if all breakpoints have buffers."
+ "Remove the `find-file-hook' if all source breakpoints have buffers."
(cl-loop for breakpoint in dape--breakpoints
+ when (dape--source-breakpoint-p breakpoint)
always (bufferp (dape--breakpoint-source breakpoint))
finally (remove-hook 'find-file-hook
#'dape--breakpoint-find-file-hook)))
@@ -3234,6 +3252,7 @@ Source is either a buffer or file name."
Called as a hook in `find-file-hook'."
(when-let* ((buffer-file-name (buffer-file-name)))
(cl-loop for breakpoint in dape--breakpoints
+ when (dape--source-breakpoint-p breakpoint)
for filename = (dape--breakpoint-file-name breakpoint)
for line = (dape--breakpoint-line breakpoint)
when (and (equal buffer-file-name filename) line)
@@ -3253,13 +3272,15 @@ If KEEP-STATE is non-nil preserve ID and VERIFIED state."
(unless keep-state
(setf (dape--breakpoint-id breakpoint) nil
(dape--breakpoint-verified breakpoint) nil))
- (setf (dape--breakpoint-hits breakpoint) nil)))
+ (when (dape--source-breakpoint-p breakpoint)
+ (setf (dape--source-breakpoint-hits breakpoint) nil))))
(defun dape--breakpoints-at-point ()
- "Return list of breakpoints at current point."
+ "Return list of source breakpoints at current point."
(cl-loop with current-line = (line-number-at-pos (point))
for breakpoint in dape--breakpoints
- when (and (eq (current-buffer) (dape--breakpoint-buffer breakpoint))
+ when (and (dape--source-breakpoint-p breakpoint)
+ (eq (current-buffer) (dape--breakpoint-buffer breakpoint))
(equal current-line (dape--breakpoint-line breakpoint)))
collect breakpoint))
@@ -3274,7 +3295,9 @@ If KEEP-STATE is non-nil preserve ID and VERIFIED state."
(defun dape--breakpoint-notify-all ()
"Notify adapters of changes in `dape--breakpoint's sources."
(apply #'dape--breakpoint-notify-changes
- (mapcar #'dape--breakpoint-source dape--breakpoints)))
+ (mapcar #'dape--breakpoint-source
+ (cl-remove-if-not #'dape--source-breakpoint-p
+ dape--breakpoints))))
(defun dape--breakpoint-buffer-kill-hook (&rest _)
"Convert overlay breakpoints in current buffer."
@@ -3283,7 +3306,7 @@ If KEEP-STATE is non-nil preserve ID and VERIFIED state."
(cond (buffer-file-name
(let ((line (dape--breakpoint-line breakpoint)))
(dape--breakpoint-delete-overlay breakpoint)
- (setf (dape--breakpoint-location breakpoint)
+ (setf (dape--source-breakpoint-location breakpoint)
`(,buffer-file-name . ,line)))
(add-hook 'find-file-hook #'dape--breakpoint-find-file-hook))
(t (dape--breakpoint-remove breakpoint))))))
@@ -3295,7 +3318,7 @@ If TYPE is `log', `expression', or `hits', VALUE should be a string.
Unless SKIP-NOTIFY is non-nil, notify all connections.
Note: removes existing breakpoints at the line before placing."
(dape-breakpoint-remove-at-point 'skip-notify)
- (let ((breakpoint (dape--breakpoint-make :type type :value value)))
+ (let ((breakpoint (make-dape--source-breakpoint :type type :value value)))
(dape--breakpoint-make-overlay breakpoint)
(push breakpoint dape--breakpoints)
(unless skip-notify
@@ -3304,7 +3327,7 @@ Note: removes existing breakpoints at the line before placing."
(defun dape--breakpoint-delete-overlay (breakpoint)
"Delete overlay of BREAKPOINT and restore margin if needed."
- (let ((overlay (dape--breakpoint-location breakpoint)))
+ (let ((overlay (dape--source-breakpoint-location breakpoint)))
(when-let* ((buffer (dape--breakpoint-buffer breakpoint)))
(with-current-buffer buffer
(when (and
@@ -3312,7 +3335,7 @@ Note: removes existing breakpoints at the line before placing."
dape--original-margin
;; ...and no breakpoints left in margin
(not (cl-some (lambda (bp)
- (let ((type (dape--breakpoint-type bp)))
+ (let ((type (dape--source-breakpoint-type bp)))
(or (not type) (eq 'until type))))
(dape--breakpoints-in-buffer))))
;; ...the margin should be reset
@@ -3324,7 +3347,7 @@ Note: removes existing breakpoints at the line before placing."
(redisplay t)))))
(when (overlayp overlay)
(delete-overlay overlay))
- (setf (dape--breakpoint-location breakpoint) nil)))
+ (setf (dape--source-breakpoint-location breakpoint) nil)))
(defun dape--breakpoint-disable (breakpoint disabled)
"Set BREAKPOINT overlay state to DISABLED."
@@ -3337,44 +3360,47 @@ Note: removes existing breakpoints at the line before placing."
(dape--breakpoint-make-overlay breakpoint))))
(defun dape--breakpoint-remove (breakpoint &optional skip-notify)
- "Remove BREAKPOINT breakpoint from buffer and notify all adapters.
+ "Remove BREAKPOINT from `dape--breakpoints' and notify adapters.
If SKIP-NOTIFY is non-nil, do not notify adapter about removal."
(setq dape--breakpoints (delq breakpoint dape--breakpoints))
- (unless skip-notify
- (dape--breakpoint-notify-changes (dape--breakpoint-source breakpoint)))
- (dape--breakpoint-delete-overlay breakpoint)
- (dape--breakpoint-maybe-remove-ff-hook)
+ (when (dape--source-breakpoint-p breakpoint)
+ (unless skip-notify
+ (dape--breakpoint-notify-changes (dape--breakpoint-source breakpoint)))
+ (dape--breakpoint-delete-overlay breakpoint)
+ (dape--breakpoint-maybe-remove-ff-hook))
(run-hooks 'dape-update-ui-hook))
(defun dape--breakpoint-update (conn breakpoint update)
"Update BREAKPOINT with UPDATE plist from CONN."
- (with-slots (id verified type value disabled) breakpoint
- (unless disabled
- ;; Update `dape--breakpoint' data
- (setf id (plist-put id conn (plist-get update :id))
- verified (plist-put verified conn
- (eq (plist-get update :verified) t)))
- ;; Move breakpoints and notify adapters
- (let ((buffer (dape--breakpoint-buffer breakpoint))
- (line (dape--breakpoint-line breakpoint))
- (new-line (plist-get update :line)))
- ;; Skip work and notify if nothing has moved
- (when (and (numberp line) (numberp new-line)
- (not (eq line new-line)))
- (dape--breakpoint-delete-overlay breakpoint)
- (if buffer
- (dape--with-line buffer new-line
- (dape-breakpoint-remove-at-point 'skip-notify)
- (dape--breakpoint-make-overlay breakpoint)
- (pulse-momentary-highlight-region
- (line-beginning-position) (line-beginning-position 2)
- 'next-error))
- (setcdr (dape--breakpoint-location breakpoint) new-line))
- (dape--breakpoint-notify-changes (dape--breakpoint-source breakpoint))
- (dape--message "Breakpoint in %s moved from line %s to %s"
- (if buffer (buffer-name buffer)
- (dape--breakpoint-file-name breakpoint))
- line new-line)))))
+ (unless (dape--breakpoint-disabled breakpoint)
+ ;; Update `dape--breakpoint' data
+ (setf (dape--breakpoint-id breakpoint)
+ (plist-put (dape--breakpoint-id breakpoint) conn
+ (plist-get update :id))
+ (dape--breakpoint-verified breakpoint)
+ (plist-put (dape--breakpoint-verified breakpoint) conn
+ (eq (plist-get update :verified) t)))
+ ;; Move breakpoints and notify adapters
+ (let ((buffer (dape--breakpoint-buffer breakpoint))
+ (line (dape--breakpoint-line breakpoint))
+ (new-line (plist-get update :line)))
+ ;; Skip work and notify if nothing has moved
+ (when (and (numberp line) (numberp new-line)
+ (not (eq line new-line)))
+ (dape--breakpoint-delete-overlay breakpoint)
+ (if buffer
+ (dape--with-line buffer new-line
+ (dape-breakpoint-remove-at-point 'skip-notify)
+ (dape--breakpoint-make-overlay breakpoint)
+ (pulse-momentary-highlight-region
+ (line-beginning-position) (line-beginning-position 2)
+ 'next-error))
+ (setcdr (dape--source-breakpoint-location breakpoint) new-line))
+ (dape--breakpoint-notify-changes (dape--breakpoint-source breakpoint))
+ (dape--message "Breakpoint in %s moved from line %s to %s"
+ (if buffer (buffer-name buffer)
+ (dape--breakpoint-file-name breakpoint))
+ line new-line))))
(run-hooks 'dape-update-ui-hook))
(defun dape-breakpoint-load (&optional filename)
@@ -3398,9 +3424,9 @@ Will use `dape-default-breakpoints-file' if FILENAME is nil."
(dape--breakpoint-place type value))
else do
(add-hook 'find-file-hook #'dape--breakpoint-find-file-hook)
- (push (dape--breakpoint-make :location (cons filename line)
- :type type
- :value value)
+ (push (make-dape--source-breakpoint :location (cons filename line)
+ :type type
+ :value value)
dape--breakpoints))))
(dape--breakpoint-notify-all))
@@ -3419,8 +3445,8 @@ Will use `dape-default-breakpoints-file' if FILENAME is nil."
for filename = (dape--breakpoint-file-name breakpoint)
when filename collect
`(,filename ,(dape--breakpoint-line breakpoint)
- ,(dape--breakpoint-type breakpoint)
- ,(dape--breakpoint-value breakpoint))
+ ,(dape--source-breakpoint-type breakpoint)
+ ,(dape--source-breakpoint-value breakpoint))
into serialized finally do
(prin1 serialized (current-buffer)))
;; Skip write if nothing has changed since last save
@@ -3847,46 +3873,49 @@ buffers get displayed and how they are grouped."
(dape--command-at-line dape-info-breakpoint-disable (dape--breakpoint)
(dape-info-breakpoints-mode)
"Enable or disable breakpoint at current line without removing it."
+ (unless (dape--source-breakpoint-p dape--breakpoint)
+ (user-error "Disable is only supported for source breakpoints"))
(dape--breakpoint-disable
dape--breakpoint (not (dape--breakpoint-disabled dape--breakpoint)))
(dape--breakpoint-notify-changes (dape--breakpoint-source dape--breakpoint))
(revert-buffer)
(run-hooks 'dape-update-ui-hook))
-(dape--command-at-line dape-info-breakpoint-dwim (dape--breakpoint
- dape--exception)
+(dape--command-at-line dape-info-breakpoint-dwim (dape--breakpoint)
(dape-info-breakpoints-mode)
- "Toggle exception or goto breakpoint at current line."
- (cond (dape--breakpoint
- (with-selected-window
- (display-buffer
- (or (dape--breakpoint-buffer dape--breakpoint)
- (find-file-noselect
- (dape--breakpoint-file-name dape--breakpoint)))
- dape-display-source-buffer-action)
- (goto-char (point-min))
- (forward-line (1- (dape--breakpoint-line dape--breakpoint)))))
- (dape--exception
- (plist-put dape--exception :enabled
- (not (plist-get dape--exception :enabled)))
- (dolist (conn (dape--live-connections))
- (dape--set-exception-breakpoints conn))
- (revert-buffer)
- (run-hooks 'dape-update-ui-hook))))
-
-
-(dape--command-at-line dape-info-breakpoint-delete (dape--breakpoint
- dape--data-breakpoint)
+ "Toggle exception or goto source breakpoint at current line."
+ (cl-typecase dape--breakpoint
+ (dape--source-breakpoint
+ (with-selected-window
+ (display-buffer
+ (or (dape--breakpoint-buffer dape--breakpoint)
+ (find-file-noselect
+ (dape--breakpoint-file-name dape--breakpoint)))
+ dape-display-source-buffer-action)
+ (goto-char (point-min))
+ (forward-line (1- (dape--breakpoint-line dape--breakpoint)))))
+ (dape--exception-breakpoint
+ (setf (dape--breakpoint-disabled dape--breakpoint)
+ (not (dape--breakpoint-disabled dape--breakpoint)))
+ (dolist (conn (dape--live-connections))
+ (dape--set-exception-breakpoints conn))
+ (revert-buffer)
+ (run-hooks 'dape-update-ui-hook))))
+
+(dape--command-at-line dape-info-breakpoint-delete (dape--breakpoint)
(dape-info-breakpoints-mode)
"Delete breakpoint at current line."
- (cond (dape--breakpoint
- (dape--breakpoint-remove dape--breakpoint))
- (dape--data-breakpoint
- (setq dape--data-breakpoints
- (delq dape--data-breakpoint
- dape--data-breakpoints))
- (when-let* ((conn (dape--live-connection 'stopped t)))
- (dape--with-request (dape--set-data-breakpoints conn)))))
+ (cl-typecase dape--breakpoint
+ (dape--exception-breakpoint
+ (setf (dape--breakpoint-disabled dape--breakpoint) t)
+ (dolist (conn (dape--live-connections))
+ (dape--set-exception-breakpoints conn)))
+ (dape--data-breakpoint
+ (dape--breakpoint-remove dape--breakpoint)
+ (when-let* ((conn (dape--live-connection 'stopped t)))
+ (dape--with-request (dape--set-data-breakpoints conn))))
+ (t
+ (dape--breakpoint-remove dape--breakpoint)))
(revert-buffer)
(run-hooks 'dape-update-ui-hook))
@@ -3900,7 +3929,7 @@ buffers get displayed and how they are grouped."
dape-display-source-buffer-action)
(goto-char (point-min))
(forward-line (1- (dape--breakpoint-line dape--breakpoint)))
- (pcase (dape--breakpoint-type dape--breakpoint)
+ (pcase (dape--source-breakpoint-type dape--breakpoint)
('log (call-interactively #'dape-breakpoint-log))
('expression (call-interactively #'dape-breakpoint-expression))
('hits (call-interactively #'dape-breakpoint-hits))
@@ -3927,77 +3956,76 @@ expression breakpoint")))))
(let ((table (make-gdb-table))
(y (propertize "y" 'font-lock-face 'font-lock-warning-face))
(n (propertize "n" 'font-lock-face 'font-lock-doc-face)))
- (cl-loop for plist in dape--data-breakpoints do
- (gdb-table-add-row
- table
- (list
- y "Data "
- (format "%s %s %s"
- (propertize (plist-get plist :name)
- 'font-lock-face
- 'font-lock-variable-name-face)
- (plist-get plist :accessType)
- (when-let* ((data-id (plist-get plist :dataId)))
- (format "(%s)" data-id))))
- `(dape--data-breakpoint ,plist)))
- (cl-loop for breakpoint in dape--breakpoints
- for line = (dape--breakpoint-line breakpoint)
- for verified-plist = (dape--breakpoint-verified breakpoint)
- for verified-p = (or
- ;; No live connection show all as verified
- (not (dape--live-connection 'last t))
- ;; Actually verified by any connection
- (cl-find-if (apply-partially #'plist-get
- verified-plist)
- (dape--live-connections))
- ;; If hit then must be verified
- (dape--breakpoint-hits breakpoint))
- do
- (gdb-table-add-row
- table
- (list
- (cond ((dape--breakpoint-disabled breakpoint) n)
- ((when-let* ((hits (dape--breakpoint-hits breakpoint)))
- (propertize (format "%s" hits)
- 'font-lock-face 'font-lock-warning-face)))
- (y))
- (pcase (dape--breakpoint-type breakpoint)
- ('log "Log ")
- ('hits "Hits ")
- ('expression "Cond ")
- ('until "Until")
- (_ "Break"))
- (or
- ;; If buffer live, display part of the line
- (when-let* ((buffer (dape--breakpoint-buffer breakpoint)))
- (concat
- (if-let* ((filename (buffer-file-name buffer)))
- (dape--format-file-name-line filename line)
- (format "%s:%d" (buffer-name buffer) line))
- (concat
- " "
- (thread-first
- (dape--with-line buffer line
- (or (thing-at-point 'line) ""))
- (string-trim-right)
- (truncate-string-to-width 80 nil nil t)))))
- ;; Otherwise just show filename:line
- (when-let* ((filename
- (dape--breakpoint-file-name breakpoint)))
- (dape--format-file-name-line filename line))))
- `( dape--breakpoint ,breakpoint
- mouse-face highlight
- help-echo "mouse-2, RET: visit breakpoint"
- ,@(unless verified-p '(font-lock-face shadow)))))
- (cl-loop for exception in dape--exceptions do
- (gdb-table-add-row
- table
- `(,(if (plist-get exception :enabled) y n)
- "Excep"
- ,(format "%s" (plist-get exception :label)))
- `( dape--exception ,exception
- mouse-face highlight
- help-echo "mouse-2, RET: toggle exception")))
+ (cl-loop for breakpoint in dape--breakpoints do
+ (cl-typecase breakpoint
+ (dape--data-breakpoint
+ (gdb-table-add-row
+ table
+ (list
+ y "Data "
+ (format "%s %s %s"
+ (propertize (dape--data-breakpoint-name breakpoint)
+ 'font-lock-face
+ 'font-lock-variable-name-face)
+ (dape--data-breakpoint-access-type breakpoint)
+ (when-let* ((id (dape--data-breakpoint-data-id breakpoint)))
+ (format "(%s)" id))))
+ `(dape--breakpoint ,breakpoint)))
+ (dape--source-breakpoint
+ (let* ((line (dape--breakpoint-line breakpoint))
+ (verified-plist (dape--breakpoint-verified breakpoint))
+ (verified-p
+ (or ;; No live connection show all as verified
+ (not (dape--live-connection 'last t))
+ ;; Actually verified by any connection
+ (cl-find-if (apply-partially #'plist-get verified-plist)
+ (dape--live-connections))
+ ;; If hit then must be verified
+ (dape--source-breakpoint-hits breakpoint))))
+ (gdb-table-add-row
+ table
+ (list
+ (cond ((dape--breakpoint-disabled breakpoint) n)
+ ((when-let* ((hits (dape--source-breakpoint-hits breakpoint)))
+ (propertize (format "%s" hits)
+ 'font-lock-face 'font-lock-warning-face)))
+ (y))
+ (pcase (dape--source-breakpoint-type breakpoint)
+ ('log "Log ")
+ ('hits "Hits ")
+ ('expression "Cond ")
+ ('until "Until")
+ (_ "Break"))
+ (or
+ ;; If buffer live, display part of the line
+ (when-let* ((buffer (dape--breakpoint-buffer breakpoint)))
+ (concat
+ (if-let* ((filename (buffer-file-name buffer)))
+ (dape--format-file-name-line filename line)
+ (format "%s:%d" (buffer-name buffer) line))
+ (concat
+ " "
+ (thread-first
+ (dape--with-line buffer line
+ (or (thing-at-point 'line) ""))
+ (string-trim-right)
+ (truncate-string-to-width 80 nil nil t)))))
+ ;; Otherwise just show filename:line
+ (when-let* ((filename (dape--breakpoint-file-name breakpoint)))
+ (dape--format-file-name-line filename line))))
+ `( dape--breakpoint ,breakpoint
+ mouse-face highlight
+ help-echo "mouse-2, RET: visit breakpoint"
+ ,@(unless verified-p '(font-lock-face shadow))))))
+ (dape--exception-breakpoint
+ (gdb-table-add-row
+ table
+ `(,(if (not (dape--breakpoint-disabled breakpoint)) y n)
+ "Excep"
+ ,(format "%s" (dape--exception-breakpoint-label breakpoint)))
+ `( dape--breakpoint ,breakpoint
+ mouse-face highlight
+ help-echo "mouse-2, RET: toggle exception")))))
(insert (gdb-table-string table " ")))))
@@ -4414,12 +4442,13 @@ current buffer with CONN config."
:frameId (plist-get (dape--current-stack-frame conn) :id))))
(if (or error (not (stringp dataId)))
(message "Unable to set data breakpoint: %s" (or error description))
- (push (list :name name
- :dataId dataId
- :accessType (completing-read
- (format "Breakpoint type for `%s': " name)
- (append accessTypes nil) nil t))
- dape--data-breakpoints)
+ (push (make-dape--data-breakpoint
+ :name name
+ :data-id dataId
+ :access-type (completing-read
+ (format "Breakpoint type for `%s': " name)
+ (append accessTypes nil) nil t))
+ dape--breakpoints)
(dape--with-request
(dape--set-data-breakpoints conn)
;; Make sure breakpoint buffer is displayed
@@ -5235,14 +5264,15 @@ CONN is inferred for interactive invocations."
(add-hook 'dape-active-mode-hook #'dape--until-reset)
(add-hook 'dape-stopped-hook #'dape--until-reset)
(if (cl-member 'until (dape--breakpoints-at-point)
- :key #'dape--breakpoint-type)
+ :key #'dape--source-breakpoint-type)
(dape-breakpoint-remove-at-point)
(let (;; Block to ensure breakpoints changes before continue
(dape--request-blocking t))
;; Disable all non disabled breakpoints temporarily
(cl-loop for breakpoint in dape--breakpoints
- unless (or (dape--breakpoint-disabled breakpoint)
- (eq (dape--breakpoint-type breakpoint) 'until))
+ unless (or (not (dape--source-breakpoint-p breakpoint))
+ (dape--breakpoint-disabled breakpoint)
+ (eq (dape--source-breakpoint-type breakpoint) 'until))
do (dape--breakpoint-disable breakpoint 'until)
finally do (dape--breakpoint-notify-all))
(dape--breakpoint-place 'until)
@@ -5254,7 +5284,8 @@ CONN is inferred for interactive invocations."
(let (notification-required-p)
(dolist (breakpoint dape--breakpoints)
(cond (;; Remove all `until' breakpoints
- (eq (dape--breakpoint-type breakpoint) 'until)
+ (and (dape--source-breakpoint-p breakpoint)
+ (eq (dape--source-breakpoint-type breakpoint) 'until))
(dape--breakpoint-remove breakpoint))
(;; Enable all disabled breakpoints
(eq (dape--breakpoint-disabled breakpoint) 'until)