大佬们,我使用的 doom emacs 今天启动 eglot 报错了。
我排查发现是 id=3 的请求返回的结果解析错误,eglot--sig-info
中activeParamter
值为 nil
导致 3218 行 (when (= i active-param)
求值错误,它的上层函数是eglot-signature-eldoc-function
由于这里太复杂了(全是宏),我不知道怎么 debug 了 请问大佬们怎么解决啊?
pyton 的没有任何问题,直接使用的doom的模块
eglot版本: e501275e06952889056268dabe08ccd0dbaf23e5
jdtls 版本: https://download.eclipse.org/jdtls/milestones/1.24.0/jdt-language-server-1.24.0-202306011728.tar.gz"
- 我的所有关于 eglot 的配置配置
;; https://github.com/joaotavora/eglot/discussions/888#discussioncomment-2386710
(cl-defmethod eglot-execute-command
(_server (_cmd (eql java.apply.workspaceEdit)) arguments)
"Eclipse JDT breaks spec and replies with edits as arguments."
(mapc #'eglot--apply-workspace-edit arguments))
(cl-defgeneric +eglot/ext-uri-to-path (uri)
"Support extension uri."
nil)
;; https://github.com/eclipse/eclipse.jdt.ls/blob/b4e5cb4b693d5d503d90be89b0b9a8abe9db41a5/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JDTUtils.java#L809
(cl-defmethod +eglot/ext-uri-to-path (uri &context (major-mode java-mode))
"Support Eclipse jdtls `jdt://' uri scheme."
(when-let* ((jdt-scheme-p (string-prefix-p "jdt://" uri))
(filename (save-match-data
(when (string-match "jdt://contents/\\(.*?\\)/\\(.*\\)\.class\\?" uri)
(format "%s.java"
(replace-regexp-in-string "/" "." (match-string 2 uri) t t))))))
(+eglot/create-source-file :java/classFileContents uri filename)))
;; https://github.com/emacs-lsp/lsp-mode/blob/d3bc47bde5ffc1bace40122a6ec0c6d8b9e84500/clients/lsp-clojure.el#L272
;; https://github.com/clojure-lsp/clojure-lsp/blob/master/lib/test/clojure_lsp/shared_test.clj
(cl-defmethod +eglot/ext-uri-to-path (uri &context (major-mode clojure-mode))
"Support Clojure-lsp `zifile://', `jar:file://' uri scheme."
(when-let* ((clj-scheme-p (or (string-prefix-p "jar:file://" uri)
(string-prefix-p "zipfile://" uri)))
(filename (when (string-match "^\\(jar:file\\|zipfile\\)://.+\\(!/\\|::\\)\\(.+\\)" uri)
(let* ((ns-path (match-string 3 uri))
(filename (replace-regexp-in-string "/" "." ns-path)))
filename))))
(+eglot/create-source-file :clojure/dependencyContents uri filename)))
(defun +eglot/create-source-file (method uri filename)
"Create source file and metadata in project root .eglot directory."
(let* ((cache-dir (file-name-concat (project-root (eglot--current-project)) ".eglot"))
(source-file (expand-file-name (file-name-concat cache-dir filename))))
(unless (file-readable-p source-file)
(let ((content (jsonrpc-request (eglot--current-server-or-lose) method (list :uri uri)))
(metadata-file (+eglot/path-to-metadata-file source-file)))
(unless (file-directory-p cache-dir) (make-directory cache-dir t))
(with-temp-file source-file (insert content))
(with-temp-file metadata-file (insert uri))))
source-file))
(defun +eglot/path-to-metadata-file (path)
(format "%s.%s.metadata" (file-name-directory path) (file-name-base path)))
(defun +eglot/path-to-ext-uri (path)
"Retrieve extension uri from metadata."
(let ((metadata-file (+eglot/path-to-metadata-file path)))
(when (file-exists-p metadata-file)
(with-temp-buffer
(insert-file-contents metadata-file)
(buffer-string)))))
(define-advice eglot--uri-to-path (:around (orig-fn uri) advice)
"Support non standard LSP uri scheme."
(when (keywordp uri) (setq uri (substring (symbol-name uri) 1)))
(or (+eglot/ext-uri-to-path uri)
(funcall orig-fn uri)))
(define-advice eglot--path-to-uri (:around (orig-fn path) advice)
"Support non standard LSP uri scheme."
(or (+eglot/path-to-ext-uri path)
(funcall orig-fn path)))
(after! eglot
;; 覆盖默认 eglot jump to reference 配置,
(map! :map eglot-mode-map
:n "gD" nil))
;; 设置lombok
(setq lombok-library-path (expand-file-name "java/lombok.jar" lsp-local-install-dir)
jdk-base-path "/usr/lib/jvm/"
eglot-extend-to-xref t)
(unless (file-exists-p lombok-library-path)
(url-copy-file "https://projectlombok.org/downloads/lombok.jar" lombok-library-path))
(set-eglot-client! '(java-mode java-ts-mode)
;; 服务器启动参数配置
`(,(expand-file-name "java/jdtls/bin/jdtls" lsp-local-install-dir)
"-configuration" ,(expand-file-name "java/jdtls/config_linux" lsp-local-install-dir)
"-data" ,(expand-file-name "java/workspace" lsp-local-install-dir)
,(concat "--jvm-arg=-javaagent:" lombok-library-path)
;; 初始化
:initializationOptions (:settings
(:java
(:configuration
(:runtime [(:name "JavaSE-1.8" :path ,(expand-file-name "java-8-openjdk" jdk-base-path) :default t)
(:name "JavaSE-11" :path ,(expand-file-name "java-11-openjdk" jdk-base-path))
(:name "JavaSE-17" :path ,(expand-file-name "java-17-openjdk" jdk-base-path))])
:format (:settings (:url ,(expand-file-name "formatter/java-google-style.xml" doom-private-dir)
:profile "GoogleStyle"))
;; NOTE: https://github.com/redhat-developer/vscode-java/issues/406#issuecomment-356303715
;; > We enabled it by default so that workspace-wide errors can be reported (eg. removing a public method in one class would cause
;; compilation errors in other files consuming that method).
;; for large workspaces, it may make sense to be able to disable autobuild if it negatively impacts performance.
:autobuild (:enabled t)
;; https://github.com/dgileadi/vscode-java-decompiler
:contentProvider (:preferred "fernflower")))
;; WIP: support non standard LSP `java/classFileContents', `Location' items that have a `jdt://...' uri
;; https://github.com/eclipse/eclipse.jdt.ls/issues/1384
;; nvim impl demo: https://github.com/mfussenegger/dotfiles/commit/3cddf73cd43120da2655e2df6d79bdfd06697f0e
;; lsp-java impl demo: https://github.com/emacs-lsp/lsp-java/blob/master/lsp-java.el
:extendedClientCapabilities (:classFileContentsSupport t)
;; bundles: decompilers, etc.
;; https://github.com/dgileadi/dg.jdt.ls.decompiler
:bundles ,(let ((bundles-dir (expand-file-name "java/bundles" lsp-local-install-dir))
jdtls-bundles)
(require 'dash)
(->> (when (file-directory-p bundles-dir)
(directory-files bundles-dir t "\\.jar$"))
(append jdtls-bundles)
(apply #'vector))))))
;; 设置 Company 补全后端配置
(set-company-backend! 'eglot--managed-mode
'company-capf
'(:separate company-dabbrev company-yasnippet company-ispell company-abbrev))
;; 如果当前 java-mode 将自动启动 eglot
(add-hook! 'java-mode-local-vars-hook :append #'lsp!)
(after! nxml-mode
;; 设置 pom.xml 补全后端
(set-company-backend! 'nxml-mode 'company-pom))
(set-file-template! "/resources/?.*/logback-spring\\.xml$" :trigger "__logback-spring" :mode 'nxml-mode :project t)
(set-file-template! "/resources/?.*/mybatis-spring\\.xml$" :trigger "__mybatis-spring" :mode 'nxml-mode :project t)
(set-file-template! "/test/[A-Z].*Test\\(s\\|Case\\)?\\.java$" :trigger "__test" :mode 'java-mode :project t)
- 报错日志
Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p nil)
eglot--sig-info((:label "println(Object x) : void" :parameters [(:label "Object x")]) nil nil)
#f(compiled-function (s) #<bytecode -0x7396529f3fe5a95>)((:label "println(Object x) : void" :parameters [(:label "Object x")]))
mapconcat(#f(compiled-function (s) #<bytecode -0x7396529f3fe5a95>) [(:label "println() : void" :parameters []) (:label "println(Object x) : void" :parameters [(:label "Object x")]) (:label "println(String x) : void" :parameters [(:label "String x")]) (:label "println(char[] x) : void" :parameters [(:label "char[] x")]) (:label "println(double x) : void" :parameters [(:label "double x")]) (:label "println(float x) : void" :parameters [(:label "float x")]) (:label "println(long x) : void" :parameters [(:label "long x")]) (:label "println(int x) : void" :parameters [(:label "int x")]) (:label "println(char x) : void" :parameters [(:label "char x")]) (:label "println(boolean x) : void" :parameters [(:label "boolean x")])] "\n")
#f(compiled-function (jsonrpc-lambda-elem11) #<bytecode -0x89666e83036998>)((:signatures [(:label "println() : void" :parameters []) (:label "println(Object x) : void" :parameters [(:label "Object x")]) (:label "println(String x) : void" :parameters [(:label "String x")]) (:label "println(char[] x) : void" :parameters [(:label "char[] x")]) (:label "println(double x) : void" :parameters [(:label "double x")]) (:label "println(float x) : void" :parameters [(:label "float x")]) (:label "println(long x) : void" :parameters [(:label "long x")]) (:label "println(int x) : void" :parameters [(:label "int x")]) (:label "println(char x) : void" :parameters [(:label "char x")]) (:label "println(boolean x) : void" :parameters [(:label "boolean x")])] :activeSignature 3 :activeParameter 0))
jsonrpc-connection-receive(#<eglot-lsp-server eglot-lsp-server-15578cde2434> (:jsonrpc "2.0" :id 41 :result (:signatures [(:label "println() : void" :parameters []) (:label "println(Object x) : void" :parameters [(:label "Object x")]) (:label "println(String x) : void" :parameters [(:label "String x")]) (:label "println(char[] x) : void" :parameters [(:label "char[] x")]) (:label "println(double x) : void" :parameters [(:label "double x")]) (:label "println(float x) : void" :parameters [(:label "float x")]) (:label "println(long x) : void" :parameters [(:label "long x")]) (:label "println(int x) : void" :parameters [(:label "int x")]) (:label "println(char x) : void" :parameters [(:label "char x")]) (:label "println(boolean x) : void" :parameters [(:label "boolean x")])] :activeSignature 3 :activeParameter 0)))
jsonrpc--process-filter(#<process EGLOT (java-learn/(java-mode java-ts-mode))> "Content-Length: 779\15\n\15\n{\"jsonrpc\":\"2.0\",\"id\":41,\"r...")