branch: externals/dape
commit 61ff3b61a86ae04a1dd5c74ecc04f4caaa419d7f
Author: Magiel Bruntink <magiel.brunt...@icloud.com>
Commit: GitHub <nore...@github.com>

    Added batteries for Java debugging with JDTLS + plugin. (#34)
    
    * Added batteries for Java debugging with JDTLS + plugin.
    
    * Fix typo and remove some blank lines.
    
    * Fix indentation.
    
    * Added ensure function for jdtls config.
---
 README.org | 13 +++++++++++++
 dape.el    | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/README.org b/README.org
index 45de516275..ef2a44a7bd 100644
--- a/README.org
+++ b/README.org
@@ -129,6 +129,19 @@ Install with ~gem install debug~.
 
 See https://github.com/ruby/debug for more information
 
+** Java - JDTLS with Java Debug Server plugin
+See https://github.com/eclipse-jdtls/eclipse.jdt.ls for installation of JDTLS.
+See https://github.com/microsoft/java-debug for installation of the Java Debug 
Server plugin.
+The Java config depends on Eglot running JDTLS with the plugin prior to 
starting Dape.
+Extend ~eglot-server-programs~ as follows to have JDTLS load the plugin:
+#+begin_src emacs-lisp
+  (add-to-list 'eglot-server-programs
+               `((java-mode java-ts-mode) .
+                 ("jdtls"
+                  :initializationOptions
+                  (:bundles 
["/PATH/TO/java-debug/com.microsoft.java.debug.plugin/target/com.microsoft.java.debug.plugin-VERSION.jar"]))))
+#+end_src
+
 ** Other untested adapters
 If you find a working configuration for any other debug adapter please submit 
a PR.
 
diff --git a/dape.el b/dape.el
index 6aedbc14fc..aa5435d0d5 100644
--- a/dape.el
+++ b/dape.el
@@ -226,7 +226,62 @@
      ;; rails server
      ;; bundle exec ruby foo.rb
      ;; bundle exec rake test
-     -c (lambda () (read-string "Invoke command: "))))
+     -c (lambda () (read-string "Invoke command: ")))
+    (jdtls
+     modes (java-mode java-ts-mode)
+     ensure (lambda (config)
+             (require 'eglot)
+             (let* ((target (plist-get config 'target))
+                    (target-file (cond ((functionp target) (funcall target))
+                                       ((stringp target) target))))
+               (unless target-file
+                 (error "No debug target specified"))
+               (with-current-buffer (find-file target-file)
+                 (unless (eglot-current-server)
+                   (eglot-ensure)
+                   (error "No running eglot server, starting one. Try again 
when eglot server is running"))
+                 (unless (seq-contains-p (eglot--server-capable 
:executeCommandProvider :commands)
+                                         "vscode.java.resolveClasspath")
+                   (error "jdtls instance does not bundle java-debug-server, 
please install")))))
+     fn (lambda (config)
+         (pcase-let* ((target (plist-get config 'target))
+                      (default-directory (project-root (project-current)))
+                      (server (with-current-buffer (find-file target)
+                                (eglot-current-server)))
+                      (`(,project-name ,main-class)
+                       (split-string (plist-get config 'entrypoint) ":"))
+                      (`[,module-paths ,class-paths]
+                       (eglot-execute-command server 
"vscode.java.resolveClasspath"
+                                              (vector main-class 
project-name))))
+           (thread-first config
+                         (plist-put :mainClass main-class)
+                         (plist-put :projectName project-name)
+                         (plist-put :modulePaths module-paths)
+                         (plist-put :classPaths class-paths))))
+     port (lambda () (eglot-execute-command (eglot-current-server)
+                                           "vscode.java.startDebugSession" 
nil))
+     entrypoint (lambda ()
+                 (completing-read
+                  "Main class: "
+                  (cl-map 'list
+                          (lambda (candidate)
+                            (concat (plist-get candidate :projectName) ":"
+                                    (plist-get candidate :mainClass)))
+                          (eglot-execute-command (eglot-current-server)
+                                                 "vscode.java.resolveMainClass"
+                                                 (project-name 
(project-current))))
+                  nil t))
+     target (lambda () (when (buffer-file-name)
+                        (file-relative-name (buffer-file-name)
+                                            (project-root (project-current)))))
+     :args ""
+     :stopOnEntry nil
+     :type "java"
+     :request "launch"
+     :vmArgs " -XX:+ShowCodeDetailsInExceptionMessages"
+     :console "integratedConsole"
+     :internalConsoleOptions "neverOpen"))
+
   "This variable holds the Dape configurations as an alist.
 In this alist, the car element serves as a symbol identifying each
 configuration.  Each configuration, in turn, is a property list (plist)

Reply via email to