From f2b653e1a38dee896b735a7021f42bc3edf10be0 Mon Sep 17 00:00:00 2001 From: Daniel Pettersson Date: Sun, 31 Dec 2023 12:49:55 +0100 Subject: [PATCH 01/11] Add debug prints to failing test --- dape-tests.el | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dape-tests.el b/dape-tests.el index 163c3f70..0643d480 100644 --- a/dape-tests.el +++ b/dape-tests.el @@ -48,7 +48,12 @@ failed." (with-timeout (,seconds) (while (not ,pred) (accept-process-output nil 0.01))) - (should ,pred) + (condition-case err + (should ,pred) + (ert-test-failed + (message "Current buffer: %s" (current-buffer)) + (message "Current buffer contents:\n %s" (buffer-string)) + (signal 'ert-test-failed (cdr err)))) (let ((ret ,pred)) (ignore ret) ret)))) From 254e0dc2415bbf646fd0de8caf46b007572dc76a Mon Sep 17 00:00:00 2001 From: Daniel Pettersson Date: Sun, 31 Dec 2023 12:53:44 +0100 Subject: [PATCH 02/11] Add workflow dispatch --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6acc8954..ceee2152 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,6 +5,7 @@ on: branches: - master pull_request: + workflow_dispatch: jobs: test: From 9f7bd2636f87322157d1c5b382a7bcb8a60e624c Mon Sep 17 00:00:00 2001 From: Daniel Pettersson Date: Mon, 1 Jan 2024 14:38:00 +0100 Subject: [PATCH 03/11] Cleanup should for cleaner ert errors --- dape-tests.el | 144 ++++++++++++++++++++++---------------------------- 1 file changed, 62 insertions(+), 82 deletions(-) diff --git a/dape-tests.el b/dape-tests.el index 0643d480..5d0baf3a 100644 --- a/dape-tests.el +++ b/dape-tests.el @@ -52,7 +52,7 @@ failed." (should ,pred) (ert-test-failed (message "Current buffer: %s" (current-buffer)) - (message "Current buffer contents:\n %s" (buffer-string)) + (message "Current buffer contents:\n%s" (buffer-string)) (signal 'ert-test-failed (cdr err)))) (let ((ret ,pred)) (ignore ret) @@ -109,6 +109,9 @@ Helper for `dape-test--with-files'." (dape-test--should (not (process-list))) (advice-remove 'yes-or-no-p 'always-yes) + ;; clean up buffers + (dolist (buffer buffers) + (kill-buffer buffer)) ;; clean up files (delete-directory temp-dir t))))) @@ -203,18 +206,16 @@ Expects line with string \"breakpoint\" in source." (dape-breakpoint-toggle))) (apply 'dape-test--debug dape-args) ;; at breakpoint and stopped - (dape-test--should - (and (eq dape--state 'stopped) - (equal (line-number-at-pos) - (dape-test--line-at-regex "breakpoint")))) + (dape-test--should (equal dape--state 'stopped)) + (dape-test--should (equal (line-number-at-pos) + (dape-test--line-at-regex "breakpoint"))) ;; restart (goto-char (point-min)) (apply 'dape-test--debug dape-args) ;; at breakpoint and stopped - (dape-test--should - (and (eq dape--state 'stopped) - (equal (line-number-at-pos) - (dape-test--line-at-regex "breakpoint")))))) + (dape-test--should (eq dape--state 'stopped)) + (dape-test--should (= (line-number-at-pos) + (dape-test--line-at-regex "breakpoint"))))) (ert-deftest dape-test-restart-with-dape () "Should be able to restart with `dape' even though session active." @@ -380,29 +381,24 @@ Expects line with string \"breakpoint\" in source." ;; contents of watch buffer (with-current-buffer (dape-test--should (dape--info-get-live-buffer 'dape-info-watch-mode)) - (dape-test--should - (and (dape-test--line-at-regex "^ a") - (dape-test--line-at-regex "^\\+ b"))) + (dape-test--should (dape-test--line-at-regex "^ a")) + (dape-test--should (dape-test--line-at-regex "^\\+ b")) ;; expansion (dape-test--apply-to-match "^\\+ b" 'dape-info-scope-toggle) (dape-test--should (dape-test--line-at-regex "^ member")) ;; assert contraction (dape-test--apply-to-match "^\\- b" 'dape-info-scope-toggle) - (dape-test--should - (not (dape-test--line-at-regex "^ member"))) + (dape-test--should (not (dape-test--line-at-regex "^ member"))) ;; set value - (dape-test--should - (dape-test--line-at-regex "^ a *0")) + (dape-test--should (dape-test--line-at-regex "^ a *0")) (cl-letf (((symbol-function 'read-string) (lambda (&rest _) "99"))) (dape-test--apply-to-match "^ a" 'dape-info-variable-edit)) - (dape-test--should - (dape-test--line-at-regex "^ a *99")) + (dape-test--should (dape-test--line-at-regex "^ a *99")) ;; watch removal (dape-test--apply-to-match "^ a" 'dape-info-scope-watch-dwim) - (dape-test--should - (not (dape-test--line-at-regex "^ a")))))) + (dape-test--should (not (dape-test--line-at-regex "^ a")))))) (ert-deftest dape-test-stack-buffer() "Stack buffer contents and commands." @@ -434,20 +430,18 @@ Expects line with string \"breakpoint\" in source." (with-current-buffer (dape-test--should (dape--info-get-live-buffer 'dape-info-stack-mode)) ;; buffer contents - (dape-test--should - (and (dape-test--line-at-regex "^1 in b") - (dape-test--line-at-regex "^2 in a") - (member 'dape--info-stack-position - overlay-arrow-variable-list) - (= (marker-position dape--info-stack-position) 1))) + (dape-test--should (dape-test--line-at-regex "^1 in b")) + (dape-test--should (dape-test--line-at-regex "^2 in a")) + (dape-test--should (member 'dape--info-stack-position + overlay-arrow-variable-list)) + (dape-test--should (= (marker-position dape--info-stack-position) 1)) ;; select stack frame (dape-test--apply-to-match "^2 in a" 'dape-info-stack-select) ;; buffer contents - (dape-test--should - (and (= (marker-position dape--info-stack-position) - (save-excursion - (dape-test--goto-line (dape-test--line-at-regex "^2 in a")) - (point)))))) + (dape-test--should (= (marker-position dape--info-stack-position) + (save-excursion + (dape-test--goto-line (dape-test--line-at-regex "^2 in a")) + (point))))) ;; scope buffer should update to new stack (with-current-buffer (dape-test--should @@ -456,8 +450,9 @@ Expects line with string \"breakpoint\" in source." (dape-test--line-at-regex "^ a_var"))) ;; source buffer points at new stack frame (with-current-buffer main-buffer - (= (line-number-at-pos) - (dape-test--line-at-regex "stack"))))) + (dape-test--should + (= (line-number-at-pos) + (dape-test--line-at-regex "stack")))))) (ert-deftest dape-test-threads-buffer () "Threads buffer contents and commands." @@ -490,38 +485,31 @@ Expects line with string \"breakpoint\" in source." (with-current-buffer (dape-test--should (dape--info-get-live-buffer 'dape-info-threads-mode)) ;; buffer contents - (dape-test--should - (and (dape-test--line-at-regex "^1 .* stopped in") - (dape-test--line-at-regex "^2 .* stopped in thread_fn") - (member 'dape--info-thread-position - overlay-arrow-variable-list) - (= (marker-position dape--info-thread-position) - (save-excursion - (dape-test--goto-line (dape-test--line-at-regex - "^2 .* stopped in thread_fn")) - (point)))))) + (dape-test--should (dape-test--line-at-regex "^1 .* stopped in")) + (dape-test--should (dape-test--line-at-regex "^2 .* stopped in thread_fn")) + (dape-test--should (member 'dape--info-thread-position overlay-arrow-variable-list)) + (dape-test--should (= (marker-position dape--info-thread-position) + (save-excursion + (dape-test--goto-line (dape-test--line-at-regex + "^2 .* stopped in thread_fn")) + (point))))) (with-current-buffer (dape-test--should (dape--info-get-live-buffer 'dape-info-scope-mode 0)) ;; scope buffer in thread_fn - (dape-test--should - (dape-test--line-at-regex "^ thread_var"))) - (with-current-buffer (dape-test--should - (dape--info-get-live-buffer 'dape-info-threads-mode)) + (dape-test--should (dape-test--line-at-regex "^ thread_var"))) + (with-current-buffer (dape-test--should (dape--info-get-live-buffer 'dape-info-threads-mode)) ;; select thread (dape-test--apply-to-match "^1 .* stopped in" 'dape-info-select-thread)) - (with-current-buffer (dape-test--should - (dape--info-get-live-buffer 'dape-info-threads-mode)) + (with-current-buffer (dape-test--should (dape--info-get-live-buffer 'dape-info-threads-mode)) ;; thread selected - (dape-test--should - (and (dape-test--line-at-regex "^1 .* stopped in") - (dape-test--line-at-regex "^2 .* stopped in thread_fn") - (member 'dape--info-thread-position - overlay-arrow-variable-list) - (= (marker-position dape--info-thread-position) - (save-excursion - (dape-test--goto-line (dape-test--line-at-regex - "^1 .* stopped in")) - (point)))))) + (dape-test--should (dape-test--line-at-regex "^1 .* stopped in")) + (dape-test--should (dape-test--line-at-regex "^2 .* stopped in thread_fn")) + (dape-test--should (member 'dape--info-thread-position overlay-arrow-variable-list)) + (dape-test--should (= (marker-position dape--info-thread-position) + (save-excursion + (dape-test--goto-line (dape-test--line-at-regex + "^1 .* stopped in")) + (point))))) (with-current-buffer (dape-test--should (dape--info-get-live-buffer 'dape-info-scope-mode 0)) ;; scope buffer in thread_fn @@ -546,29 +534,25 @@ Expects line with string \"breakpoint\" in source." (dape-test--debug 'debugpy :program (buffer-file-name main-buffer) :cwd default-directory) + ;; at breakpoint and stopped - (dape-test--should - (eq dape--state 'stopped)) (with-current-buffer main-buffer - (dape-test--should - (and (= (line-number-at-pos) - (dape-test--line-at-regex "breakpoint")) - (eq dape--state 'stopped)))) + (dape-test--should (= (line-number-at-pos) + (dape-test--line-at-regex "breakpoint")))) + (dape-test--should (eq dape--state 'stopped)) + (dape-test--should (get-buffer "*dape-repl*")) (pop-to-buffer "*dape-repl*") (insert "next") (comint-send-input) (with-current-buffer main-buffer - (dape-test--should - (and (= (line-number-at-pos) - (dape-test--line-at-regex "second line")) - (eq dape--state 'stopped)))) + (dape-test--should (= (line-number-at-pos) + (dape-test--line-at-regex "second line")))) + (dape-test--should (eq dape--state 'stopped)) (insert "next") (comint-send-input) + (dape-test--should (eq dape--state 'stopped)) (with-current-buffer main-buffer - (dape-test--should - (and (= (line-number-at-pos) - (dape-test--line-at-regex "third line")) - (eq dape--state 'stopped)))) + (dape-test--should (= (line-number-at-pos) (dape-test--line-at-regex "third line")))) (insert "a = 99") (comint-send-input) (with-current-buffer (dape-test--should @@ -593,14 +577,12 @@ Expects line with string \"breakpoint\" in source." :program (buffer-file-name main-buffer) :cwd default-directory) ;; at breakpoint and stopped - (dape-test--should - (eq dape--state 'stopped)) + (dape-test--should (eq dape--state 'stopped)) (dape--info-buffer 'dape-info-modules-mode) ;; contents (with-current-buffer (dape-test--should (dape--info-get-live-buffer 'dape-info-modules-mode)) - (dape-test--should - (dape-test--line-at-regex "^__main__ of main.py"))))) + (dape-test--should (dape-test--line-at-regex "^__main__ of main.py"))))) (ert-deftest dape-test-sources-buffer () "Sources buffer contents and commands." @@ -620,15 +602,13 @@ Expects line with string \"breakpoint\" in source." :program (buffer-file-name index-buffer) :cwd default-directory) ;; stopped - (dape-test--should - (eq dape--state 'stopped)) + (dape-test--should (eq dape--state 'stopped)) (dape--info-buffer 'dape-info-sources-mode) ;; contents (with-current-buffer (dape-test--should (dape--info-get-live-buffer 'dape-info-sources-mode)) - (dape-test--should - (and (dape-test--line-at-regex "^os ") - (dape-test--line-at-regex "index.js")))) + (dape-test--should (dape-test--line-at-regex "^os ")) + (dape-test--should (dape-test--line-at-regex "index.js"))) (with-current-buffer (dape-test--should (dape--info-get-live-buffer 'dape-info-sources-mode)) (dape-test--apply-to-match "^os " 'dape-info-sources-goto)) From 250cbb864bd7e119b80a50e367bb6afec516af6c Mon Sep 17 00:00:00 2001 From: Daniel Pettersson Date: Mon, 1 Jan 2024 14:56:58 +0100 Subject: [PATCH 04/11] Add dape-debug contents on failure --- dape-tests.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dape-tests.el b/dape-tests.el index 5d0baf3a..62d5a5e0 100644 --- a/dape-tests.el +++ b/dape-tests.el @@ -53,6 +53,8 @@ failed." (ert-test-failed (message "Current buffer: %s" (current-buffer)) (message "Current buffer contents:\n%s" (buffer-string)) + (when-let ((debug-buffer (get-buffer "*dape-debug*"))) + (message "dape-debug contents:\n%s" (buffer-string))) (signal 'ert-test-failed (cdr err)))) (let ((ret ,pred)) (ignore ret) From dcd65938fd88f078fe1cd1d3ef5b2dcc40e9167d Mon Sep 17 00:00:00 2001 From: Daniel Pettersson Date: Mon, 1 Jan 2024 15:01:10 +0100 Subject: [PATCH 05/11] Ensure nil state on test cleanup --- dape-tests.el | 1 + 1 file changed, 1 insertion(+) diff --git a/dape-tests.el b/dape-tests.el index 62d5a5e0..6b38860a 100644 --- a/dape-tests.el +++ b/dape-tests.el @@ -111,6 +111,7 @@ Helper for `dape-test--with-files'." (dape-test--should (not (process-list))) (advice-remove 'yes-or-no-p 'always-yes) + (setq dape--state nil) ;; clean up buffers (dolist (buffer buffers) (kill-buffer buffer)) From 1e9587bbfc7bc0f8fde818961eb3fc300e10d9ab Mon Sep 17 00:00:00 2001 From: Daniel Pettersson Date: Mon, 1 Jan 2024 15:03:06 +0100 Subject: [PATCH 06/11] Change stopped strategy --- dape-tests.el | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dape-tests.el b/dape-tests.el index 6b38860a..ff26e8e4 100644 --- a/dape-tests.el +++ b/dape-tests.el @@ -111,7 +111,6 @@ Helper for `dape-test--with-files'." (dape-test--should (not (process-list))) (advice-remove 'yes-or-no-p 'always-yes) - (setq dape--state nil) ;; clean up buffers (dolist (buffer buffers) (kill-buffer buffer)) @@ -542,7 +541,7 @@ Expects line with string \"breakpoint\" in source." (with-current-buffer main-buffer (dape-test--should (= (line-number-at-pos) (dape-test--line-at-regex "breakpoint")))) - (dape-test--should (eq dape--state 'stopped)) + (dape-test--should (dape--stopped-threads)) (dape-test--should (get-buffer "*dape-repl*")) (pop-to-buffer "*dape-repl*") (insert "next") @@ -553,7 +552,7 @@ Expects line with string \"breakpoint\" in source." (dape-test--should (eq dape--state 'stopped)) (insert "next") (comint-send-input) - (dape-test--should (eq dape--state 'stopped)) + (dape-test--should (dape--stopped-threads)) (with-current-buffer main-buffer (dape-test--should (= (line-number-at-pos) (dape-test--line-at-regex "third line")))) (insert "a = 99") From ae0ac0d18f4bcbcfdb605cf1101456d22c06b089 Mon Sep 17 00:00:00 2001 From: Daniel Pettersson Date: Mon, 1 Jan 2024 15:29:07 +0100 Subject: [PATCH 07/11] Fix debug printouts --- dape-tests.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dape-tests.el b/dape-tests.el index ff26e8e4..9fb9a3f0 100644 --- a/dape-tests.el +++ b/dape-tests.el @@ -54,7 +54,8 @@ failed." (message "Current buffer: %s" (current-buffer)) (message "Current buffer contents:\n%s" (buffer-string)) (when-let ((debug-buffer (get-buffer "*dape-debug*"))) - (message "dape-debug contents:\n%s" (buffer-string))) + (with-current-buffer debug-buffer + (message "dape-debug contents:\n%s" (buffer-string)))) (signal 'ert-test-failed (cdr err)))) (let ((ret ,pred)) (ignore ret) From 99ee5980101fafd46c5115ddcbe78d3beb5d86ac Mon Sep 17 00:00:00 2001 From: Daniel Pettersson Date: Mon, 1 Jan 2024 16:00:58 +0100 Subject: [PATCH 08/11] Rework restart-in-progress to use adapter terminate arg --- dape.el | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/dape.el b/dape.el index c316fa11..43034999 100644 --- a/dape.el +++ b/dape.el @@ -567,8 +567,6 @@ The hook is run with one argument, the compilation buffer." "Debug adapter communications process.") (defvar dape--parent-process nil "Debug adapter parent process. Used for by startDebugging adapters.") -(defvar dape--restart-in-progress nil - "Used for prevent adapter killing when restart request is in flight.") (defvar-local dape--source nil "Store source plist in fetched source buffer.") @@ -1625,12 +1623,12 @@ Starts a new process as per request of the debug adapter." 'dape-repl-exit-code-exit 'dape-repl-exit-code-fail))) -(cl-defmethod dape-handle-event (_process (_event (eql terminated)) _body) +(cl-defmethod dape-handle-event (_process (_event (eql terminated)) body) "Handle terminated events." (dape--update-state 'terminated) (dape--remove-stack-pointers) (dape--repl-message "* Program terminated *" 'italic) - (unless dape--restart-in-progress + (unless (eq (plist-get :restart body) t) (dape-kill))) @@ -1655,7 +1653,6 @@ Starts a new process as per request of the debug adapter." dape--stack-id nil dape--source-buffers nil dape--process process - dape--restart-in-progress nil dape--repl-insert-text-guard nil) (dape--update-state 'starting) (run-hook-with-args 'dape-on-start-hooks) @@ -1800,10 +1797,7 @@ Starts a new process as per request of the debug adapter." (plist-get dape--capabilities :supportsRestartRequest)) (setq dape--threads nil) (setq dape--thread-id nil) - (setq dape--restart-in-progress t) - (dape-request dape--process "restart" nil - (dape--callback - (setq dape--restart-in-progress nil)))) + (dape-request dape--process "restart" nil)) ((and dape--config) (dape dape--config)) ((user-error "Unable to derive session to restart, run `dape'")))) From 2f429b57cd4eadd19eed58dc64d60e224ba7fb94 Mon Sep 17 00:00:00 2001 From: Daniel Pettersson Date: Mon, 1 Jan 2024 16:30:56 +0100 Subject: [PATCH 09/11] Revert "Rework restart-in-progress to use adapter terminate arg" This reverts commit 99ee5980101fafd46c5115ddcbe78d3beb5d86ac. --- dape.el | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dape.el b/dape.el index 43034999..c316fa11 100644 --- a/dape.el +++ b/dape.el @@ -567,6 +567,8 @@ The hook is run with one argument, the compilation buffer." "Debug adapter communications process.") (defvar dape--parent-process nil "Debug adapter parent process. Used for by startDebugging adapters.") +(defvar dape--restart-in-progress nil + "Used for prevent adapter killing when restart request is in flight.") (defvar-local dape--source nil "Store source plist in fetched source buffer.") @@ -1623,12 +1625,12 @@ Starts a new process as per request of the debug adapter." 'dape-repl-exit-code-exit 'dape-repl-exit-code-fail))) -(cl-defmethod dape-handle-event (_process (_event (eql terminated)) body) +(cl-defmethod dape-handle-event (_process (_event (eql terminated)) _body) "Handle terminated events." (dape--update-state 'terminated) (dape--remove-stack-pointers) (dape--repl-message "* Program terminated *" 'italic) - (unless (eq (plist-get :restart body) t) + (unless dape--restart-in-progress (dape-kill))) @@ -1653,6 +1655,7 @@ Starts a new process as per request of the debug adapter." dape--stack-id nil dape--source-buffers nil dape--process process + dape--restart-in-progress nil dape--repl-insert-text-guard nil) (dape--update-state 'starting) (run-hook-with-args 'dape-on-start-hooks) @@ -1797,7 +1800,10 @@ Starts a new process as per request of the debug adapter." (plist-get dape--capabilities :supportsRestartRequest)) (setq dape--threads nil) (setq dape--thread-id nil) - (dape-request dape--process "restart" nil)) + (setq dape--restart-in-progress t) + (dape-request dape--process "restart" nil + (dape--callback + (setq dape--restart-in-progress nil)))) ((and dape--config) (dape dape--config)) ((user-error "Unable to derive session to restart, run `dape'")))) From 893dbfb523d392a5ed160ae14f35cf31be456636 Mon Sep 17 00:00:00 2001 From: Daniel Pettersson Date: Mon, 1 Jan 2024 16:42:31 +0100 Subject: [PATCH 10/11] Rework terminate event --- dape.el | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/dape.el b/dape.el index c316fa11..0acac92d 100644 --- a/dape.el +++ b/dape.el @@ -1483,6 +1483,10 @@ Starts a new process to run process to be debugged." "Handle startDebugging requests. Starts a new process as per request of the debug adapter." (dape--response process (symbol-name command) seq t) + (when (process-live-p dape--parent-process) + ;; If an adapter spawns multiple child process warn + ;; TODO this should be supported but is jsonrpc is needed as an first step + (dape--debug 'error "Multiple parent process")) (setq dape--parent-process dape--process) ;; js-vscode leaves launch request un-answered (when (hash-table-p dape--timers) @@ -1625,13 +1629,17 @@ Starts a new process as per request of the debug adapter." 'dape-repl-exit-code-exit 'dape-repl-exit-code-fail))) -(cl-defmethod dape-handle-event (_process (_event (eql terminated)) _body) +(cl-defmethod dape-handle-event (process (_event (eql terminated)) body) "Handle terminated events." - (dape--update-state 'terminated) - (dape--remove-stack-pointers) - (dape--repl-message "* Program terminated *" 'italic) - (unless dape--restart-in-progress - (dape-kill))) + (if (and (process-live-p dape--parent-process) + (not (eq process dape--parent-process))) + (dape-handle-event dape--parent-process 'terminated body) + (dape--update-state 'terminated) + (dape--remove-stack-pointers) + (dape--repl-message "* Program terminated *" 'italic) + (unless (or dape--restart-in-progress + (eq (plist-get body :restart) t)) + (dape-kill)))) ;;; Startup/Setup From ce683a905ca5a66c7d5530245aba92089b7df988 Mon Sep 17 00:00:00 2001 From: Daniel Pettersson Date: Mon, 1 Jan 2024 17:48:05 +0100 Subject: [PATCH 11/11] Harden termination response --- dape.el | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dape.el b/dape.el index 0acac92d..dacf61f6 100644 --- a/dape.el +++ b/dape.el @@ -862,10 +862,10 @@ If EXTENDED end of line is after newline." (ignore-errors (and dape--process (delete-process dape--process)) - (and dape--server-process - (delete-process dape--server-process)) (and dape--parent-process - (delete-process dape--parent-process)))) + (delete-process dape--parent-process)) + (and dape--server-process + (delete-process dape--server-process)))) (defun dape--kill-buffers (&optional skip-process-buffers) "Kill all Dape related buffers. @@ -1638,7 +1638,9 @@ Starts a new process as per request of the debug adapter." (dape--remove-stack-pointers) (dape--repl-message "* Program terminated *" 'italic) (unless (or dape--restart-in-progress - (eq (plist-get body :restart) t)) + (eq (plist-get body :restart) t) + (or (eq dape--process process) + (eq dape--parent-process process))) (dape-kill))))