From bac16677e258a560471a920c6fdeac91c3ecb447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felici=C3=A1n=20N=C3=A9meth?= Date: Mon, 28 Feb 2022 14:54:47 +0100 Subject: [PATCH] Add new command: cargo-find-dependency * cargo.el (cargo-find-dependency): New command. (cargo-minor-mode-command-map): Bind it to C-S-f. * cargo-process.el (cargo-process--get-metadata): New defun. * README.md (Usage): Document the keybinding. --- README.md | 1 + cargo-process.el | 9 +++++++++ cargo.el | 28 ++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/README.md b/README.md index 52383b9..7b5c340 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ You will now have the following key combinations at your disposal: C-c C-c C-S-a | cargo-process-audit C-c C-c C-S-r | cargo-process-script C-c C-c C-w | cargo-process-watch + C-c C-c C-S-f | cargo-find-dependency Before executing the task, Emacs will prompt you to save any modified buffers associated with the current Cargo project. Setting `compilation-ask-about-save` diff --git a/cargo-process.el b/cargo-process.el index 6b8a2db..c9aa610 100644 --- a/cargo-process.el +++ b/cargo-process.el @@ -347,6 +347,15 @@ If FILE-NAME is not a TRAMP file, return it unmodified." (cdr (assoc 'workspace_root metadata-json))))) workspace-root))) +(defun cargo-process--get-metadata () + "Return the metadata of the current package as an alist." + (when (cargo-process--project-root) + (let ((metadata-text + (shell-command-to-string + (concat (shell-quote-argument cargo-process--custom-path-to-bin) + " metadata --format-version 1")))) + (cargo-json-read-from-string metadata-text)))) + (defun manifest-path-argument (name) (let ((manifest-filename (cargo-process--tramp-file-local-name (cargo-process--project-root "Cargo.toml")))) (when (and manifest-filename diff --git a/cargo.el b/cargo.el index 3ccd1e3..14dc1f8 100644 --- a/cargo.el +++ b/cargo.el @@ -88,6 +88,7 @@ (define-key km (kbd "C-S-a") 'cargo-process-audit) (define-key km (kbd "C-S-r") 'cargo-process-script) (define-key km (kbd "C-w") 'cargo-process-watch) + (define-key km (kbd "C-S-f") 'cargo-find-dependency) km) "Keymap for Cargo mode commands after prefix.") (fset 'cargo-minor-mode-command-map cargo-minor-mode-command-map) @@ -100,6 +101,33 @@ (defvar cargo-minor-mode nil) +(defun cargo-find-dependency (crate &optional metadata) + "Find CRATE's Cargo.toml. +If METADATA is non-nil, use that instead of fetching it with cargo." + (interactive (let* ((metadata + (cargo-process--get-metadata)) + (crates + (mapcar (lambda (pkg) (alist-get 'name pkg)) + (append (alist-get 'packages metadata) nil)))) + (list + (completing-read + "Dependency: " crates nil t nil nil (symbol-at-point)) + metadata))) + (let ((filenames + (cl-loop for pkg in (append (alist-get 'packages metadata) nil) + when (equal crate (alist-get 'name pkg)) + collect (alist-get 'manifest_path pkg))) + ;; Directly `find-file' if there's just a single match. + (xref-show-xrefs-function xref-show-definitions-function)) + (if filenames + (xref-show-xrefs (mapcar (lambda (filename) + (xref-make crate + (xref-make-file-location + filename 1 0))) + filenames) + nil) + (message "Can't find: %s" crate)))) + ;;;###autoload (define-minor-mode cargo-minor-mode "Cargo minor mode. Used to hold keybindings for cargo-mode.