aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilfred Hughes <me@wilfred.me.uk>2018-03-16 20:50:40 +0000
committerWilfred Hughes <me@wilfred.me.uk>2018-03-16 20:50:40 +0000
commitc9a3b0428dcbda6c8f3c3a0926307f2a52cdfd14 (patch)
treeaa8f73e15454ba0b61682e695efa6ecac41d3218
parentd04a7bc38439e97f5c6a9f8bdcb98ef52a6060b8 (diff)
Handle aliases separately
If a symbol is a variable or function alias, say so, and provide a link to the underlying symbol. Ensure the source code is the alias definition, not the definition of the underlying function/variable. Fixes #98
-rw-r--r--CHANGELOG.md5
-rw-r--r--helpful.el70
-rw-r--r--test/unit-test.el15
3 files changed, 65 insertions, 25 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7646b87..e721a00 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# v0.9
+Much better handling of aliases: show aliases differently to their
+underlying symbol, show the `defalias` call in the source code, don't
+show duplicates in the Aliases list, and cross-reference the Elisp
+manual.
+
Fixed an issue when looking at variable docs where we would visit the
definition buffer without the user requesting it.
diff --git a/helpful.el b/helpful.el
index 632a41d..ee99684 100644
--- a/helpful.el
+++ b/helpful.el
@@ -183,23 +183,21 @@ Return SYM otherwise."
(defun helpful--aliases (sym callable-p)
"Return all the aliases for SYM."
- (let ((changed t)
- (canonical (helpful--canonical-symbol sym callable-p))
+ (let ((canonical (helpful--canonical-symbol sym callable-p))
aliases)
- (while changed
- (setq changed nil)
- (mapatoms
- (lambda (s)
- (when (and
- ;; Skip variables that aren't bound, so we're faster.
- (if callable-p (fboundp s) (boundp s))
-
- ;; If this symbol is a new alias for our target sym,
- ;; add it.
- (eq canonical (helpful--canonical-symbol s callable-p))
- (not (-contains-p aliases s)))
- (push s aliases)
- (setq changed t)))))
+ (mapatoms
+ (lambda (s)
+ (when (and
+ ;; Skip variables that aren't bound, so we're faster.
+ (if callable-p (fboundp s) (boundp s))
+
+ ;; If this symbol is a new alias for our target sym,
+ ;; add it.
+ (eq canonical (helpful--canonical-symbol s callable-p))
+
+ ;; Don't include SYM.
+ (not (eq sym s)))
+ (push s aliases))))
(--sort
(string< (symbol-name it) (symbol-name other))
aliases)))
@@ -929,9 +927,7 @@ buffer."
(pos nil)
(opened nil))
(when (and (symbolp sym) callable-p)
- (-let [(base-sym . src-path) (find-function-library sym)]
- ;; `base-sym' is the underlying symbol if `sym' is an alias.
- (setq sym base-sym)
+ (-let [(_ . src-path) (find-function-library sym)]
(setq path src-path)))
(when (and primitive-p path find-function-C-source-directory)
;; Convert "src/foo.c" to "".
@@ -1283,10 +1279,25 @@ OBJ may be a symbol or a compiled function object."
(defun helpful--summary (sym callable-p)
"Return a one sentence summary for SYM."
(-let* ((primitive-p (helpful--primitive-p sym callable-p))
+ (canonical-sym (helpful--canonical-symbol sym callable-p))
+ (alias-p (not (eq canonical-sym sym)))
((buf pos opened)
(if (or (not primitive-p) find-function-C-source-directory)
(helpful--definition sym callable-p)
'(nil nil nil)))
+ (alias-button
+ (if callable-p
+ ;; Show a link to 'defalias' in the manual.
+ (helpful--button
+ "function alias"
+ 'helpful-manual-button
+ 'symbol 'defalias)
+ ;; Show a link to the variable aliases section in the
+ ;; manual.
+ (helpful--button
+ "alias"
+ 'helpful-info-button
+ 'info-node "(elisp)Variable Aliases")))
(interactive-button
(helpful--button
"interactive"
@@ -1307,6 +1318,10 @@ OBJ may be a symbol or a compiled function object."
(help-fns--autoloaded-p sym (buffer-file-name buf))))
(description
(cond
+ (alias-p
+ (format "%s %s"
+ (if callable-p "a" "an")
+ alias-button))
((and callable-p (commandp sym) autoloaded-p)
(format "an %s, %s" interactive-button autoload-button))
((and callable-p (commandp sym))
@@ -1317,6 +1332,13 @@ OBJ may be a symbol or a compiled function object."
"a")))
(kind
(cond
+ (alias-p
+ (format "for %s,"
+ (helpful--button
+ (symbol-name canonical-sym)
+ 'helpful-describe-exactly-button
+ 'symbol canonical-sym
+ 'callable-p callable-p)))
((not callable-p) "variable")
((macrop sym) "macro")
(t "function")))
@@ -1338,9 +1360,11 @@ OBJ may be a symbol or a compiled function object."
(when opened
(kill-buffer buf))
- (format "%s is %s %s %s."
- (if (symbolp sym) sym "This lambda")
- description kind defined)))
+ (s-word-wrap
+ 70
+ (format "%s is %s %s %s."
+ (if (symbolp sym) sym "This lambda")
+ description kind defined))))
(defun helpful-update ()
"Update the current *Helpful* buffer to the latest
@@ -1482,7 +1506,7 @@ state of the current symbol."
(insert (helpful--make-forget-button helpful--sym helpful--callable-p))))
(let ((aliases (helpful--aliases helpful--sym helpful--callable-p)))
- (when (> (length aliases) 1)
+ (when aliases
(helpful--insert-section-break)
(insert
(helpful--heading "Aliases")
diff --git a/test/unit-test.el b/test/unit-test.el
index 2a42c10..e06305a 100644
--- a/test/unit-test.el
+++ b/test/unit-test.el
@@ -313,10 +313,10 @@ and that buffer has been killed, handle it gracefully."
(ert-deftest helpful--aliases ()
(should
(equal (helpful--aliases 'null t)
- (list 'not 'null)))
+ (list 'not)))
(should
(equal (helpful--aliases 'emacs-repository-version nil)
- (list 'emacs-bzr-version 'emacs-repository-version))))
+ (list 'emacs-bzr-version))))
(defun helpful-fn-in-elc ())
@@ -405,3 +405,14 @@ associated a lambda with a keybinding."
(equal pos (point)))
(should
(equal subforms '(bar))))))
+
+(ert-deftest helpful--summary--aliases ()
+ ;; exclude the sym itself
+ "Ensure we mention that a symbol is an alias."
+ (let* ((summary (helpful--summary '-select t)))
+ ;; Strip properties to make assertion messages more readable.
+ (set-text-properties 0 (1- (length summary)) nil summary)
+ (should
+ (equal
+ summary
+ "-select is a function alias for -filter, defined in dash.el."))))