summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
authorLars Ingebrigtsen <larsi@gnus.org>2016-05-01 18:38:07 +0200
committerLars Ingebrigtsen <larsi@gnus.org>2016-05-01 18:38:07 +0200
commitce98b0b1ab20a1b5a0fe85c8b118b34d3b3cf274 (patch)
treeb990694b4689c7ff51ae0e5f1bfe394a0eefdb88 /lisp/emacs-lisp
parentbf0b6fab032bd35fae36f7371b7cd1fe3bfaaac7 (diff)
downloademacs-ce98b0b1ab20a1b5a0fe85c8b118b34d3b3cf274.tar.gz
emacs-ce98b0b1ab20a1b5a0fe85c8b118b34d3b3cf274.tar.bz2
emacs-ce98b0b1ab20a1b5a0fe85c8b118b34d3b3cf274.zip
Allow finding libraries loaded manually outside the load-path
* lisp/emacs-lisp/find-func.el (find-library--from-load-path): New function to find a library from a load path (bug#5661). (find-library-name): Use it. There are so many combinations of inputs and possibly entries in `load-history' that the code looks like an entry in a code obfuscation contest. If anybody has a better implementation, please substitute. But remember that the input given may be foo, foo.el, foo.elc, and the entries in load-history may be foo.el, foo.elc and foo.el.gz, and we want to return only foo.el and foo.el.gz. *phew*
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/find-func.el48
1 files changed, 42 insertions, 6 deletions
diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el
index 3bbf8091a9e..c625fd345c9 100644
--- a/lisp/emacs-lisp/find-func.el
+++ b/lisp/emacs-lisp/find-func.el
@@ -182,15 +182,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 +201,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))