emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/eglot f0b5367 08/45: Per #63: Add support for eclipse.j


From: João Távora
Subject: [elpa] externals/eglot f0b5367 08/45: Per #63: Add support for eclipse.jdt.ls server
Date: Thu, 22 Nov 2018 19:15:27 -0500 (EST)

branch: externals/eglot
commit f0b5367ab36e1c5010a0ddc18c41a7d115ca87be
Author: Michał K <address@hidden>
Commit: mkcms <address@hidden>

    Per #63: Add support for eclipse.jdt.ls server
    
    * eglot.el (eglot-server-programs): Add java-mode entry.
    (eglot-eclipse-jdt): New class.
    (eglot-initialization-options): Override for eglot-eclipse-jdt.
    (eglot--eclipse-jdt-contact): New function.
---
 README.md |  2 ++
 eglot.el  | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index fc06d52..38698dd 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,7 @@ for the language of your choice. Otherwise, it prompts you to 
enter one:
 * Rust's [rls][rls]
 * Python's [pyls][pyls]
 * Ruby's [solargraph][solargraph]
+* Java's [Eclipse JDT Language Server][eclipse-jdt]
 * Bash's [bash-language-server][bash-language-server]
 * PHP's [php-language-server][php-language-server]
 * C/C++'s [ccls][ccls]  ([cquery][cquery] and [clangd][clangd] also work)
@@ -301,4 +302,5 @@ Under the hood:
 [haskell-ide-engine]: https://github.com/haskell/haskell-ide-engine
 [kotlin-language-server]: https://github.com/fwcd/KotlinLanguageServer
 [go-langserver]: https://github.com/sourcegraph/go-langserver
+[eclipse-jdt]: https://github.com/eclipse/eclipse.jdt.ls
 
diff --git a/eglot.el b/eglot.el
index 4376d3a..daae454 100644
--- a/eglot.el
+++ b/eglot.el
@@ -91,7 +91,9 @@
 language-server/bin/php-language-server.php"))
                                 (haskell-mode . ("hie-wrapper"))
                                 (kotlin-mode . ("kotlin-language-server"))
-                                (go-mode . ("go-langserver" "-mode=stdio" 
"-gocodecompletion")))
+                                (go-mode . ("go-langserver" "-mode=stdio"
+                                            "-gocodecompletion"))
+                                (java-mode . eglot--eclipse-jdt-contact))
   "How the command `eglot' guesses the server to start.
 An association list of (MAJOR-MODE . CONTACT) pairs.  MAJOR-MODE
 is a mode symbol, or a list of mode symbols.  The associated
@@ -1893,6 +1895,96 @@ If SKIP-SIGNATURE, don't try to send 
textDocument/signatureHelp."
           :progressReportFrequencyMs -1)))
 
 
+;;; eclipse-jdt-specific
+;;;
+(defclass eglot-eclipse-jdt (eglot-lsp-server) ()
+  :documentation "Eclipse's Java Development Tools Language Server.")
+
+(cl-defmethod eglot-initialization-options ((server eglot-eclipse-jdt))
+  "Passes through required jdt initialization options"
+  `(:workspaceFolders
+    [,@(cl-delete-duplicates
+        (mapcar #'eglot--path-to-uri
+                (let* ((roots (project-roots (eglot--project server)))
+                       (root (car roots)))
+                  (append
+                   roots
+                   (mapcar
+                    #'file-name-directory
+                    (append
+                     (file-expand-wildcards (concat root "*/pom.xml"))
+                     (file-expand-wildcards (concat root "*/build.gradle"))
+                     (file-expand-wildcards (concat root "*/.project")))))))
+        :test #'string=)]
+    ,@(if-let ((home (or (getenv "JAVA_HOME")
+                         (ignore-errors
+                           (expand-file-name
+                            ".."
+                            (file-name-directory
+                             (file-chase-links (executable-find "javac"))))))))
+          `(:settings (:java (:home ,home)))
+        (ignore (eglot--warn "JAVA_HOME env var not set")))))
+
+(defun eglot--eclipse-jdt-contact (interactive)
+  "Return a contact for connecting to eclipse.jdt.ls server, as a cons cell."
+  (cl-labels
+      ((is-the-jar
+        (path)
+        (and (string-match-p
+              "org\\.eclipse\\.equinox\\.launcher_.*\\.jar$"
+              (file-name-nondirectory path))
+             (file-exists-p path))))
+    (let* ((classpath (or (getenv "CLASSPATH") ":"))
+           (cp-jar (cl-find-if #'is-the-jar (split-string classpath ":")))
+           (jar cp-jar)
+           (dir
+            (cond
+             (jar (file-name-as-directory
+                   (expand-file-name ".." (file-name-directory jar))))
+             (interactive
+              (expand-file-name
+               (read-directory-name
+                (concat "Path to eclipse.jdt.ls directory (could not"
+                        " find it in CLASSPATH): ")
+                nil nil t)))
+             (t (error "Could not find eclipse.jdt.ls jar in CLASSPATH"))))
+           (repodir
+            (concat dir
+                    "org.eclipse.jdt.ls.product/target/repository/"))
+           (repodir (if (file-directory-p repodir) repodir dir))
+           (config
+            (concat
+             repodir
+             (cond
+              ((string= system-type "darwin") "config_mac")
+              ((string= system-type "windows-nt") "config_win")
+              (t "config_linux"))))
+           (workspace
+            (expand-file-name (md5 (car (project-roots (project-current))))
+                              (concat user-emacs-directory
+                                      "eglot-eclipse-jdt-cache"))))
+      (unless jar
+        (setq jar
+              (cl-find-if #'is-the-jar
+                          (directory-files (concat repodir "plugins") t))))
+      (unless (and jar (file-exists-p jar) (file-directory-p config))
+        (error "Could not find required eclipse.jdt.ls files (build 
required?)"))
+      (when (and interactive (not cp-jar)
+                 (y-or-n-p (concat "Add path to the server program "
+                                   "to CLASSPATH environment variable?")))
+        (setenv "CLASSPATH" (concat (getenv "CLASSPATH") ":" jar)))
+      (unless (file-directory-p workspace)
+        (make-directory workspace t))
+      (cons 'eglot-eclipse-jdt
+            (list (executable-find "java")
+                  "-Declipse.application=org.eclipse.jdt.ls.core.id1"
+                  "-Dosgi.bundles.defaultStartLevel=4"
+                  "-Declipse.product=org.eclipse.jdt.ls.core.product"
+                  "-jar" jar
+                  "-configuration" config
+                  "-data" workspace)))))
+
+
 ;; FIXME: A horrible hack of Flymake's insufficient API that must go
 ;; into Emacs master, or better, 26.2
 (when (version< emacs-version "27.0")



reply via email to

[Prev in Thread] Current Thread [Next in Thread]