Skip to content

Commit

Permalink
Support Eglot 18
Browse files Browse the repository at this point in the history
  • Loading branch information
wyuenho committed Jan 15, 2025
1 parent f6b1be0 commit 0739187
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 23 deletions.
24 changes: 17 additions & 7 deletions pet.el
Original file line number Diff line number Diff line change
Expand Up @@ -788,15 +788,23 @@ default otherwise."
(declare-function eglot--workspace-configuration-plist "ext:eglot")
(declare-function eglot--guess-contact "ext:eglot")

(defun pet-eglot--executable-find-advice (fn &rest args)
(defun pet-eglot--executable-find (&rest args)
"Look up Python language servers using `pet-executable-find'.
FN is `eglot--executable-find', ARGS is the arguments to
`eglot--executable-find'."
ARGS is the arguments to `executable-find'."
(pcase-let ((`(,command . ,_) args))
(if (member command '("pylsp" "pyls" "pyright-langserver" "jedi-language-server" "ruff-lsp"))
(pet-executable-find command)
(apply fn args))))
(apply #'pet--executable-find args))))

(defun pet-eglot-alternatives-advice (fn &rest args)
"Look up executables using `pet-eglot--executable-find'.
FN is `eglot-alternatives'. See its docstring for the definition of
ARGS."
(cl-letf (((symbol-function 'executable-find)
(symbol-function 'pet-eglot--executable-find)))
(apply fn args)))

(defun pet-lookup-eglot-server-initialization-options (command)
"Return LSP initializationOptions for Eglot.
Expand Down Expand Up @@ -902,7 +910,9 @@ arguments to `eglot--workspace-configuration-plist'."
FN is `eglot--guess-contact', ARGS is the arguments to
`eglot--guess-contact'."
(let* ((result (apply fn args))
(let* ((result (cl-letf (((symbol-function 'executable-find)
(symbol-function 'pet-eglot--executable-find)))
(apply fn args)))
(contact (nth 3 result))
(probe (seq-position contact :initializationOptions))
(program-with-args (seq-subseq contact 0 (or probe (length contact))))
Expand All @@ -924,13 +934,13 @@ FN is `eglot--guess-contact', ARGS is the arguments to

(defun pet-eglot-setup ()
"Set up Eglot to use server executables and virtualenvs found by PET."
(advice-add 'eglot--executable-find :around #'pet-eglot--executable-find-advice)
(advice-add 'eglot-alternatives :around #'pet-eglot-alternatives-advice)
(advice-add 'eglot--workspace-configuration-plist :around #'pet-eglot--workspace-configuration-plist-advice)
(advice-add 'eglot--guess-contact :around #'pet-eglot--guess-contact-advice))

(defun pet-eglot-teardown ()
"Tear down PET advices to Eglot."
(advice-remove 'eglot--executable-find #'pet-eglot--executable-find-advice)
(advice-remove 'eglot-alternatives #'pet-eglot-alternatives-advice)
(advice-remove 'eglot--workspace-configuration-plist #'pet-eglot--workspace-configuration-plist-advice)
(advice-remove 'eglot--guess-contact #'pet-eglot--guess-contact-advice))

Expand Down
32 changes: 16 additions & 16 deletions test/pet-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -996,33 +996,33 @@
(expect (local-variable-p 'flycheck-python-pycompile-executable) :not :to-be-truthy)
(expect (local-variable-p 'flycheck-python-ruff-executable) :not :to-be-truthy)))

(describe "pet-eglot--executable-find-advice"
(describe "pet-eglot--executable-find"
(it "should delegate to `pet-executable-find' for Python LSP servers"
(spy-on 'eglot--executable-find :and-call-fake (lambda (&rest args) (string-join args " ")))
(spy-on 'executable-find :and-call-fake (lambda (&rest args) (string-join args " ")))
(spy-on 'pet-executable-find :and-call-fake 'identity)

(expect (pet-eglot--executable-find-advice 'eglot--executable-find "pylsp") :to-equal "pylsp")
(expect (pet-eglot--executable-find "pylsp") :to-equal "pylsp")
(expect (spy-context-return-value (spy-calls-most-recent 'pet-executable-find)) :to-equal "pylsp")
(expect 'eglot--executable-find :not :to-have-been-called)
(expect 'executable-find :not :to-have-been-called)

(expect (pet-eglot--executable-find-advice 'eglot--executable-find "pyls") :to-equal "pyls")
(expect (pet-eglot--executable-find "pyls") :to-equal "pyls")
(expect (spy-context-return-value (spy-calls-most-recent 'pet-executable-find)) :to-equal "pyls")
(expect 'eglot--executable-find :not :to-have-been-called)
(expect 'executable-find :not :to-have-been-called)

(expect (pet-eglot--executable-find-advice 'eglot--executable-find "pyright-langserver") :to-equal "pyright-langserver")
(expect (pet-eglot--executable-find "pyright-langserver") :to-equal "pyright-langserver")
(expect (spy-context-return-value (spy-calls-most-recent 'pet-executable-find)) :to-equal "pyright-langserver")
(expect 'eglot--executable-find :not :to-have-been-called)
(expect 'executable-find :not :to-have-been-called)

(expect (pet-eglot--executable-find-advice 'eglot--executable-find "jedi-language-server") :to-equal "jedi-language-server")
(expect (pet-eglot--executable-find "jedi-language-server") :to-equal "jedi-language-server")
(expect (spy-context-return-value (spy-calls-most-recent 'pet-executable-find)) :to-equal "jedi-language-server")
(expect 'eglot--executable-find :not :to-have-been-called)
(expect 'executable-find :not :to-have-been-called)

(expect (pet-eglot--executable-find-advice 'eglot--executable-find "ruff-lsp") :to-equal "ruff-lsp")
(expect (pet-eglot--executable-find "ruff-lsp") :to-equal "ruff-lsp")
(expect (spy-context-return-value (spy-calls-most-recent 'pet-executable-find)) :to-equal "ruff-lsp")
(expect 'eglot--executable-find :not :to-have-been-called)
(expect 'executable-find :not :to-have-been-called)

(expect (pet-eglot--executable-find-advice 'eglot--executable-find "sh" "-c") :to-equal "sh -c")
(expect 'eglot--executable-find :to-have-been-called-with "sh" "-c")))
(expect (pet-eglot--executable-find "sh") :to-equal "sh")
(expect 'executable-find :to-have-been-called-with "sh")))

(describe "pet-eglot--workspace-configuration-plist-advice"
(before-each
Expand Down Expand Up @@ -1277,15 +1277,15 @@
(it "should advice eglot functions"
(pet-eglot-setup)
(expect (advice-member-p 'pet-eglot--workspace-configuration-plist-advice 'eglot--workspace-configuration-plist) :to-be-truthy)
(expect (advice-member-p 'pet-eglot--executable-find-advice 'eglot--executable-find) :to-be-truthy)
(expect (advice-member-p 'pet-eglot-alternatives-advice 'eglot-alternatives) :to-be-truthy)
(expect (advice-member-p 'pet-eglot--guess-contact-advice 'eglot--guess-contact) :to-be-truthy)))

(describe "pet-eglot-teardown"
(it "should remove `pet' advices from eglot functions"
(pet-eglot-setup)
(pet-eglot-teardown)
(expect (advice-member-p 'pet-eglot--workspace-configuration-plist-advice 'eglot--workspace-configuration-plist) :to-be nil)
(expect (advice-member-p 'pet-eglot--executable-find-advice 'eglot--executable-find) :to-be nil)
(expect (advice-member-p 'pet-eglot-alternatives-advice 'eglot-alternatives) :to-be nil)
(expect (advice-member-p 'pet-eglot--guess-contact-advice 'eglot--guess-contact) :to-be nil)))

(describe "pet-dape-setup"
Expand Down

0 comments on commit 0739187

Please sign in to comment.