summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eglot-x.el73
1 files changed, 49 insertions, 24 deletions
diff --git a/eglot-x.el b/eglot-x.el
index 9c96225..62a0f26 100644
--- a/eglot-x.el
+++ b/eglot-x.el
@@ -280,6 +280,7 @@ connections."
["Clear flycheck" eglot-x-clear-flycheck]
["Cancel flycheck" eglot-x-cancel-flycheck])
["View crate graph" eglot-x-view-crate-graph]
+ ["Find crate in dependencies" eglot-x-find-crate]
"--"
["Reload workspace" eglot-x-reload-workspace]
["Status" eglot-x-analyzer-status]
@@ -955,34 +956,58 @@ This assumes rust."
(let ((xref-show-xrefs-function xref-show-definitions-function))
(xref-show-xrefs xrefs nil))
(user-error
- (eglot-x--find-crate-with-cargo (symbol-name symbol)))))))
- ;; (switch-to-buffer (help-buffer))
- ;; (message "Can't find: %s" symbol))))))
-
-(defun eglot-x--find-crate-with-cargo (crate)
- "Find CRATE with cargo and jq."
- ;; The jq dependency can be easily eliminated.
- ;; This should be in cargo.el.
- (let* ((regexp (concat "^"
- (replace-regexp-in-string "_" "[_-]" crate)
- "$"))
- (res (shell-command-to-string
- (concat "cargo metadata --format-version 1|"
- "jq '.packages[]|select(.name|test(\""
- regexp
- "\")).manifest_path'")))
- (xrefs
+ (condition-case err
+ (eglot-x-find-crate (symbol-name symbol))
+ (error
+ (switch-to-buffer (help-buffer))
+ (signal (car err) (cdr err)))))))))
+
+(defun eglot-x--get-dependencies ()
+ "Return dependencies with the rust-analyzer/fetchDependencyList request."
+ (let ((res (jsonrpc-request (eglot--current-server-or-lose)
+ :rust-analyzer/fetchDependencyList
+ eglot--{})))
+ (plist-get res :crates)))
+
+(defun eglot-x-find-crate (&optional crate crates)
+ "Find a rust dependency named CRATE.
+If CRATE is nil or there are multiple matches, provide a completion.
+CRATES should be nil, it is used internally."
+ (interactive
+ (let ((crates (eglot-x--get-dependencies))
+ (completion-extra-properties
+ '(:annotation-function
+ (lambda (c)
+ (when-let ((desc (get-text-property 0 :annotation c)))
+ (concat " " desc))))))
+ (list
+ (completing-read
+ "Dependency: "
+ (mapcar (lambda (obj)
+ (propertize (plist-get obj :name)
+ :annotation (plist-get obj :version)))
+ crates)
+ nil t nil nil (word-at-point))
+ crates)))
+ (let* ((crates (seq-filter (lambda (obj)
+ (string= crate (plist-get obj :name)))
+ (or crates (eglot-x--get-dependencies))))
+ (xrefs
(lambda ()
- (mapcar (lambda (line)
- (xref-make crate
+ (mapcar (lambda (obj)
+ (xref-make (if (plist-get obj :version)
+ (format "%s:%s"
+ (plist-get obj :name)
+ (plist-get obj :version))
+ (plist-get obj :name))
(xref-make-file-location
- (substring line 1 -1) 1 0)))
- (split-string res)))))
- (if (not (equal res ""))
+ (eglot--uri-to-path (plist-get obj :path))
+ 1 0)))
+ crates))))
+ (if crates
(let ((xref-show-xrefs-function xref-show-definitions-function))
(xref-show-xrefs xrefs nil))
- (switch-to-buffer (help-buffer))
- (message "Can't find: %s" crate))))
+ (user-error "[eglot-x] Can't find crate: %s" crate))))
(defvar eglot-x--graph-buffer " *eglot-x-crate-graph*"
"Buffer name to store the output of the background process.")