-
-
Notifications
You must be signed in to change notification settings - Fork 940
Open
Labels
Description
Thank you for the bug report
- I am using the latest version of
lsp-moderelated packages. - I checked FAQ and Troubleshooting sections
- You may also try reproduce the issue using clean environment using the following command:
M-x lsp-start-plain
Bug description
With the pyrefly server added via custom config, cannot use xref-find-definitions.
Steps to reproduce
- Enable pyrefly integration, or minimally:
(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection (lambda () '("pyrefly" "lsp")))
:activation-fn (lsp-activate-on "python")
:add-on? t
:multi-root t
:server-id 'my-pyrefly))- Use
xref-find-definitionson any valid identifier, such as this minimal case:
x = 1
print(x)
# ^
# xref-find-definitions hereThe error will appear after some timeouts, if any.
Expected behavior
xref-find-definitions works correctly.
Which Language Server did you use?
Pyrefly
OS
Linux
Error callstack
Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p nil)
=(nil nil)
(if (= left-line right-line) (> left-character right-character) (> left-line right-line))
(let* ((left-line (plist-get input0 :line)) (left-character (plist-get input0 :character)) (right-line (plist-get input1 :line)) (right-character (plist-get input1 :character))) (if (= left-line right-line) (> left-character right-character) (> left-line right-line)))
lsp--position-compare(nil nil)
(let* ((left-start (plist-get input0 :start)) (right-start (plist-get input1 :start))) (lsp--position-compare right-start left-start))
(let ((input0 (lsp--location-range left)) (input1 (lsp--location-range right))) (let* ((left-start (plist-get input0 :start)) (right-start (plist-get input1 :start))) (lsp--position-compare right-start left-start)))
(if (not (string= left-uri right-uri)) (string< left-uri right-uri) (let ((input0 (lsp--location-range left)) (input1 (lsp--location-range right))) (let* ((left-start (plist-get input0 :start)) (right-start (plist-get input1 :start))) (lsp--position-compare right-start left-start))))
(let ((left-uri (lsp--location-uri left)) (right-uri (lsp--location-uri right))) (if (not (string= left-uri right-uri)) (string< left-uri right-uri) (let ((input0 (lsp--location-range left)) (input1 (lsp--location-range right))) (let* ((left-start (plist-get input0 :start)) (right-start (plist-get input1 :start))) (lsp--position-compare right-start left-start)))))
#f(lambda (left right) [eldoc-documentation-default cl-struct-lsp--log-entry-tags cl-struct-lsp-session-tags cl-struct-lsp--workspace-tags cl-struct-lsp--registered-capability-tags lsp-mode-menu cl-struct-lsp--folding-range-tags cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t] "Sort first by file, then by line, then by column." (let ((left-uri (lsp--location-uri left)) (right-uri (lsp--location-uri right))) (if (not (string= left-uri right-uri)) (string< left-uri right-uri) (let ((input0 (lsp--location-range left)) (input1 (lsp--location-range right))) (let* ((left-start (plist-get input0 :start)) (right-start (plist-get input1 :start))) (lsp--position-compare right-start left-start))))))((:end (:character 1 :line 0) :start (:character 0 :line 0)) :range)
sort(((:originSelectionRange (:end (:character 7 :line 1) :start (:character 6 :line 1)) :targetRange (:end (:character 5 :line 0) :start (:character 0 :line 0)) :targetSelectionRange (:end (:character 1 :line 0) :start (:character 0 :line 0)) :targetUri "file:///home/dan/temp/test/lsp-pyrefly-reproduce.py") :range (:end (:character 1 :line 0) :start (:character 0 :line 0)) :uri "file:///home/dan/temp/test/lsp-pyrefly-reproduce.py") lsp--location-before-p)
#f(compiled-function (pred list) #<bytecode 0x1872bfc40bbfcaf5>)(lsp--location-before-p ((:originSelectionRange (:end (:character 7 :line 1) :start (:character 6 :line 1)) :targetRange (:end (:character 5 :line 0) :start (:character 0 :line 0)) :targetSelectionRange (:end (:character 1 :line 0) :start (:character 0 :line 0)) :targetUri "file:///home/dan/temp/test/lsp-pyrefly-reproduce.py") :range (:end (:character 1 :line 0) :start (:character 0 :line 0)) :uri "file:///home/dan/temp/test/lsp-pyrefly-reproduce.py"))
apply(#f(compiled-function (pred list) #<bytecode 0x1872bfc40bbfcaf5>) lsp--location-before-p ((:originSelectionRange (:end (:character 7 :line 1) :start (:character 6 :line 1)) :targetRange (:end (:character 5 :line 0) :start (:character 0 :line 0)) :targetSelectionRange (:end (:character 1 :line 0) :start (:character 0 :line 0)) :targetUri "file:///home/dan/temp/test/lsp-pyrefly-reproduce.py") :range (:end (:character 1 :line 0) :start (:character 0 :line 0)) :uri "file:///home/dan/temp/test/lsp-pyrefly-reproduce.py") nil)
seq-sort(lsp--location-before-p ((:originSelectionRange (:end (:character 7 :line 1) :start (:character 6 :line 1)) :targetRange (:end (:character 5 :line 0) :start (:character 0 :line 0)) :targetSelectionRange (:end (:character 1 :line 0) :start (:character 0 :line 0)) :targetUri "file:///home/dan/temp/test/lsp-pyrefly-reproduce.py") :range (:end (:character 1 :line 0) :start (:character 0 :line 0)) :uri "file:///home/dan/temp/test/lsp-pyrefly-reproduce.py"))
(seq-group-by (-compose #'lsp--uri-to-path #'lsp--location-uri) (seq-sort #'lsp--location-before-p locations))
(seq-map --cl-get-xrefs-in-file-- (seq-group-by (-compose #'lsp--uri-to-path #'lsp--location-uri) (seq-sort #'lsp--location-before-p locations)))
(apply #'nconc (seq-map --cl-get-xrefs-in-file-- (seq-group-by (-compose #'lsp--uri-to-path #'lsp--location-uri) (seq-sort #'lsp--location-before-p locations))))
(let* ((--cl-get-xrefs-in-file-- #'(lambda (file-locs) (let* ((--dash-source-717-- file-locs) (filename ...) (matches --dash-source-717--)) (condition-case err (let ... ...) (error ...) (file-error ...)))))) (apply #'nconc (seq-map --cl-get-xrefs-in-file-- (seq-group-by (-compose #'lsp--uri-to-path #'lsp--location-uri) (seq-sort #'lsp--location-before-p locations)))))
lsp--locations-to-xref-items(((:originSelectionRange (:end (:character 7 :line 1) :start (:character 6 :line 1)) :targetRange (:end (:character 5 :line 0) :start (:character 0 :line 0)) :targetSelectionRange (:end (:character 1 :line 0) :start (:character 0 :line 0)) :targetUri "file:///home/dan/temp/test/lsp-pyrefly-reproduce.py") :range (:end (:character 1 :line 0) :start (:character 0 :line 0)) :uri "file:///home/dan/temp/test/lsp-pyrefly-reproduce.py"))
(save-excursion (if (get-text-property 0 'identifier-at-point identifier) nil (goto-char (cl-rest (or (assoc identifier lsp--symbols-cache) (user-error "Unable to find symbol %s in current document" identifier))))) (lsp--locations-to-xref-items (lsp-request "textDocument/definition" (lsp--text-document-position-params))))
(progn (save-excursion (if (get-text-property 0 'identifier-at-point identifier) nil (goto-char (cl-rest (or (assoc identifier lsp--symbols-cache) (user-error "Unable to find symbol %s in current document" identifier))))) (lsp--locations-to-xref-items (lsp-request "textDocument/definition" (lsp--text-document-position-params)))))
#f(lambda (_backend identifier) [view-inhibit-help-message lsp-help-mode-abbrev-table lsp-help-mode-syntax-table eldoc-documentation-default cl-struct-lsp--log-entry-tags cl-struct-lsp-session-tags cl-struct-lsp--workspace-tags cl-struct-lsp--registered-capability-tags lsp-mode-menu cl-struct-lsp--folding-range-tags cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t] (progn (save-excursion (if (get-text-property 0 'identifier-at-point identifier) nil (goto-char (cl-rest (or (assoc identifier lsp--symbols-cache) (user-error "Unable to find symbol %s in current document" identifier))))) (lsp--locations-to-xref-items (lsp-request "textDocument/definition" (lsp--text-document-position-params))))))(xref-lsp #("x" 0 1 (identifier-at-point t fontified t)))
apply(#f(lambda (_backend identifier) [view-inhibit-help-message lsp-help-mode-abbrev-table lsp-help-mode-syntax-table eldoc-documentation-default cl-struct-lsp--log-entry-tags cl-struct-lsp-session-tags cl-struct-lsp--workspace-tags cl-struct-lsp--registered-capability-tags lsp-mode-menu cl-struct-lsp--folding-range-tags cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t] (progn (save-excursion (if (get-text-property 0 'identifier-at-point identifier) nil (goto-char (cl-rest (or ... ...)))) (lsp--locations-to-xref-items (lsp-request "textDocument/definition" (lsp--text-document-position-params)))))) xref-lsp #("x" 0 1 (identifier-at-point t fontified t)))
xref-backend-definitions(xref-lsp #("x" 0 1 (identifier-at-point t fontified t)))
#f(compiled-function () #<bytecode -0x1a307b6b1281ea37>)()
xref-show-definitions-buffer(#f(compiled-function () #<bytecode -0x1a307b6b1281ea37>) ((window . #<window 3 on lsp-pyrefly-reproduce.py>) (display-action) (auto-jump)))
xref--show-defs(#f(compiled-function () #<bytecode -0x1a307b6b1281ea37>) nil)
xref--find-definitions(#("x" 0 1 (identifier-at-point t fontified t)) nil)
xref-find-definitions(#("x" 0 1 (identifier-at-point t fontified t)))
funcall-interactively(xref-find-definitions #("x" 0 1 (identifier-at-point t fontified t)))
command-execute(xref-find-definitions)Anything else?
The cause seems to be at https://github.com/emacs-lsp/lsp-mode/blob/7fcd17e7d8a06e9943dde059bb940ae80e3974fc/lsp-mode.el#L5354C1-L5360C31, lsp--locations-to-xref-items's pcase matching returns the wrong case.
I'm not sure how that pcase works, but this workaround solves the case for me:
(defun my-lsp--locations-to-xref-items--workaround-list-a (func locations &rest args)
(condition-case _
(apply func locations args)
((wrong-type-argument)
(apply func (list locations) args))))
(advice-add #'lsp--locations-to-xref-items :around #'my-lsp--locations-to-xref-items--workaround-list-a)