Skip to content

Commit dd6473a

Browse files
committed
Implement support loaded sources
- added new command `dapui-loaded-sources`
1 parent 3a63be1 commit dd6473a

File tree

3 files changed

+187
-10
lines changed

3 files changed

+187
-10
lines changed

README.org

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
- [[#locals][Locals]]
2020
- [[#breakpoints][Breakpoints]]
2121
- [[#keybindings-1][Keybindings]]
22+
- [[#loaded-sources][Loaded sources]]
2223
- [[#dap-debug-repl][DAP debug REPL]]
2324
- [[#configuration][Configuration]]
2425
- [[#dap-mode-configuration][DAP mode configuration]]
@@ -27,6 +28,7 @@
2728
- [[#commands][Commands]]
2829
- [[#python][Python]]
2930
- [[#installation-1][Installation]]
31+
- [[#usage-1][Usage]]
3032
- [[#ruby][Ruby]]
3133
- [[#lldb][LLDB]]
3234
- [[#installation-2][Installation]]
@@ -39,16 +41,16 @@
3941
- [[#javascript-1][Javascript]]
4042
- [[#firefox][Firefox]]
4143
- [[#installation-4][Installation]]
42-
- [[#usage-1][Usage]]
44+
- [[#usage-2][Usage]]
4345
- [[#chrome][Chrome]]
4446
- [[#installation-5][Installation]]
45-
- [[#usage-2][Usage]]
47+
- [[#usage-3][Usage]]
4648
- [[#microsoft-edge][Microsoft Edge]]
4749
- [[#installation-6][Installation]]
48-
- [[#usage-3][Usage]]
50+
- [[#usage-4][Usage]]
4951
- [[#node][Node]]
5052
- [[#installation-7][Installation]]
51-
- [[#usage-4][Usage]]
53+
- [[#usage-5][Usage]]
5254
- [[#extending-dap-with-new-debug-servers][Extending DAP with new Debug servers]]
5355
- [[#example][Example]]
5456
- [[#links][Links]]
@@ -168,6 +170,8 @@
168170
| ~bui-list-mark~ | Mark breakpoint under point | m |
169171
| ~bui-list-unmark~ | Unmark breakpoint under point | u |
170172
| ~bui-list-unmark-all~ | Unmark breakpoint under point | U |
173+
** Loaded sources
174+
Loaded sources can be viewed by invoking ~dap-tm-loaded-sources~.
171175
** DAP debug REPL
172176
DAP provides a debug shell to execute commands when the program has hit
173177
breakpoints. The REPL has the same features as regular emacs shells (e.g.
@@ -289,7 +293,7 @@ case, define a template:
289293
#+BEGIN_SRC elisp
290294
(require 'dap-php)
291295
#+END_SRC
292-
Start debugging by selecting "PHP Run Configuration" from the ~dap-debug~ menu, issue the debug request in your
296+
Start debugging by selecting "PHP Run Configuration" from the ~dap-debug~ menu, issue the debug request in your
293297
browser by choosing the running thread (~dap-switch-thread~) and then ~dap-step-in~.
294298
** Native Debug (GDB/LLDB)
295299
Using https://github.com/WebFreak001/code-debug

dap-mode.el

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
;; Author: Ivan Yonchovski <[email protected]>
1919
;; Keywords: languages, debug
2020
;; URL: https://github.com/yyoncho/dap-mode
21-
;; Package-Requires: ((emacs "25.1") (dash "2.14.1") (lsp-mode "6.0") (dash-functional "1.2.0") (tree-mode "1.1.1.1") (bui "1.1.0") (f "0.20.0") (s "1.12.0"))
21+
;; Package-Requires: ((emacs "25.1") (dash "2.14.1") (lsp-mode "6.0") (dash-functional "1.2.0") (tree-mode "1.1.1.1") (bui "1.1.0") (f "0.20.0") (s "1.12.0") (treemacs "2.5"))
2222
;; Version: 0.3
2323

2424
;;; Commentary:
@@ -91,6 +91,11 @@ has been terminated."
9191
:type 'hook
9292
:group 'dap-mode)
9393

94+
(defcustom dap-loaded-sources-changed-hook nil
95+
"List of functions to be called after loaded sources have changed for the session."
96+
:type 'hook
97+
:group 'dap-mode)
98+
9499
(defcustom dap-session-created-hook nil
95100
"List of functions to be called after session have been created.
96101
It will be called with one argument - the created session."
@@ -170,7 +175,8 @@ The hook will be called with the session file and the new set of breakpoint loca
170175
(launch-args nil)
171176
;; The result of initialize request. It holds the server capabilities.
172177
(initialize-result nil)
173-
(error-message nil))
178+
(error-message nil)
179+
(loaded-sources nil))
174180

175181
(cl-defstruct dap--parser
176182
(waiting-for-response nil)
@@ -803,7 +809,11 @@ thread exection but the server will log message."
803809
debug-session
804810
(dap--get-breakpoints)
805811
(apply-partially #'dap--send-configuration-done debug-session)))
806-
(_ (message (format "No messages handler for %s" event-type))))))
812+
("loadedSource"
813+
(-let [(&hash "body" (&hash "source")) event]
814+
(cl-pushnew source (dap--debug-session-loaded-sources debug-session))
815+
(run-hook-with-args 'dap-loaded-sources-changed-hook debug-session)))
816+
(_ (message "No message handler for %s" event-type)))))
807817

808818
(defun dap--create-filter-function (debug-session)
809819
"Create filter function for DEBUG-SESSION."
@@ -893,8 +903,7 @@ ADAPTER-ID the id of the adapter."
893903
:launch-args launch-args
894904
:proc proc
895905
:name session-name
896-
:output-buffer (dap--create-output-buffer session-name)
897-
:workspace lsp--cur-workspace)))
906+
:output-buffer (dap--create-output-buffer session-name))))
898907
(set-process-sentinel proc
899908
(lambda (_process exit-str)
900909
(message "Debug session process exited with status: %s" exit-str)

dapui.el

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
;;; dapui.el --- DAP UI controls implemented using treemacs. -*- lexical-binding: t; -*-
2+
3+
;; Copyright (C) 2019 Ivan Yonchovski
4+
5+
;; Author: Ivan Yonchovski <[email protected]>
6+
;; Keywords: abbrev
7+
8+
;; This program is free software; you can redistribute it and/or modify
9+
;; it under the terms of the GNU General Public License as published by
10+
;; the Free Software Foundation, either version 3 of the License, or
11+
;; (at your option) any later version.
12+
13+
;; This program is distributed in the hope that it will be useful,
14+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
;; GNU General Public License for more details.
17+
18+
;; You should have received a copy of the GNU General Public License
19+
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
20+
21+
;;; Commentary:
22+
23+
;;
24+
25+
;;; Code:
26+
(require 'dash)
27+
(require 'dap-mode)
28+
(require 'cl-lib)
29+
(require 'treemacs)
30+
31+
(defvar dapui-theme "Default")
32+
33+
(defun dapui--loaded-sources-children (node)
34+
(let ((children (cl-second (treemacs-button-get node :pth))))
35+
(when (cl-first children)
36+
(->> children
37+
(dapui--group-by-map #'cl-first #'cl-rest)
38+
(-sort #'dapui--compare-source)))))
39+
40+
(defun dapui--loaded-symbols-goto-path (&rest _args)
41+
(-let* ((node (-some-> (treemacs-node-at-point)
42+
(button-get :key)))
43+
((source &as &hash "sourceReference" "path") (get-text-property 0 'source node)))
44+
(if (f-exists? path)
45+
(progn
46+
(select-window (get-lru-window nil nil t))
47+
(switch-to-buffer (find-file path)))
48+
(dap--send-message
49+
(dap--make-request "source"
50+
(list :source source
51+
:sourceReference sourceReference))
52+
(-lambda ((&hash? "body" (&hash "content")))
53+
(select-window (get-lru-window nil nil t))
54+
(switch-to-buffer (get-buffer-create path))
55+
(let ((inhibit-read-only t))
56+
(erase-buffer)
57+
(insert content)
58+
(goto-char (point-min))
59+
(setq-local buffer-file-name path)
60+
(delay-mode-hooks (set-auto-mode))
61+
(font-lock-ensure)))
62+
(dap--cur-session)))))
63+
64+
(defun dapui--loaded-sources-root ()
65+
(let ((lsp-file-truename-cache (ht)))
66+
(lsp-with-cached-filetrue-name
67+
(let ((session (dap--cur-session)))
68+
(when (dap--session-running session)
69+
(->> (dap--debug-session-loaded-sources session)
70+
(-map (-lambda ((source &as &hash "path"))
71+
(let ((parts (f-split (if (f-absolute? path)
72+
(f-relative path (lsp-workspace-root path))
73+
path))))
74+
(append (-butlast parts)
75+
(list (propertize (-last-item parts) 'source source))))))
76+
(dapui--group-by-map #'cl-first #'cl-rest)
77+
(-sort 'dapui--compare-source)))))))
78+
79+
(treemacs-define-expandable-node dap-loaded-sources-node
80+
:icon-open-form (dapui--calculate-icon (treemacs-button-get node :pth) t)
81+
:icon-closed-form (dapui--calculate-icon (treemacs-button-get node :pth) nil)
82+
:query-function (dapui--loaded-sources-children node)
83+
:ret-action 'dapui--loaded-symbols-goto-path
84+
:render-action
85+
(treemacs-render-node
86+
:icon (dapui--calculate-icon item nil)
87+
:label-form (propertize (cl-first item) 'face 'default)
88+
:state treemacs-dap-loaded-sources-node-closed-state
89+
:key-form (cl-first item)
90+
:more-properties (:pth item)))
91+
92+
(defun dapui--group-by-map (fn map-fn list)
93+
(->> list
94+
(-group-by fn)
95+
(-map (-lambda ((fst . rst))
96+
(list fst (-map map-fn rst))))))
97+
98+
(defun dapui--compare-source (left right)
99+
(if (dapui--source-is-dir? left)
100+
(or (not (dapui--source-is-dir? right))
101+
(string< (cl-first left)
102+
(cl-first right)))
103+
(not (or (dapui--source-is-dir? right)
104+
(string< (cl-first left)
105+
(cl-first right))))))
106+
107+
(defun dapui--calculate-icon (item open?)
108+
(let ((dir? (dapui--source-is-dir? item)))
109+
(concat
110+
(cond
111+
(open? "")
112+
(dir? "")
113+
(t " "))
114+
(if dir?
115+
(treemacs-get-icon-value 'dir-open nil dapui-theme)
116+
(treemacs-icon-for-file (cl-first item))))))
117+
118+
(treemacs-define-variadic-node dap-loaded-sources
119+
:query-function (dapui--loaded-sources-root)
120+
:render-action
121+
(treemacs-render-node
122+
:icon (dapui--calculate-icon item nil)
123+
:label-form (propertize (cl-first item) 'face 'default)
124+
:state treemacs-dap-loaded-sources-node-closed-state
125+
:key-form (cl-first item)
126+
:more-properties (:pth item))
127+
:root-key-form 'DAP-Loaded-Sources)
128+
129+
(defun dapui--source-is-dir? (item)
130+
(cl-first (cl-second item)))
131+
132+
(defun dapui-sources-refresh (&rest _args)
133+
(condition-case _err
134+
(let ((inhibit-read-only t))
135+
(with-current-buffer "*DAP Loaded Sources*"
136+
(treemacs-update-node '(:custom DAP-Loaded-Sources) t)))
137+
(error)))
138+
139+
(defun dapui--cleanup-sources-hook ()
140+
(remove-hook 'dap-terminated-hook 'dapui--sources-refresh)
141+
(remove-hook 'dap-session-changed-hook 'dapui--sources-refresh))
142+
143+
;;;###autoload
144+
(defun dapui-loaded-sources ()
145+
(interactive)
146+
(let* ((buffer (get-buffer-create "*DAP Loaded Sources*"))
147+
(window (display-buffer-in-side-window buffer nil)))
148+
(select-window window)
149+
(set-window-dedicated-p window t)
150+
(treemacs-initialize)
151+
(setq-local treemacs-default-visit-action 'treemacs-RET-action)
152+
(treemacs-DAP-LOADED-SOURCES-extension)
153+
154+
(add-hook 'dap-terminated-hook 'dapui--sources-refresh)
155+
(add-hook 'dap-session-changed-hook 'dapui--sources-refresh)
156+
(add-hook 'dap-loaded-sources-changed-hook 'dapui--sources-refresh)
157+
(add-hook 'kill-buffer-hook 'dapui--cleanup-sources-hook nil t)))
158+
159+
(provide 'dapui)
160+
;;; dapui.el ends here
161+
162+
;; Local Variables:
163+
;; flycheck-disabled-checkers: (emacs-lisp-checkdoc)
164+
;; End:

0 commit comments

Comments
 (0)