@@ -349,7 +349,7 @@ DEBUG-SESSION is the debug session triggering the event."
349
349
[" Sessions" dap-ui-sessions]
350
350
[" Locals" dap-ui-locals]
351
351
[" Expressions" dap-ui-expressions]
352
- [" Sources" dapui -loaded-sources]
352
+ [" Sources" dap-ui -loaded-sources]
353
353
[" Output" dap-go-to-output-buffer]
354
354
[" Breakpoints" dap-ui-breakpoints]
355
355
" ---"
@@ -1119,7 +1119,132 @@ request."
1119
1119
(make-obsolete 'dap-ui-inspect-thing-at-point 'dap-ui-expressions-add " dap-mode 0.2" )
1120
1120
1121
1121
1122
+ ; ; Loaded sources
1123
+ (defun dap-ui--loaded-sources-children (item )
1124
+ (let ((children (cl-second item)))
1125
+ (when (cl-first children)
1126
+ (->> children
1127
+ (dap-ui--sources-group-by-map #'cl-first #'cl-rest )
1128
+ (-sort #'dap-ui--compare-source )))))
1129
+
1130
+ (defun dap-ui--loaded-symbols-goto-path (&rest _args )
1131
+ (-let* ((node (-some-> (treemacs-node-at-point)
1132
+ (button-get :key )))
1133
+ ((source &as &hash " sourceReference" " path" ) (get-text-property 0 'source node)))
1134
+ (if (f-exists? path)
1135
+ (progn
1136
+ (select-window (get-lru-window nil nil t ))
1137
+ (switch-to-buffer (find-file path)))
1138
+ (dap--send-message
1139
+ (dap--make-request " source"
1140
+ (list :source source
1141
+ :sourceReference sourceReference))
1142
+ (-lambda ((&hash? " body" (&hash " content" )))
1143
+ (select-window (get-lru-window nil nil t ))
1144
+ (switch-to-buffer (get-buffer-create path))
1145
+ (let ((inhibit-read-only t ))
1146
+ (erase-buffer )
1147
+ (insert content)
1148
+ (goto-char (point-min ))
1149
+ (setq-local buffer-file-name path)
1150
+ (delay-mode-hooks (set-auto-mode ))
1151
+ (font-lock-ensure )))
1152
+ (dap--cur-session)))))
1153
+
1154
+ (defun dap-ui--loaded-sources-root ()
1155
+ (let ((lsp-file-truename-cache (ht)))
1156
+ (lsp-with-cached-filetrue-name
1157
+ (let ((session (dap--cur-session)))
1158
+ (when (dap--session-running session)
1159
+ (->> (dap--debug-session-loaded-sources session)
1160
+ (-filter (-lambda ((source &as &hash " path" )) path))
1161
+ (-map (-lambda ((source &as &hash " path" ))
1162
+ (let ((parts (f-split (if (f-absolute? path)
1163
+ (let ((relativized (f-relative path (lsp-workspace-root path))))
1164
+ (if (string-prefix-p " .." relativized) ; do not relativize paths outside the workspace
1165
+ path
1166
+ relativized))
1167
+ path))))
1168
+ (append (-butlast parts)
1169
+ (list (propertize (-last-item parts) 'source source ))))))
1170
+ (dap-ui--sources-group-by-map #'cl-first #'cl-rest )
1171
+ (-sort 'dap-ui--compare-source )))))))
1172
+
1173
+ (treemacs-define-variadic-entry-node-type dap-loaded-sources
1174
+ :key 'DAP-Loaded-Sources
1175
+ :label (propertize " DAP-Loaded-Sources" 'face 'font-lock-keyword-face )
1176
+ :open-icon (dap-ui--calculate-sources-icon item t )
1177
+ :closed-icon (dap-ui--calculate-sources-icon item nil )
1178
+ :children (dap-ui--loaded-sources-root)
1179
+ :child-type 'dap-loaded-sources-node
1180
+ :more-properties `(:pth , item ))
1181
+
1182
+ (treemacs-define-expandable-node-type dap-loaded-sources-node
1183
+ :open-icon (dap-ui--calculate-sources-icon item t )
1184
+ :closed-icon (dap-ui--calculate-sources-icon item nil )
1185
+ :label (propertize (cl-first item) 'face 'default )
1186
+ :key (cl-first item)
1187
+ :children (dap-ui--loaded-sources-children (treemacs-button-get btn :pth ))
1188
+ :child-type 'dap-loaded-sources-node
1189
+ :more-properties `(:pth , item )
1190
+ :ret-action 'dap-ui--loaded-symbols-goto-path )
1191
+
1192
+ (defun dap-ui--sources-group-by-map (fn map-fn list )
1193
+ (->> list
1194
+ (-group-by fn)
1195
+ (-map (-lambda ((fst . rst))
1196
+ (list fst (-map map-fn rst))))))
1197
+
1198
+ (defun dap-ui--compare-source (left right )
1199
+ (if (dap-ui--source-is-dir? left)
1200
+ (or (not (dap-ui--source-is-dir? right))
1201
+ (string< (cl-first left)
1202
+ (cl-first right)))
1203
+ (not (or (dap-ui--source-is-dir? right)
1204
+ (string< (cl-first left)
1205
+ (cl-first right))))))
1206
+
1207
+ (defun dap-ui--calculate-sources-icon (item open? )
1208
+ (let ((dir? (dap-ui--source-is-dir? item)))
1209
+ (concat
1210
+ (cond
1211
+ ((and dir? open?) " ▾ " )
1212
+ (dir? " ▸ " )
1213
+ (t " " ))
1214
+ (if dir?
1215
+ (treemacs-get-icon-value 'dir-open )
1216
+ (treemacs-icon-for-file (cl-first item))))))
1217
+
1218
+
1219
+ (defun dap-ui--source-is-dir? (item )
1220
+ (cl-first (cl-second item)))
1221
+
1222
+ (defun dap-ui-sources-refresh (&rest _args )
1223
+ (condition-case _err
1224
+ (let ((inhibit-read-only t ))
1225
+ (with-current-buffer " *DAP Loaded Sources*"
1226
+ (treemacs-update-node 'DAP-Loaded-Sources t )))
1227
+ (error )))
1228
+
1229
+ (defun dap-ui--cleanup-sources-hook ()
1230
+ (remove-hook 'dap-terminated-hook 'dap-ui-sources-refresh )
1231
+ (remove-hook 'dap-session-changed-hook 'dap-ui-sources-refresh ))
1232
+
1233
+ ;;;### autoload
1234
+ (defun dap-ui-loaded-sources ()
1235
+ (interactive )
1236
+ (let* ((buffer (get-buffer-create " *DAP Loaded Sources*" ))
1237
+ (window (display-buffer-in-side-window buffer nil )))
1238
+ (select-window window)
1239
+ (set-window-dedicated-p window t )
1240
+ (treemacs-initialize dap-loaded-sources
1241
+ :and-do (setf treemacs-space-between-root-nodes t ))
1242
+ (add-hook 'dap-terminated-hook 'dap-ui-sources-refresh )
1243
+ (add-hook 'dap-session-changed-hook 'dap-ui-sources-refresh )
1244
+ (add-hook 'dap-loaded-sources-changed-hook 'dap-ui-sources-refresh )
1245
+ (add-hook 'kill-buffer-hook 'dap-ui--cleanup-sources-hook nil t )))
1122
1246
1247
+
1123
1248
; ; Breakpoints - new
1124
1249
(defvar dap-exception-breakpoints nil )
1125
1250
0 commit comments