Handling wildcards in paths


My recent experiments with Eglot and Java led me to figure out how to speed up the connection to Eclipse JDT Language Server. Basically I wanted a simpler version of eglot--eclipse-jdt-contact to avoid any prompt and just do the right thing for me.

Looking at Eglot’s bug tracker, there is an issue with some tips: #424. I followed the instructions and added the relevant code to my init.el:

(with-eval-after-load 'eglot
  (defconst mu-jdt-launcher
    (concat "/home/manuel/jdt/plugins"
            "/org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar"))

  (defun mu-eglot-jdt-contact (_interactive)
    "See `eglot--eclipse-jdt-contact'."
    (let ((cp (or (getenv "CLASSPATH") path-separator)))
      (setenv "CLASSPATH" (concat cp path-separator mu-jdt-launcher))
      (unwind-protect (eglot--eclipse-jdt-contact nil)
        (setenv "CLASSPATH" cp))))
  (setcdr (assq 'java-mode eglot-server-programs) #'mu-eglot-jdt-contact))

However, I do not like the hard-coded path to the JDT jar file, mainly because I have to manually update it every time I install a new version of the language server. Fortunately, Emacs has what I need right under the hood: file-expand-wildcards.

(defconst mu-jdt-launcher
  (let ((path "~/jdt/plugins/org.eclipse.equinox.launcher_*"))
    (car (file-expand-wildcards path 'full))))

If you check the documentation of file-expand-wildcards you will notice that it returns a list of file names matching the given pattern. In this case, there is only one element in that list, so car can safely grab it. Again, the documentation will also explain the meaning of that 'full argument, but I am sure it is pretty clear already.