]> code.delx.au - gnu-emacs/blobdiff - lisp/emacs-lisp/find-func.el
Merge from origin/emacs-25
[gnu-emacs] / lisp / emacs-lisp / find-func.el
index 3bbf8091a9e6d694b7274b7c1c2456659902b009..4a7b7109106dfb69e9a295a06730167b16c233d9 100644 (file)
@@ -43,6 +43,8 @@
 
 ;;; Code:
 
+(require 'seq)
+
 ;;; User variables:
 
 (defgroup find-function nil
@@ -111,7 +113,7 @@ should insert the feature name."
   ;; (point-min), which is acceptable in this case.
   :type 'regexp
   :group 'xref
-  :version "25.0")
+  :version "25.1")
 
 (defcustom find-alias-regexp
   "(defalias +'%s"
@@ -120,7 +122,7 @@ Note it must contain a `%s' at the place where `format'
 should insert the feature name."
   :type 'regexp
   :group 'xref
-  :version "25.0")
+  :version "25.1")
 
 (defvar find-function-regexp-alist
   '((nil . find-function-regexp)
@@ -182,15 +184,15 @@ See the functions `find-function' and `find-variable'."
 LIBRARY should be a string (the name of the library)."
   ;; If the library is byte-compiled, try to find a source library by
   ;; the same name.
-  (if (string-match "\\.el\\(c\\(\\..*\\)?\\)\\'" library)
-      (setq library (replace-match "" t t library)))
+  (when (string-match "\\.el\\(c\\(\\..*\\)?\\)\\'" library)
+    (setq library (replace-match "" t t library)))
   (or
    (locate-file library
-               (or find-function-source-path load-path)
-               (find-library-suffixes))
+                (or find-function-source-path load-path)
+                (find-library-suffixes))
    (locate-file library
-               (or find-function-source-path load-path)
-               load-file-rep-suffixes)
+                (or find-function-source-path load-path)
+                load-file-rep-suffixes)
    (when (file-name-absolute-p library)
      (let ((rel (find-library--load-name library)))
        (when rel
@@ -201,8 +203,44 @@ LIBRARY should be a string (the name of the library)."
           (locate-file rel
                        (or find-function-source-path load-path)
                        load-file-rep-suffixes)))))
+   (find-library--from-load-path library)
    (error "Can't find library %s" library)))
 
+(defun find-library--from-load-path (library)
+  ;; In `load-history', the file may be ".elc", ".el", ".el.gz", and
+  ;; LIBRARY may be "foo.el" or "foo", so make sure that we get all
+  ;; potential matches, and then see whether any of them lead us to an
+  ;; ".el" or an ".el.gz" file.
+  (let* ((elc-regexp "\\.el\\(c\\(\\..*\\)?\\)\\'")
+         (suffix-regexp
+          (concat "\\("
+                  (mapconcat 'regexp-quote (find-library-suffixes) "\\'\\|")
+                  "\\|" elc-regexp "\\)\\'"))
+         (potentials
+          (mapcar
+           (lambda (entry)
+             (if (string-match suffix-regexp (car entry))
+                 (replace-match "" t t (car entry))
+               (car entry)))
+           (seq-filter
+            (lambda (entry)
+              (string-match
+               (concat "\\`"
+                       (regexp-quote
+                        (replace-regexp-in-string suffix-regexp "" library))
+                       suffix-regexp)
+               (file-name-nondirectory (car entry))))
+            load-history)))
+         result)
+    (dolist (file potentials)
+      (dolist (suffix (find-library-suffixes))
+        (when (not result)
+          (cond ((file-exists-p file)
+                 (setq result file))
+                ((file-exists-p (concat file suffix))
+                 (setq result (concat file suffix)))))))
+    result))
+
 (defvar find-function-C-source-directory
   (let ((dir (expand-file-name "src" source-directory)))
     (if (file-accessible-directory-p dir) dir))
@@ -366,8 +404,10 @@ signal an error.
 
 If VERBOSE is non-nil, and FUNCTION is an alias, display a
 message about the whole chain of aliases."
-  (let ((def (if (symbolp function)
-                 (find-function-advised-original function)))
+  (let ((def (when (symbolp function)
+               (or (fboundp function)
+                   (signal 'void-function (list function)))
+               (find-function-advised-original function)))
         aliases)
     ;; FIXME for completeness, it might be nice to print something like:
     ;; foo (which is advised), which is an alias for bar (which is advised).