commit 2c8feeb3ff818606b15ca08ad90e2116afef001c
parent 850c316513558a0ced66f004cd8825a209755bfc
Author: Wilfred Hughes <me@wilfred.me.uk>
Date: Sun, 12 Aug 2018 17:28:56 -0700
Clearly separate library names from absolute paths
We need an absolute path for opening the file, but
`find-function-search-for-symbol` expects a relative path for
primitive functions.
Using the library name allows us to avoid `find-function-C-source`,
which doesn't support Rust primitives. This should fix Remacs support.
See discussion in
https://github.com/Wilfred/remacs/pull/800
Diffstat:
2 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/helpful.el b/helpful.el
@@ -1111,14 +1111,19 @@ If the source code cannot be found, return the sexp used."
(or (assoc sym completions)
(assoc-string sym completions))))
-(defun helpful--find-library-name (path)
- "A wrapper around `find-library-name' that returns nil if PATH
-has no library with that name.
-
-This can happen when users have installed Emacs without its
-source code: they have e.g. org.elc but no org.el."
- (condition-case _err
- (find-library-name path)
+(defun helpful--library-path (library-name)
+ "Find the absolute path for the source of LIBRARY-NAME.
+
+LIBRARY-NAME takes the form \"foo.el\" , \"foo.el\" or
+\"src/foo.c\".
+
+If .elc files exist without the corresponding .el, return nil."
+ (when (member (f-ext library-name) '("c" "rs"))
+ (setq library-name
+ (f-expand library-name
+ (f-parent find-function-C-source-directory))))
+ (condition-case nil
+ (find-library-name library-name)
(error nil)))
(defun helpful--definition (sym callable-p)
@@ -1132,7 +1137,7 @@ POS is the position of the start of the definition within the
buffer."
(let ((initial-buffers (buffer-list))
(primitive-p (helpful--primitive-p sym callable-p))
- (path nil)
+ (library-name nil)
(buf nil)
(pos nil)
(opened nil)
@@ -1149,22 +1154,17 @@ buffer."
(not primitive-p)))
(when (and (symbolp sym) callable-p)
- (-let [(_ . src-path) (find-function-library sym)]
- (setq path src-path)))
- (when (and primitive-p path find-function-C-source-directory)
- ;; Convert relative to absolute path.
- (setq path (f-expand path
- (f-parent find-function-C-source-directory))))
+ (setq library-name (cdr (find-function-library sym))))
(cond
((and (not (symbolp sym)) (functionp sym))
(list nil nil nil))
- ((and callable-p path)
+ ((and callable-p library-name)
;; Convert foo.elc to foo.el.
- (-when-let (src-path (helpful--find-library-name path))
- ;; Open `path' ourselves, so we can widen before searching.
+ (-when-let (src-path (helpful--library-path library-name))
+ ;; Open `src-path' ourselves, so we can widen before searching.
;;
- ;; Opening large.c files can be slow (e.g. when looking at
+ ;; Opening large .c files can be slow (e.g. when looking at
;; `defalias'), especially if the user has configured mode hooks.
;;
;; Bind `auto-mode-alist' to nil, so we open the buffer in
@@ -1193,9 +1193,7 @@ buffer."
(save-restriction
(widen)
(setq pos
- (if primitive-p
- (cdr (find-function-C-source sym path nil))
- (cdr (find-function-search-for-symbol sym nil path)))))))))
+ (cdr (find-function-search-for-symbol sym nil library-name))))))))
(callable-p
;; Functions defined interactively may have an edebug property
;; that contains the location of the definition.
diff --git a/test/helpful-unit-test.el b/test/helpful-unit-test.el
@@ -295,6 +295,14 @@ symbol (not a form)."
(skip-unless find-function-C-source-directory)
(helpful--definition 'default-directory nil))
+(ert-deftest helpful--definition-special-form ()
+ "Ensure we find the position of special forms."
+ (skip-unless find-function-C-source-directory)
+ (-let [(buf pos _)
+ (helpful--definition 'if t)]
+ (should buf)
+ (should pos)))
+
(setq helpful-var-without-defvar 'foo)
(ert-deftest helpful--definition-no-defvar ()