yeet
This commit is contained in:
134
.config/emacs/modules/tools/debugger/autoload/debugger.el
Normal file
134
.config/emacs/modules/tools/debugger/autoload/debugger.el
Normal file
@@ -0,0 +1,134 @@
|
||||
;;; tools/debugger/autoload/debugger.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar-local +debugger--last-config nil
|
||||
"Configuration of the last debugging session of buffer.")
|
||||
(put '+debugger--last-config 'permanent-local t) ; don't kill on mode change
|
||||
|
||||
(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 (doom-project-p)
|
||||
(doom-store-get (doom-project-root) "+debugger")
|
||||
+debugger--last-config))
|
||||
|
||||
(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 (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 ()
|
||||
(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 ()
|
||||
(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 ()
|
||||
"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
|
||||
infromation."
|
||||
(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 (cddr 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))))))
|
||||
(cons 'dap launch-args))
|
||||
(cons 'realgud (intern (cadr configuration))))))))
|
||||
|
||||
;;
|
||||
;;; Interactive commands
|
||||
|
||||
;;;###autoload
|
||||
(defun +debugger/start-last ()
|
||||
"Relaunch the last debugger session."
|
||||
(interactive)
|
||||
(let ((configuration (+debugger--get-last-config)))
|
||||
(unless configuration
|
||||
(user-error "No last debugger%s to invoke"
|
||||
(if (doom-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)
|
||||
"Launch a debugger session.
|
||||
|
||||
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")
|
||||
(when (or arg (null (+debugger--get-last-config)))
|
||||
(+debugger--set-config (+debugger-completing-read)))
|
||||
(+debugger/start-last))
|
||||
|
||||
;;;###autoload
|
||||
(defun +debugger/quit ()
|
||||
"Quit the active debugger, if any."
|
||||
(interactive)
|
||||
(cond ((and (fboundp 'dap--cur-session) (dap--cur-session))
|
||||
(dap-disconnect (dap--cur-session)))
|
||||
((and (fboundp 'realgud-get-cmdbuf) (realgud-get-cmdbuf))
|
||||
(let ((buf (realgud-get-cmdbuf)))
|
||||
(ignore-errors
|
||||
(call-interactively #'realgud:cmd-quit))
|
||||
(let (realgud-safe-mode)
|
||||
(kill-buffer buf))))
|
||||
((user-error "No debugging session to quit"))))
|
||||
|
||||
;; TODO debugger breakpoint commands
|
||||
;; ;;;###autoload
|
||||
;; (defun +debugger/toggle-breakpoint ()
|
||||
;; (interactive)
|
||||
;; (user-error "not implemented yet"))
|
||||
|
||||
;; ;;;###autoload
|
||||
;; (defun +debugger/next-breakpoint ()
|
||||
;; (interactive)
|
||||
;; (user-error "not implemented yet"))
|
||||
|
||||
;; ;;;###autoload
|
||||
;; (defun +debugger/previous-breakpoint ()
|
||||
;; (interactive)
|
||||
;; (user-error "not implemented yet"))
|
||||
34
.config/emacs/modules/tools/debugger/autoload/evil.el
Normal file
34
.config/emacs/modules/tools/debugger/autoload/evil.el
Normal file
@@ -0,0 +1,34 @@
|
||||
;; tools/debugger/autoload/evil.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! :editor evil)
|
||||
|
||||
;;;###autoload (autoload '+debugger:start "tools/debugger/autoload/evil" nil t)
|
||||
(evil-define-command +debugger:start (&optional path)
|
||||
"Initiate debugger for current major mode"
|
||||
(interactive "<f>")
|
||||
;; TODO Add python debugging
|
||||
(let ((default-directory (doom-project-root)))
|
||||
(pcase major-mode
|
||||
((or 'c-mode 'c++-mode)
|
||||
(realgud:gdb (if path (concat "gdb " path))))
|
||||
('ruby-mode
|
||||
;; FIXME
|
||||
(doom:repl nil (format "run '%s'" (file-name-nondirectory (or path buffer-file-name)))))
|
||||
('sh-mode
|
||||
(let ((shell sh-shell))
|
||||
(when (string= shell "sh")
|
||||
(setq shell "bash"))
|
||||
(pcase shell
|
||||
("bash"
|
||||
(realgud:bashdb (if path (concat "bashdb " path))))
|
||||
("zsh"
|
||||
(realgud:zshdb (if path (concat "zshdb " path))))
|
||||
(_ (user-error "No shell debugger for %s" shell)))))
|
||||
((or 'js-mode 'js2-mode 'js3-mode)
|
||||
(realgud:trepanjs))
|
||||
('haskell-mode (haskell-debug))
|
||||
(_ (user-error "No debugger for %s" major-mode)))))
|
||||
|
||||
;;;###autoload (autoload '+debugger:toggle-breakpoint "tools/debugger/autoload/evil" nil t)
|
||||
(evil-define-command +debugger:toggle-breakpoint (&optional bang)
|
||||
(interactive "<!>")
|
||||
(call-interactively (if bang #'realgud:cmd-clear #'realgud:cmd-break)))
|
||||
160
.config/emacs/modules/tools/debugger/config.el
Normal file
160
.config/emacs/modules/tools/debugger/config.el
Normal file
@@ -0,0 +1,160 @@
|
||||
;;; tools/debugger/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +debugger--realgud-alist
|
||||
'((realgud:bashdb :modes (sh-mode))
|
||||
(realgud:gdb)
|
||||
(realgud:gub :modes (go-mode))
|
||||
(realgud:kshdb :modes (sh-mode))
|
||||
(realgud:pdb :modes (python-mode))
|
||||
(realgud:perldb :modes (perl-mode perl6-mode))
|
||||
(realgud:rdebug :modes (ruby-mode))
|
||||
(realgud:remake)
|
||||
(realgud:trepan :modes (perl-mode perl6-mode))
|
||||
(realgud:trepan2 :modes (python-mode))
|
||||
(realgud:trepan3k :modes (python-mode))
|
||||
(realgud:trepanjs :modes (javascript-mode js2-mode js3-mode))
|
||||
(realgud:trepanpl :modes (perl-mode perl6-mode raku-mode))
|
||||
(realgud:zshdb :modes (sh-mode))))
|
||||
|
||||
(defvar +debugger--dap-alist
|
||||
`(((:lang cc +lsp) :after ccls :require (dap-lldb dap-gdb-lldb))
|
||||
((:lang elixir +lsp) :after elixir-mode :require dap-elixir)
|
||||
((:lang go +lsp) :after go-mode :require dap-go)
|
||||
((:lang java +lsp) :after java-mode :require lsp-java)
|
||||
((:lang php +lsp) :after php-mode :require dap-php)
|
||||
((:lang python +lsp) :after python :require dap-python)
|
||||
((:lang ruby +lsp) :after ruby-mode :require dap-ruby)
|
||||
((:lang rust +lsp) :after rustic-mode :require (dap-lldb dap-cpptools))
|
||||
((:lang javascript +lsp)
|
||||
:after (js2-mode typescript-mode)
|
||||
:require (dap-node dap-chrome dap-firefox ,@(if IS-WINDOWS '(dap-edge)))))
|
||||
"TODO")
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
;;;###package gdb
|
||||
(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
|
||||
:init
|
||||
(use-package! realgud-trepan-ni
|
||||
:defer t
|
||||
:init (add-to-list '+debugger--realgud-alist
|
||||
'(realgud:trepan-ni :modes (javascript-mode js2-mode js3-mode)
|
||||
:package realgud-trepan-ni)))
|
||||
|
||||
;; Realgud doesn't generate its autoloads properly so we do it ourselves
|
||||
(dolist (debugger +debugger--realgud-alist)
|
||||
(autoload (car debugger)
|
||||
(if-let (sym (plist-get (cdr debugger) :package))
|
||||
(symbol-name sym)
|
||||
"realgud")
|
||||
nil t))
|
||||
|
||||
:config
|
||||
(set-popup-rule! "^\\*\\(?:trepanjs:\\(?:g\\|zsh\\|bash\\)db\\|pdb \\)"
|
||||
:size 20 :select nil :quit nil)
|
||||
|
||||
(defadvice! +debugger--cleanup-after-realgud-a (&optional buf)
|
||||
"Kill command buffer when debugging session ends (which closes its popup)."
|
||||
:after #'realgud:terminate
|
||||
(when (stringp buf)
|
||||
(setq buf (get-buffer buf)))
|
||||
(when-let (cmdbuf (realgud-get-cmdbuf buf))
|
||||
(let (kill-buffer-hook)
|
||||
(kill-buffer buf))))
|
||||
|
||||
;; Monkey-patch `realgud:run-process' to run in a popup.
|
||||
;; TODO Find a more elegant solution
|
||||
;; FIXME Causes realgud:cmd-* to focus popup on every invocation
|
||||
(defadvice! +debugger--realgud-open-in-other-window-a
|
||||
(debugger-name script-filename cmd-args minibuffer-history-var &optional no-reset)
|
||||
:override #'realgud:run-process
|
||||
(let* ((cmd-buf (apply #'realgud-exec-shell debugger-name script-filename
|
||||
(car cmd-args) no-reset (cdr cmd-args)))
|
||||
(process (get-buffer-process cmd-buf)))
|
||||
(cond ((and process (eq 'run (process-status process)))
|
||||
(pop-to-buffer cmd-buf)
|
||||
(when (boundp 'evil-emacs-state-local-map)
|
||||
(define-key evil-emacs-state-local-map (kbd "ESC ESC") #'+debugger/quit))
|
||||
(realgud:track-set-debugger debugger-name)
|
||||
(realgud-cmdbuf-info-in-debugger?= 't)
|
||||
(realgud-cmdbuf-info-cmd-args= cmd-args)
|
||||
(when cmd-buf
|
||||
(switch-to-buffer cmd-buf)
|
||||
(when realgud-cmdbuf-info
|
||||
(let* ((info realgud-cmdbuf-info)
|
||||
(cmd-args (realgud-cmdbuf-info-cmd-args info))
|
||||
(cmd-str (mapconcat #'identity cmd-args " ")))
|
||||
(if (boundp 'starting-directory)
|
||||
(realgud-cmdbuf-info-starting-directory= starting-directory))
|
||||
(set minibuffer-history-var
|
||||
(cl-remove-duplicates (cons cmd-str (eval minibuffer-history-var))
|
||||
:from-end t))))))
|
||||
(t
|
||||
(if cmd-buf (switch-to-buffer cmd-buf))
|
||||
(message "Error running command: %s" (mapconcat #'identity cmd-args " "))))
|
||||
cmd-buf)))
|
||||
|
||||
|
||||
(use-package! dap-mode
|
||||
:when (and (featurep! +lsp) (not (featurep! :tools lsp +eglot)))
|
||||
:hook (dap-mode . dap-tooltip-mode)
|
||||
:init
|
||||
(setq dap-breakpoints-file (concat doom-etc-dir "dap-breakpoints")
|
||||
dap-utils-extension-path (concat doom-etc-dir "dap-extension/"))
|
||||
(after! lsp-mode (require 'dap-mode))
|
||||
:config
|
||||
(pcase-dolist (`((,category . ,modules) :after ,after :require ,libs)
|
||||
+debugger--dap-alist)
|
||||
(when (doom-module-p category (car modules) (cadr modules))
|
||||
(dolist (lib (doom-enlist after))
|
||||
(with-eval-after-load lib
|
||||
(mapc #'require (doom-enlist libs))))))
|
||||
|
||||
(dap-mode 1)
|
||||
|
||||
(define-minor-mode +dap-running-session-mode
|
||||
"A mode for adding keybindings to running sessions"
|
||||
:init-value nil
|
||||
:keymap (make-sparse-keymap)
|
||||
(when (bound-and-true-p evil-mode)
|
||||
(evil-normalize-keymaps)) ; if you use evil, this is necessary to update the keymaps
|
||||
;; The following code adds to the dap-terminated-hook so that this minor
|
||||
;; mode will be deactivated when the debugger finishes
|
||||
(when +dap-running-session-mode
|
||||
(let ((session-at-creation (dap--cur-active-session-or-die)))
|
||||
(add-hook 'dap-terminated-hook
|
||||
(lambda (session)
|
||||
(when (eq session session-at-creation)
|
||||
(+dap-running-session-mode -1)))))))
|
||||
|
||||
;; Activate this minor mode when dap is initialized
|
||||
(add-hook 'dap-session-created-hook #'+dap-running-session-mode)
|
||||
;; Activate this minor mode when hitting a breakpoint in another file
|
||||
(add-hook 'dap-stopped-hook #'+dap-running-session-mode)
|
||||
;; Activate this minor mode when stepping into code in another file
|
||||
(add-hook 'dap-stack-frame-changed-hook (lambda (session)
|
||||
(when (dap--session-running session)
|
||||
(+dap-running-session-mode 1))))
|
||||
|
||||
(map! :localleader
|
||||
:map +dap-running-session-mode-map
|
||||
"d" #'dap-hydra))
|
||||
|
||||
|
||||
(use-package! dap-ui
|
||||
:when (featurep! +lsp)
|
||||
:hook (dap-mode . dap-ui-mode)
|
||||
:hook (dap-ui-mode . dap-ui-controls-mode))
|
||||
4
.config/emacs/modules/tools/debugger/doctor.el
Normal file
4
.config/emacs/modules/tools/debugger/doctor.el
Normal file
@@ -0,0 +1,4 @@
|
||||
;;; tools/debugger/doctor.el -*- lexical-binding: t; -*-
|
||||
|
||||
(when (and (featurep! +lsp) (featurep! :tools lsp +eglot))
|
||||
(warn! "+lsp flag is not compatible with :tools (lsp +eglot). Choose only one of (eglot or dap-mode) please"))
|
||||
10
.config/emacs/modules/tools/debugger/packages.el
Normal file
10
.config/emacs/modules/tools/debugger/packages.el
Normal file
@@ -0,0 +1,10 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/debugger/packages.el
|
||||
|
||||
(when (package! realgud :pin "3c88611c4ed59069093187c2a039b8d05cbe53e8")
|
||||
(when (featurep! :lang javascript)
|
||||
(package! realgud-trepan-ni :pin "0ec088ea343835e24ae73da09bea96bfb02a3130")))
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(package! dap-mode :pin "76cad34de8984f57c2b1e374e9c985cc7ec8dad0")
|
||||
(package! posframe :pin "6c0e63d6b3b6638c11729c5db28019a38ff44f5b"))
|
||||
Reference in New Issue
Block a user