]> git.eshelyaron.com Git - emacs.git/commitdiff
Add function use-package-jump-to-package-form
authorJustin Burkett <justin@burkett.cc>
Thu, 23 Jun 2016 02:46:32 +0000 (22:46 -0400)
committerJustin Burkett <justin@burkett.cc>
Thu, 23 Jun 2016 03:18:14 +0000 (23:18 -0400)
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.

lisp/use-package/use-package.el

index 8c47678117de0aeea29b4e37543bc96a354cb774..a5195146df87319a6cc293c060b717b01af963dc 100644 (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