|
48 | 48 | :group 'lsp-dart |
49 | 49 | :type '(repeat string)) |
50 | 50 |
|
| 51 | +(defcustom lsp-dart-dap-devtools-theme "dark" |
| 52 | + "The theme to Dart DevTools." |
| 53 | + :group 'lsp-dart |
| 54 | + :type 'string) |
| 55 | + |
| 56 | +(defcustom lsp-dart-dap-devtools-hide-options "debugger" |
| 57 | + "What to hide when openning Dart DevTools." |
| 58 | + :group 'lsp-dart |
| 59 | + :type 'string) |
| 60 | + |
| 61 | +(defconst lsp-dart-dap--devtools-buffer-name "*LSP Dart - DevTools*") |
| 62 | +(defconst lsp-dart-dap--pub-list-pacakges-buffer-name "*LSP Dart - Pub list packages*") |
| 63 | + |
51 | 64 | (defun lsp-dart-dap--setup-extension () |
52 | 65 | "Setup dart debugger extension to run `lsp-dart-dap-debugger-program`." |
53 | | - (message "DAP Dart :: Setting up...") |
| 66 | + (lsp-dart-project-log "Setting up DAP...") |
54 | 67 | (lsp-async-start-process |
55 | 68 | (lambda () |
56 | 69 | (lsp-async-start-process |
57 | | - (lambda () (message "DAP Dart :: Setup done!")) |
58 | | - (lambda () (message "DAP Dart :: Error setting up lsp-dart-dap, check if `npm` is on $PATH")) |
| 70 | + (lambda () (lsp-dart-project-log "DAP setup done!")) |
| 71 | + (lambda (_) (lsp-dart-project-log "Error setting up lsp-dart-dap, check if `npm` is on $PATH")) |
59 | 72 | (f-join lsp-dart-dap-debugger-path "extension/node_modules/typescript/bin/tsc") |
60 | 73 | "--project" (f-join lsp-dart-dap-debugger-path "extension"))) |
61 | | - (lambda () (message "DAP Dart :: Error setting up lsp-dart-dap, check if `npm` is on $PATH")) |
| 74 | + (lambda (_) (lsp-dart-project-log "Error setting up lsp-dart-dap, check if `npm` is on $PATH")) |
62 | 75 | "npm" "install" "--prefix" (f-join lsp-dart-dap-debugger-path "extension") |
63 | 76 | "--no-package-lock" "--silent" "--no-save")) |
64 | 77 |
|
|
91 | 104 | :program nil |
92 | 105 | :name "Dart::Run")) |
93 | 106 |
|
| 107 | +(cl-defmethod dap-handle-event ((_event (eql dart.debuggerUris)) _session params) |
| 108 | + "Handle debugger uris EVENT for SESSION with PARAMS." |
| 109 | + (-let* (((&hash "vmServiceUri" vm-service-uri) params)) |
| 110 | + (lsp-workspace-set-metadata "dart-debug-vm-service-uri" vm-service-uri))) |
| 111 | + |
| 112 | +(defun lsp-dart-dap--clean-buffer (buffer) |
| 113 | + "Clean BUFFER content." |
| 114 | + (when (get-buffer buffer) |
| 115 | + (with-current-buffer buffer |
| 116 | + (erase-buffer)))) |
| 117 | + |
| 118 | +(defun lsp-dart-dap--buffer-whole-string (buffer) |
| 119 | + "Return all content of BUFFER." |
| 120 | + (with-current-buffer buffer |
| 121 | + (save-restriction |
| 122 | + (widen) |
| 123 | + (buffer-substring-no-properties (point-min) (point-max))))) |
| 124 | + |
| 125 | +(defun lsp-dart-dap--check-devtools-uri (callback) |
| 126 | + "Check for uri on devtools buffer and call CALLBACK with it. |
| 127 | +If URI is not found on buffer, schedule re-check." |
| 128 | + (let ((content (lsp-dart-dap--buffer-whole-string lsp-dart-dap--devtools-buffer-name))) |
| 129 | + (if (string= content "") |
| 130 | + (run-with-idle-timer 0.3 nil #'lsp-dart-dap--check-devtools-uri callback) |
| 131 | + (-let* (((&hash "params" (&hash "host" "port")) (lsp--read-json content)) |
| 132 | + (uri (concat host ":" (number-to-string port)))) |
| 133 | + (lsp-workspace-set-metadata "dart-debug-devtools-uri" uri) |
| 134 | + (funcall callback uri))))) |
| 135 | + |
| 136 | +(defun lsp-dart-dap--devtools-activated-p () |
| 137 | + "Return non-nil if devtools is activated otherwise nil." |
| 138 | + (lsp-dart-dap--clean-buffer lsp-dart-dap--pub-list-pacakges-buffer-name) |
| 139 | + (let* ((pub (lsp-dart-project-get-pub-command)) |
| 140 | + (_proc (call-process pub |
| 141 | + nil |
| 142 | + lsp-dart-dap--pub-list-pacakges-buffer-name |
| 143 | + nil |
| 144 | + "global" "list")) |
| 145 | + (content (lsp-dart-dap--buffer-whole-string lsp-dart-dap--pub-list-pacakges-buffer-name))) |
| 146 | + (string-match-p "devtools \\([0-9]\\.[0-9]\\.[0-9]\\)" content))) |
| 147 | + |
| 148 | +(defun lsp-dart-dap--activate-devtools (callback) |
| 149 | + "Activate Dart Devtools via pub then call CALLBACK." |
| 150 | + (lsp-dart-project-log "Activating DevTools...") |
| 151 | + (let ((pub (lsp-dart-project-get-pub-command))) |
| 152 | + (lsp-async-start-process |
| 153 | + (lambda () |
| 154 | + (lsp-dart-project-log "DevTools activated successfully!") |
| 155 | + (funcall callback)) |
| 156 | + (lambda (_) (lsp-dart-project-log "Could not Activate DevTools. \ |
| 157 | +Try to activate manually running 'pub global activate devtools'")) |
| 158 | + pub "global" "activate" "devtools"))) |
| 159 | + |
| 160 | +(defun lsp-dart-dap--check-devtools-activated (callback) |
| 161 | + "Check if devtools is activated otherwise prompt for activate it. |
| 162 | +If it is already activated or after activated successfully, call CALLBACK." |
| 163 | + (if (lsp-dart-dap--devtools-activated-p) |
| 164 | + (funcall callback) |
| 165 | + (when (y-or-n-p "Dart DevTools needs to be activated with \ |
| 166 | +'pub global activate devtools' to use this feature.\nActivate DevTools? ") |
| 167 | + (lsp-dart-dap--activate-devtools callback)))) |
| 168 | + |
| 169 | +(defun lsp-dart-dap--kill-devtools-proc (proc _session) |
| 170 | + "Kill the devtools PROC process of SESSION." |
| 171 | + (lsp-workspace-set-metadata "dart-debug-devtools-uri" nil) |
| 172 | + (delete-process proc) |
| 173 | + (lsp-dart-dap--clean-buffer lsp-dart-dap--devtools-buffer-name)) |
| 174 | + |
| 175 | +(defvar-local lsp-dart-dap--check-devtools-uri-timer nil) |
| 176 | + |
| 177 | +(defun lsp-dart-dap--start-devtools (callback) |
| 178 | + "Start Dart DevTools process and call CALLBACK after started successfully." |
| 179 | + (lsp-dart-dap--check-devtools-activated |
| 180 | + (lambda () |
| 181 | + (if-let ((uri (lsp-workspace-get-metadata "dart-debug-devtools-uri"))) |
| 182 | + (funcall callback uri) |
| 183 | + (let* ((pub (lsp-dart-project-get-pub-command)) |
| 184 | + (proc (start-process "Start DevTools" |
| 185 | + lsp-dart-dap--devtools-buffer-name |
| 186 | + pub "global" "run" "devtools" |
| 187 | + "--machine" |
| 188 | + "--enable-notifications" |
| 189 | + "--try-ports" "10"))) |
| 190 | + (add-hook 'dap-terminated-hook (-partial #'lsp-dart-dap--kill-devtools-proc proc)) |
| 191 | + (when lsp-dart-dap--check-devtools-uri-timer |
| 192 | + (cancel-timer lsp-dart-dap--check-devtools-uri-timer)) |
| 193 | + (setq lsp-dart-dap--check-devtools-uri-timer |
| 194 | + (run-with-idle-timer 0.3 nil #'lsp-dart-dap--check-devtools-uri callback))))))) |
| 195 | + |
| 196 | +(defun lsp-dart-dap--open-devtools (uri vm-service-uri) |
| 197 | + "Open DevTools URI with VM-SERVICE-URI param at browser." |
| 198 | + (let* ((params (url-build-query-string `((ide Emacs) |
| 199 | + (uri ,vm-service-uri) |
| 200 | + (hide ,lsp-dart-dap-devtools-hide-options) |
| 201 | + (theme ,lsp-dart-dap-devtools-theme)))) |
| 202 | + (url (concat "http://" uri "?" params))) |
| 203 | + (browse-url url))) |
| 204 | + |
| 205 | +;;;###autoload |
| 206 | +(defun lsp-dart-dap-open-devtools () |
| 207 | + "Open Dart DevTools for the current debug session." |
| 208 | + (interactive) |
| 209 | + (let ((session (dap--cur-session)) |
| 210 | + (vm-service-uri (lsp-workspace-get-metadata "dart-debug-vm-service-uri"))) |
| 211 | + (when (and session vm-service-uri) |
| 212 | + (lsp-dart-dap--start-devtools |
| 213 | + (lambda (uri) |
| 214 | + (lsp-dart-project-log "Openning DevTools at browser...") |
| 215 | + (lsp-dart-dap--open-devtools uri vm-service-uri)))))) |
| 216 | + |
94 | 217 | (provide 'lsp-dart-dap) |
95 | 218 | ;;; lsp-dart-dap.el ends here |
0 commit comments