From 6de1e56d4f25ec553ef2822edc0fb6e7aa933ad1 Mon Sep 17 00:00:00 2001 From: Henrik Laxhuber Date: Sun, 28 Feb 2021 22:13:24 +0100 Subject: [PATCH 1/6] Fix `+debug/start` for dap-based debuggers. Reworks the internals of how the debugger module stores the last-used configuration: - car of the configuration indicates whether it is a realgud or a dap-based configuration. - For dap-based debuggers, the entire dap configuration is stored, with code copied from `dab-debug`. - When inside a project, don't store the configuration as a buffer-local variable, but instead as a project-local variable using `projectile-variable`. Fixes #2367. --- modules/tools/debugger/autoload/debugger.el | 99 +++++++++++++++------ modules/tools/debugger/packages.el | 2 + 2 files changed, 74 insertions(+), 27 deletions(-) diff --git a/modules/tools/debugger/autoload/debugger.el b/modules/tools/debugger/autoload/debugger.el index 73394337c..4be0cc54e 100644 --- a/modules/tools/debugger/autoload/debugger.el +++ b/modules/tools/debugger/autoload/debugger.el @@ -1,28 +1,70 @@ ;;; tools/debugger/autoload/debugger.el -*- lexical-binding: t; -*- -(defvar +debugger--last nil) +(defvar +debugger-last-configuration nil + "Configuration of the last debugging session of buffer.") +(make-variable-buffer-local '+debugger-last-configuration) + +(defun +debugger-get-configuration () + "Get last debugging configuration. + +If in a project, returns the configuration of the last debugging session in the +project, if any. Else, returns the last debugging configuration of the current +buffer, if any." + (if (projectile-project-p) + (projectile-variable-get '+debugger-last-configuration) + +debugger-last-configuration)) + +(defun +debugger-set-configuration (configuration) + "Set the debugging configuration. + +If in a project, sets the project's debugging session configuration. Else, sets +the debugging configuration of the current buffer." + (if (projectile-project-p) + (projectile-variable-put '+debugger-last-configuration configuration) + (setq-local +debugger-last-configuration configuration))) (defun +debugger-list-for-dap () (when (and (bound-and-true-p lsp-mode) (bound-and-true-p lsp--buffer-deferred) (require 'dap-mode nil t) dap-mode) - (mapcar #'car dap-debug-template-configurations))) + (--map (cons 'dap it) + (-mapcat #'funcall dap-launch-configuration-providers)))) (defun +debugger-list-for-realgud () - (cl-loop for (sym . plist) in +debugger--realgud-alist - for sym-name = (symbol-name sym) - for modes = (plist-get plist :modes) - if (or (null modes) (apply #'derived-mode-p modes)) - collect sym)) + (--map (cons 'realgud (list (symbol-name it))) + (cl-loop for (sym . plist) in +debugger--realgud-alist + for sym-name = (symbol-name sym) + for modes = (plist-get plist :modes) + if (or (null modes) (apply #'derived-mode-p modes)) + collect sym))) +;; Based on dap--completing-read and dap-debug +(defun +debugger-completing-read () + "Completing read for debug configuration. -(defun +debugger-list-available () - "TODO" - (append (+debugger-list-for-dap) - (+debugger-list-for-realgud) - nil)) - +Presents both dap and realgud configurations, and returns a list of the form +('dap ...) or ('realgud ...) containing the corresponding debug configuration +infromation." + (let* ((configurations (append + (+debugger-list-for-dap) + (+debugger-list-for-realgud))) + (result (--map (cons (cadr it) it) configurations)) + (completion (completing-read "Start debugger: " (-map 'car result) nil t )) + (configuration (cdr (assoc completion result)))) + (if (eq (car configuration) 'dap) + (let* ((debug-args (-> (cdr configuration) + cl-rest + copy-tree + dap-variables-expand-in-launch-configuration)) + (launch-args (or (-some-> (plist-get debug-args :type) + (gethash dap--debug-providers) + (funcall debug-args)) + (user-error "Have you loaded the `%s' specific dap package?" + (or (plist-get debug-args :type) + (user-error "%s does not specify :type" debug-args)))))) + (cons 'dap launch-args)) + (cons 'realgud (intern (cadr configuration)))))) ;; ;;; Interactive commands @@ -31,9 +73,20 @@ (defun +debugger/start-last () "Relaunch the last debugger session." (interactive) - (unless +debugger--last - (user-error "No last debugger to invoke")) - (call-interactively +debugger--last)) + (let ((configuration (+debugger-get-configuration))) + (unless configuration + (user-error "No last debugger%s to invoke" + (if (projectile-project-p) + " of this project" + ""))) + (let ((launch-args (cdr configuration))) + (if (eq (car configuration) 'dap) + ;; start dap configuration + (if (functionp launch-args) + (funcall launch-args #'dap-start-debugging-noexpand) + (dap-start-debugging-noexpand launch-args)) + ;; else start realgud configuration: + (call-interactively launch-args))))) ;;;###autoload (defun +debugger/start (arg) @@ -42,17 +95,9 @@ Launches the last used debugger, if one exists. Otherwise, you will be prompted for what debugger to use. If the prefix ARG is set, prompt anyway." (interactive "P") - (if (or arg (null +debugger--last)) - (let ((debugger (intern-soft (completing-read "Start debugger: " (+debugger-list-available))))) - (unless debugger - (user-error "No debugging session to quit")) - (unless (fboundp debugger) - (user-error "Couldn't find debugger backend %S" debugger)) - (setq-local +debugger--last debugger) - (if (assoc debugger dap-debug-template-configurations) - (dap-debug debugger) - (call-interactively debugger))) - (+debugger/start-last))) + (if (or arg (null (+debugger-get-configuration))) + (+debugger-set-configuration (+debugger-completing-read))) + (+debugger/start-last)) ;;;###autoload (defun +debugger/quit () diff --git a/modules/tools/debugger/packages.el b/modules/tools/debugger/packages.el index 9b6e580a0..7dd754a00 100644 --- a/modules/tools/debugger/packages.el +++ b/modules/tools/debugger/packages.el @@ -5,6 +5,8 @@ (when (featurep! :lang javascript) (package! realgud-trepan-ni :pin "6e38cf838c7b47b5f1353d00901b939ffa36d707"))) +(package! projectile-variable :pin "8d348ac70bdd6dc320c13a12941b32b38140e264") + (when (featurep! +lsp) (package! dap-mode :pin "aa15b9c49b7e09bb23f9a4ff7855122f0eb19976") (package! posframe :pin "3454a4cb9d218c38f9c5b88798dfb2f7f85ad936")) From 8c33866b216546a57c1edbe6aeb78d4a250f2ee6 Mon Sep 17 00:00:00 2001 From: Henrik Laxhuber Date: Sun, 28 Feb 2021 23:07:27 +0100 Subject: [PATCH 2/6] Forgot to add use-package! for projectile-variable --- modules/tools/debugger/config.el | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/tools/debugger/config.el b/modules/tools/debugger/config.el index bccd09baf..df4ed6c45 100644 --- a/modules/tools/debugger/config.el +++ b/modules/tools/debugger/config.el @@ -38,6 +38,12 @@ (setq gdb-show-main t gdb-many-windows t) +(use-package! projectile-variable + :defer t + :commands (projectile-variable-put + projectile-variable-get + projectile-variable-alist + projectile-variable-plist)) (use-package! realgud :defer t From cf3d9eb6e0c8fec5972269cba87d598734402eec Mon Sep 17 00:00:00 2001 From: Henrik Laxhuber Date: Sun, 28 Feb 2021 23:18:19 +0100 Subject: [PATCH 3/6] Handle empty input in +debugger-completing-read --- modules/tools/debugger/autoload/debugger.el | 33 +++++++++++---------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/modules/tools/debugger/autoload/debugger.el b/modules/tools/debugger/autoload/debugger.el index 4be0cc54e..00fa108f4 100644 --- a/modules/tools/debugger/autoload/debugger.el +++ b/modules/tools/debugger/autoload/debugger.el @@ -50,21 +50,24 @@ infromation." (+debugger-list-for-dap) (+debugger-list-for-realgud))) (result (--map (cons (cadr it) it) configurations)) - (completion (completing-read "Start debugger: " (-map 'car result) nil t )) - (configuration (cdr (assoc completion result)))) - (if (eq (car configuration) 'dap) - (let* ((debug-args (-> (cdr configuration) - cl-rest - copy-tree - dap-variables-expand-in-launch-configuration)) - (launch-args (or (-some-> (plist-get debug-args :type) - (gethash dap--debug-providers) - (funcall debug-args)) - (user-error "Have you loaded the `%s' specific dap package?" - (or (plist-get debug-args :type) - (user-error "%s does not specify :type" debug-args)))))) - (cons 'dap launch-args)) - (cons 'realgud (intern (cadr configuration)))))) + (completion (completing-read "Start debugger: " (-map 'car result) nil t))) + (if (eq completion "") + (user-error "No debugging configuration specified.") + (let ((configuration (cdr (assoc completion result)))) + (if (eq (car configuration) 'dap) + ;; get dap debugging arguments + (let* ((debug-args (-> (cdr configuration) + cl-rest + copy-tree + dap-variables-expand-in-launch-configuration)) + (launch-args (or (-some-> (plist-get debug-args :type) + (gethash dap--debug-providers) + (funcall debug-args)) + (user-error "Have you loaded the `%s' specific dap package?" + (or (plist-get debug-args :type) + (user-error "%s does not specify :type" debug-args)))))) + (cons 'dap launch-args)) + (cons 'realgud (intern (cadr configuration)))))))) ;; ;;; Interactive commands From 462efded5ff6c97a1b0447759b6e217e0e1425a4 Mon Sep 17 00:00:00 2001 From: Henrik Laxhuber Date: Mon, 1 Mar 2021 09:15:06 +0100 Subject: [PATCH 4/6] Fix +debugger/quit --- modules/tools/debugger/autoload/debugger.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tools/debugger/autoload/debugger.el b/modules/tools/debugger/autoload/debugger.el index 00fa108f4..832ab6e6d 100644 --- a/modules/tools/debugger/autoload/debugger.el +++ b/modules/tools/debugger/autoload/debugger.el @@ -107,7 +107,7 @@ for what debugger to use. If the prefix ARG is set, prompt anyway." "Quit the active debugger, if any." (interactive) (cond ((and (fboundp 'dap--cur-session) (dap--cur-session)) - (dap-disconnect)) + (dap-disconnect (dap--cur-session))) ((and (fboundp 'realgud-get-cmdbuf) (realgud-get-cmdbuf)) (let ((buf (realgud-get-cmdbuf))) (ignore-errors From 44803038b20a3a6e01a3ceffef721d5669735c0a Mon Sep 17 00:00:00 2001 From: Henrik Laxhuber Date: Mon, 1 Mar 2021 09:15:26 +0100 Subject: [PATCH 5/6] Remove dash dependency --- modules/tools/debugger/autoload/debugger.el | 37 +++++++++++---------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/modules/tools/debugger/autoload/debugger.el b/modules/tools/debugger/autoload/debugger.el index 832ab6e6d..db42b3aae 100644 --- a/modules/tools/debugger/autoload/debugger.el +++ b/modules/tools/debugger/autoload/debugger.el @@ -28,16 +28,16 @@ the debugging configuration of the current buffer." (bound-and-true-p lsp--buffer-deferred) (require 'dap-mode nil t) dap-mode) - (--map (cons 'dap it) - (-mapcat #'funcall dap-launch-configuration-providers)))) + (mapcar (lambda (c) (cons 'dap c)) + (apply 'append (mapcar #'funcall dap-launch-configuration-providers))))) (defun +debugger-list-for-realgud () - (--map (cons 'realgud (list (symbol-name it))) - (cl-loop for (sym . plist) in +debugger--realgud-alist - for sym-name = (symbol-name sym) - for modes = (plist-get plist :modes) - if (or (null modes) (apply #'derived-mode-p modes)) - collect sym))) + (mapcar (lambda (c) (cons 'realgud (list (symbol-name c)))) + (cl-loop for (sym . plist) in +debugger--realgud-alist + for sym-name = (symbol-name sym) + for modes = (plist-get plist :modes) + if (or (null modes) (apply #'derived-mode-p modes)) + collect sym))) ;; Based on dap--completing-read and dap-debug (defun +debugger-completing-read () @@ -49,20 +49,21 @@ infromation." (let* ((configurations (append (+debugger-list-for-dap) (+debugger-list-for-realgud))) - (result (--map (cons (cadr it) it) configurations)) - (completion (completing-read "Start debugger: " (-map 'car result) nil t))) - (if (eq completion "") + (result (mapcar (lambda (c) (cons (cadr c) c)) configurations)) + (completion (completing-read "Start debugger: " (mapcar 'car result) nil t))) + (if (or (null completion) (eq completion "")) (user-error "No debugging configuration specified.") (let ((configuration (cdr (assoc completion result)))) (if (eq (car configuration) 'dap) ;; get dap debugging arguments - (let* ((debug-args (-> (cdr configuration) - cl-rest - copy-tree - dap-variables-expand-in-launch-configuration)) - (launch-args (or (-some-> (plist-get debug-args :type) - (gethash dap--debug-providers) - (funcall debug-args)) + (let* ((debug-args (dap-variables-expand-in-launch-configuration (copy-tree + (cl-rest + (cdr configuration))))) + (launch-args (or (catch 'is-nil + (funcall (or (gethash + (or (plist-get debug-args :type) + (throw 'is-nil nil)) dap--debug-providers) + (throw 'is-nil nil)) debug-args)) (user-error "Have you loaded the `%s' specific dap package?" (or (plist-get debug-args :type) (user-error "%s does not specify :type" debug-args)))))) From cf086d08fa130f0f961f08864f40b3fa827d3bcc Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 5 Mar 2021 18:58:18 -0500 Subject: [PATCH 6/6] Minor refactor & use doom-store-* API + Fixes a shallow comparison error (eq cannot compare strings). + Uses the doom-store-* API rather than pull in a new dependency to manage project-local variables. --- modules/tools/debugger/autoload/debugger.el | 66 ++++++++++----------- modules/tools/debugger/packages.el | 2 - 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/modules/tools/debugger/autoload/debugger.el b/modules/tools/debugger/autoload/debugger.el index db42b3aae..ab6c96e1c 100644 --- a/modules/tools/debugger/autoload/debugger.el +++ b/modules/tools/debugger/autoload/debugger.el @@ -1,37 +1,39 @@ ;;; tools/debugger/autoload/debugger.el -*- lexical-binding: t; -*- -(defvar +debugger-last-configuration nil +(defvar-local +debugger--last-config nil "Configuration of the last debugging session of buffer.") -(make-variable-buffer-local '+debugger-last-configuration) +(put '+debugger--last-config 'permanent-local t) ; don't kill on mode change -(defun +debugger-get-configuration () +(defun +debugger--get-last-config () "Get last debugging configuration. If in a project, returns the configuration of the last debugging session in the project, if any. Else, returns the last debugging configuration of the current buffer, if any." - (if (projectile-project-p) - (projectile-variable-get '+debugger-last-configuration) - +debugger-last-configuration)) + (if (doom-project-p) + (doom-store-get (doom-project-root) "+debugger") + +debugger--last-config)) -(defun +debugger-set-configuration (configuration) - "Set the debugging configuration. +(defun +debugger--set-config (config) + "Remember this debugging configuration for `+debugger/start-last'. If in a project, sets the project's debugging session configuration. Else, sets the debugging configuration of the current buffer." - (if (projectile-project-p) - (projectile-variable-put '+debugger-last-configuration configuration) - (setq-local +debugger-last-configuration configuration))) + (if (doom-project-p) + (doom-store-put (doom-project-root) config + (lambda (key _cfg) (file-directory-p key)) + "+debugger") + (setq +debugger--last-config config))) -(defun +debugger-list-for-dap () - (when (and (bound-and-true-p lsp-mode) - (bound-and-true-p lsp--buffer-deferred) - (require 'dap-mode nil t) - dap-mode) - (mapcar (lambda (c) (cons 'dap c)) - (apply 'append (mapcar #'funcall dap-launch-configuration-providers))))) +(defun +debugger--list-for-dap () + (and (or (bound-and-true-p lsp-mode) + (bound-and-true-p lsp--buffer-deferred)) + (require 'dap-mode nil t) + dap-mode + (mapcar (lambda (c) (cons 'dap c)) + (apply #'append (mapcar #'funcall dap-launch-configuration-providers))))) -(defun +debugger-list-for-realgud () +(defun +debugger--list-for-realgud () (mapcar (lambda (c) (cons 'realgud (list (symbol-name c)))) (cl-loop for (sym . plist) in +debugger--realgud-alist for sym-name = (symbol-name sym) @@ -44,21 +46,19 @@ the debugging configuration of the current buffer." "Completing read for debug configuration. Presents both dap and realgud configurations, and returns a list of the form -('dap ...) or ('realgud ...) containing the corresponding debug configuration +\('dap ...) or ('realgud ...) containing the corresponding debug configuration infromation." - (let* ((configurations (append - (+debugger-list-for-dap) - (+debugger-list-for-realgud))) - (result (mapcar (lambda (c) (cons (cadr c) c)) configurations)) - (completion (completing-read "Start debugger: " (mapcar 'car result) nil t))) - (if (or (null completion) (eq completion "")) + (let ((result (mapcar (lambda (c) (cons (cadr c) c)) + (append (+debugger--list-for-dap) + (+debugger--list-for-realgud)))) + (completion (completing-read "Start debugger: " (mapcar #'car result) nil t))) + (if (or (null completion) (string-empty-p completion)) (user-error "No debugging configuration specified.") (let ((configuration (cdr (assoc completion result)))) (if (eq (car configuration) 'dap) ;; get dap debugging arguments - (let* ((debug-args (dap-variables-expand-in-launch-configuration (copy-tree - (cl-rest - (cdr configuration))))) + (let* ((debug-args (dap-variables-expand-in-launch-configuration + (copy-tree (cddr configuration)))) (launch-args (or (catch 'is-nil (funcall (or (gethash (or (plist-get debug-args :type) @@ -77,10 +77,10 @@ infromation." (defun +debugger/start-last () "Relaunch the last debugger session." (interactive) - (let ((configuration (+debugger-get-configuration))) + (let ((configuration (+debugger--get-last-config))) (unless configuration (user-error "No last debugger%s to invoke" - (if (projectile-project-p) + (if (doom-project-p) " of this project" ""))) (let ((launch-args (cdr configuration))) @@ -99,8 +99,8 @@ infromation." Launches the last used debugger, if one exists. Otherwise, you will be prompted for what debugger to use. If the prefix ARG is set, prompt anyway." (interactive "P") - (if (or arg (null (+debugger-get-configuration))) - (+debugger-set-configuration (+debugger-completing-read))) + (when (or arg (null (+debugger--get-last-config))) + (+debugger--set-config (+debugger-completing-read))) (+debugger/start-last)) ;;;###autoload diff --git a/modules/tools/debugger/packages.el b/modules/tools/debugger/packages.el index 7dd754a00..9b6e580a0 100644 --- a/modules/tools/debugger/packages.el +++ b/modules/tools/debugger/packages.el @@ -5,8 +5,6 @@ (when (featurep! :lang javascript) (package! realgud-trepan-ni :pin "6e38cf838c7b47b5f1353d00901b939ffa36d707"))) -(package! projectile-variable :pin "8d348ac70bdd6dc320c13a12941b32b38140e264") - (when (featurep! +lsp) (package! dap-mode :pin "aa15b9c49b7e09bb23f9a4ff7855122f0eb19976") (package! posframe :pin "3454a4cb9d218c38f9c5b88798dfb2f7f85ad936"))