From 936034d0e72621815584680a9e75f44a4448ba9d Mon Sep 17 00:00:00 2001 From: dannyfreeman Date: Thu, 3 Nov 2022 09:39:16 -0400 Subject: [PATCH 1/2] Only handle file:// type URIs in eglot explicitly (Bug#58790) This issue originated with clojure-lsp sending clients "jar": type URIs that emacs is unable to handle out of the box. Before this change, jar: URIs were parsed once, but since jar: URIs contain a nested URI, this resulted in a file being dispatched with a partially parsed path that looked like `file://path/to.jar!/path/in/jar`. Now eglot will not attempt to parse URIs that are not file:// type at all, instead let file-name-handler-alist entries to deal with them. Not parsing them at all allows the file-name-handler-alist regexps to identify them more accurately. By also checking if eglot received a URI in eglot--path-to-uri, the file-name-handler-alist can provide the non-file type URI back to the lsp server, which presumably will know how to handle them since it is also giving them out to clients. --- lisp/progmodes/eglot.el | 42 ++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 204121045a..b272d370ab 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -1496,29 +1496,37 @@ eglot--uri-path-allowed-chars (defun eglot--path-to-uri (path) "URIfy PATH." (let ((truepath (file-truename path))) - (concat "file://" - ;; Add a leading "/" for local MS Windows-style paths. - (if (and (eq system-type 'windows-nt) - (not (file-remote-p truepath))) - "/") - (url-hexify-string - ;; Again watch out for trampy paths. - (directory-file-name (file-local-name truepath)) - eglot--uri-path-allowed-chars)))) + (if (url-type (url-generic-parse-url truepath)) + ;; Path is already a URI, forward it to the lsp server untouched + truepath + (concat "file://" + ;; Add a leading "/" for local MS Windows-style paths. + (if (and (eq system-type 'windows-nt) + (not (file-remote-p truepath))) + "/") + (url-hexify-string + ;; Again watch out for trampy paths. + (directory-file-name (file-local-name truepath)) + eglot--uri-path-allowed-chars))))) (defun eglot--uri-to-path (uri) "Convert URI to file path, helped by `eglot--current-server'." (when (keywordp uri) (setq uri (substring (symbol-name uri) 1))) (let* ((server (eglot-current-server)) (remote-prefix (and server (eglot--trampish-p server))) - (retval (url-unhex-string (url-filename (url-generic-parse-url uri)))) - ;; Remove the leading "/" for local MS Windows-style paths. - (normalized (if (and (not remote-prefix) - (eq system-type 'windows-nt) - (cl-plusp (length retval))) - (substring retval 1) - retval))) - (concat remote-prefix normalized))) + (url (url-generic-parse-url uri))) + (if (string= "file" (url-type url)) + (let* ((retval (url-unhex-string (url-filename url))) + ;; Remove the leading "/" for local MS Windows-style paths. + (normalized (if (and (not remote-prefix) + (eq system-type 'windows-nt) + (cl-plusp (length retval))) + (substring retval 1) + retval))) + (concat remote-prefix normalized)) + ;; Leave non-file type URIs untouched, `file-name-handler-alist' + ;; handlers can be used to dispatch them properly. + uri))) (defun eglot--snippet-expansion-fn () "Compute a function to expand snippets. -- 2.38.0