1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-10 13:40:36 -08:00

Add function use-package-jump-to-package-form

This is an attempt at resolving https://github.com/jwiegley/use-package/issues/329. The new interactive function
use-package-jump-to-package-form will prompt with a completing read of
all known packages. After selecting a package, use-package-find-require
searches load-history to see where the package was required and then I
attempt to find the correct use-package form using
use-package-form-regexp.

It will fail if the use-package form you are looking for did not
actually load the package. For example it could be something that is a
dependency of a library that was already loaded. In some sense this is a
feature because it is helpful to know that the library was already
loaded when your use-package form was encountered. It will also fail if
your use-package declaration doesn't match the regexp used, but this is
easily adjusted.
This commit is contained in:
Justin Burkett 2016-06-22 22:46:32 -04:00
parent ff0a5e281d
commit c13ca927c2

View file

@ -191,6 +191,47 @@ Must be set before loading use-package."
"\\s-+\\(" lisp-mode-symbol-regexp "\\)"))
2)))
(defvar use-package-form-regexp "^\\s-*(\\s-*use-package\\s-+\\_<%s\\_>"
"Regexp used in `use-package-jump-to-package-form' to find use
package forms in user files.")
(defun use-package--find-require (package)
"Find file that required PACKAGE by searching
`load-history'. Returns an absolute file path or nil if none is
found."
(catch 'suspect
(dolist (filespec load-history)
(dolist (entry (cdr filespec))
(when (equal entry (cons 'require package))
(throw 'suspect (car filespec)))))))
(defun use-package-jump-to-package-form (package)
"Attempt to find and jump to the `use-package' form that loaded
PACKAGE. This will only find the form if that form actually
required PACKAGE. If PACKAGE was previously required then this
function will jump to the file that orginally required PACKAGE
instead."
(interactive (list (completing-read "Package: " features)))
(let* ((package (if (stringp package) (intern package) package))
(requiring-file (use-package--find-require package))
file location)
(if (null requiring-file)
(user-error "Can't find file that requires this feature.")
(setq file (if (string= (file-name-extension requiring-file) "elc")
(concat (file-name-sans-extension requiring-file) ".el")
requiring-file))
(when (file-exists-p file)
(find-file-other-window file)
(save-excursion
(goto-char (point-min))
(setq location
(re-search-forward
(format use-package-form-regexp package) nil t)))
(if (null location)
(message "No use-package form found.")
(goto-char location)
(beginning-of-line))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Utility functions