Eglot: escape literal % characters in URIs

Escape literal % characters in Eglot URIs

Otherwise, a literal % in a file-name will be interpreted (by the
language server) as if it were a part of a percent-encoded sequence.

See Bug#78984 for context on why `url-path-allowed-chars' cannot be
changed to escape literal % characters.

* lisp/progmodes/eglot.el (eglot--uri-path-allowed-chars): Escape %,
remove the redundant variable definition.
* test/lisp/progmodes/eglot-tests.el (eglot-test-path-to-uri-escape):
test it.
This commit is contained in:
Steven Allen 2025-08-30 11:19:05 +01:00 committed by João Távora
parent 8d301906e1
commit 4ab16d701e
2 changed files with 5 additions and 6 deletions

View file

@ -675,6 +675,7 @@ This can be useful when using docker to run a language server.")
(defconst eglot--uri-path-allowed-chars
(let ((vec (copy-sequence url-path-allowed-chars)))
(aset vec ?: nil) ;; see github#639
(aset vec ?% nil) ;; see bug#78984
vec)
"Like `url-path-allowed-chars' but more restrictive.")
@ -2008,12 +2009,6 @@ If optional MARKER, return a marker instead"
;;; More helpers
(defconst eglot--uri-path-allowed-chars
(let ((vec (copy-sequence url-path-allowed-chars)))
(aset vec ?: nil) ;; see github#639
vec)
"Like `url-path-allowed-chars' but more restrictive.")
(defun eglot--snippet-expansion-fn ()
"Compute a function to expand snippets.
Doubles as an indicator of snippet support."

View file

@ -1469,6 +1469,10 @@ GUESSED-MAJOR-MODES-SYM are bound to the useful return values of
(should (string-suffix-p "c%3A/Users/Foo/bar.lisp"
(eglot-path-to-uri "c:/Users/Foo/bar.lisp"))))
(ert-deftest eglot-test-path-to-uri-escape ()
(should (equal "file:///path/with%20%25%20funny%20%3F%20characters"
(eglot-path-to-uri "/path/with % funny ? characters"))))
(ert-deftest eglot-test-same-server-multi-mode ()
"Check single LSP instance manages multiple modes in same project."
(skip-unless (executable-find "clangd"))