@@ -349,7 +349,7 @@ DEBUG-SESSION is the debug session triggering the event."
349349 [" Sessions" dap-ui-sessions]
350350 [" Locals" dap-ui-locals]
351351 [" Expressions" dap-ui-expressions]
352- [" Sources" dapui -loaded-sources]
352+ [" Sources" dap-ui -loaded-sources]
353353 [" Output" dap-go-to-output-buffer]
354354 [" Breakpoints" dap-ui-breakpoints]
355355 " ---"
@@ -1119,7 +1119,132 @@ request."
11191119(make-obsolete 'dap-ui-inspect-thing-at-point 'dap-ui-expressions-add " dap-mode 0.2" )
11201120
11211121
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 )))
11221246
1247+
11231248; ; Breakpoints - new
11241249(defvar dap-exception-breakpoints nil )
11251250
0 commit comments