commit cc270e0e0753cfd16d172cc9e6d3e415fc93122f
parent a2fe48573173341fdeed9991b7c62702bc1fee0e
Author: Wilfred Hughes <me@wilfred.me.uk>
Date: Fri, 6 Jul 2018 16:08:16 +0100
Merge pull request #134 from Wilfred/fix_repeated_calls
Fix repeated calls
Diffstat:
| M | helpful.el | | | 120 | +++++++++++++++++++++++++++++++++---------------------------------------------- |
| M | test/unit-test.el | | | 20 | +++++++++++++------- |
2 files changed, 63 insertions(+), 77 deletions(-)
diff --git a/helpful.el b/helpful.el
@@ -353,7 +353,7 @@ source code to primitives."
(and (consp fn-end)
(eq (car fn-end) 'edebug-enter))))))
-(defun helpful--can-edebug-p (sym callable-p)
+(defun helpful--can-edebug-p (sym callable-p buf pos)
"Can we use edebug with SYM?"
(and
;; SYM must be a function.
@@ -362,11 +362,7 @@ source code to primitives."
(not (helpful--primitive-p sym callable-p))
;; We need to be able to find its definition, or we can't step
;; through the source.
- (-let* (((buf pos opened) (helpful--definition sym t))
- (have-definition (and buf pos)))
- (when opened
- (kill-buffer buf))
- have-definition)))
+ buf pos))
(defun helpful--toggle-edebug (sym)
"Enable edebug when function SYM is called,
@@ -1036,35 +1032,32 @@ hooks.")
'face 'font-lock-comment-face)
source)))
-(defun helpful--source (sym callable-p)
+(defun helpful--source (sym callable-p buf pos)
"Return the source code of SYM.
If the source code cannot be found, return the sexp used."
(catch 'source
(unless (symbolp sym)
(throw 'source sym))
- (-let (((buf start-pos created) (helpful--definition sym callable-p))
- (source nil))
- (when (and buf start-pos)
+ (let ((source nil))
+ (when (and buf pos)
(with-current-buffer buf
(save-excursion
(save-restriction
- (goto-char start-pos)
+ (goto-char pos)
(narrow-to-defun t)
- ;; If there was a preceding comment, START-POS will be
+ ;; If there was a preceding comment, POS will be
;; after that comment. Move the position to include that comment.
- (setq start-pos (point-min))
+ (setq pos (point-min))
(setq source (buffer-substring-no-properties (point-min) (point-max))))))
(setq source (s-trim-right source))
(when (and source (buffer-file-name buf))
(setq source (propertize source
'helpful-path (buffer-file-name buf)
- 'helpful-pos start-pos
+ 'helpful-pos pos
'helpful-pos-is-start t)))
- (when (and buf created)
- (kill-buffer buf))
(throw 'source source)))
(when callable-p
@@ -1113,6 +1106,12 @@ buffer."
;; variables. It prompts the user, and we discard the buffer
;; afterwards anyway.
(enable-local-variables nil))
+ ;; We shouldn't be called on primitive functions if we don't have
+ ;; a directory of Emacs C sourcecode.
+ (cl-assert
+ (or find-function-C-source-directory
+ (not primitive-p)))
+
(when (and (symbolp sym) callable-p)
(-let [(_ . src-path) (find-function-library sym)]
(setq path src-path)))
@@ -1185,26 +1184,6 @@ buffer."
(error nil))))
(list buf pos opened)))
-(defun helpful--source-path (sym callable-p)
- "Return the path where SYM is defined."
- (-let* (((buf _ opened) (helpful--definition sym callable-p))
- (path nil))
- (when buf
- (setq path (buffer-file-name buf))
- (when opened
- ;; If we've just created this buffer, close it.
- (kill-buffer buf)))
- path))
-
-(defun helpful--source-pos (sym callable-p)
- "Return the file position where SYM is defined."
- (-let (((buf pos opened) (helpful--definition sym callable-p)))
- ;; If we've just created this buffer, close it.
- (when opened
- ;; If we've just created this buffer, close it.
- (kill-buffer buf))
- pos))
-
(defun helpful--reference-positions (sym callable-p buf)
"Return all the buffer positions of references to SYM in BUF."
(-let* ((forms-and-bufs
@@ -1503,15 +1482,11 @@ OBJ may be a symbol or a compiled function object."
'symbol sym
'callable-p callable-p))
-(defun helpful--summary (sym callable-p)
+(defun helpful--summary (sym callable-p buf pos)
"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.
@@ -1584,8 +1559,6 @@ OBJ may be a symbol or a compiled function object."
"defined in C source code")
(t
"without a source file"))))
- (when opened
- (kill-buffer buf))
(s-word-wrap
70
@@ -1697,27 +1670,31 @@ state of the current symbol."
(cl-assert (not (null helpful--sym)))
(unless (buffer-live-p helpful--associated-buffer)
(setq helpful--associated-buffer nil))
- (let* ((inhibit-read-only t)
- (start-line (line-number-at-pos))
- (start-column (current-column))
- (primitive-p (helpful--primitive-p helpful--sym helpful--callable-p))
- (sym-type (cond
- ((not helpful--callable-p) "Variable")
- ((macrop helpful--sym) "Macro")
- (t "Function")))
- (look-for-src (or (not primitive-p)
- find-function-C-source-directory))
- (source (when look-for-src
- (helpful--source helpful--sym helpful--callable-p)))
- (source-path (when (and look-for-src (symbolp helpful--sym))
- (helpful--source-path helpful--sym helpful--callable-p)))
- (references (helpful--calculate-references
- helpful--sym helpful--callable-p
- source-path)))
+ (-let* ((inhibit-read-only t)
+ (start-line (line-number-at-pos))
+ (start-column (current-column))
+ (primitive-p (helpful--primitive-p helpful--sym helpful--callable-p))
+ (sym-type (cond
+ ((not helpful--callable-p) "Variable")
+ ((macrop helpful--sym) "Macro")
+ (t "Function")))
+ (look-for-src (or (not primitive-p)
+ find-function-C-source-directory))
+ ((buf pos opened)
+ (if look-for-src
+ (helpful--definition helpful--sym helpful--callable-p)
+ '(nil nil nil)))
+ (source (when look-for-src
+ (helpful--source helpful--sym helpful--callable-p buf pos)))
+ (source-path (when buf
+ (buffer-file-name buf)))
+ (references (helpful--calculate-references
+ helpful--sym helpful--callable-p
+ source-path)))
(erase-buffer)
- (insert (helpful--summary helpful--sym helpful--callable-p))
+ (insert (helpful--summary helpful--sym helpful--callable-p buf pos))
(when helpful--callable-p
(helpful--insert-section-break)
@@ -1737,8 +1714,8 @@ state of the current symbol."
(when (not helpful--callable-p)
(helpful--insert-section-break)
(let* ((sym helpful--sym)
- (buf (or helpful--associated-buffer (current-buffer)))
- (val (helpful--sym-value sym buf))
+ (val-buf (or helpful--associated-buffer (current-buffer)))
+ (val (helpful--sym-value sym val-buf))
(multiple-views-p
(or (stringp val)
(keymapp val)
@@ -1766,9 +1743,9 @@ state of the current symbol."
"\n\n")
(when multiple-views-p
(insert (helpful--make-toggle-literal-button) " "))
- (when (memq (helpful--sym-value helpful--sym buf) '(nil t))
- (insert (helpful--make-toggle-button helpful--sym buf) " "))
- (insert (helpful--make-set-button helpful--sym buf))
+ (when (memq (helpful--sym-value helpful--sym val-buf) '(nil t))
+ (insert (helpful--make-toggle-button helpful--sym val-buf) " "))
+ (insert (helpful--make-set-button helpful--sym val-buf))
(when (custom-variable-p helpful--sym)
(insert " " (helpful--make-customize-button helpful--sym)))))
@@ -1789,7 +1766,7 @@ state of the current symbol."
(helpful--navigate-button
(file-name-nondirectory source-path)
source-path
- (or (helpful--source-pos helpful--sym helpful--callable-p)
+ (or pos
0)))))
(cond
((and source-path references)
@@ -1827,7 +1804,7 @@ state of the current symbol."
(format "This %s is advised." (downcase sym-type))))
(let ((can-edebug
- (helpful--can-edebug-p helpful--sym helpful--callable-p))
+ (helpful--can-edebug-p helpful--sym helpful--callable-p buf pos))
(can-trace
(and (symbolp helpful--sym)
helpful--callable-p
@@ -1885,7 +1862,7 @@ state of the current symbol."
(helpful--navigate-button
(f-abbrev source-path)
source-path
- (helpful--source-pos helpful--sym helpful--callable-p))
+ pos)
"\n"))
(primitive-p
(concat
@@ -1923,7 +1900,10 @@ state of the current symbol."
(goto-char (point-min))
(forward-line (1- start-line))
- (forward-char start-column)))
+ (forward-char start-column)
+
+ (when opened
+ (kill-buffer buf))))
;; TODO: this isn't sufficient for `edebug-eval-defun'.
(defun helpful--skip-advice (docstring)
diff --git a/test/unit-test.el b/test/unit-test.el
@@ -546,13 +546,15 @@ associated a lambda with a keybinding."
(global-set-key (kbd "C-c M-S-c") nil))
(ert-deftest helpful--source ()
- (let* ((source (helpful--source #'helpful--source t)))
+ (-let* (((buf pos opened) (helpful--definition #'helpful--source t))
+ (source (helpful--source #'helpful--source t buf pos)))
(should
(s-starts-with-p "(defun " source))))
(ert-deftest helpful--source-autoloaded ()
"We should include the autoload cookie."
- (let* ((source (helpful--source #'helpful-at-point t)))
+ (-let* (((buf pos opened) (helpful--definition #'helpful-at-point t))
+ (source (helpful--source #'helpful-at-point t buf pos)))
(should
(s-starts-with-p ";;;###autoload" source))))
@@ -560,10 +562,11 @@ associated a lambda with a keybinding."
"We should return the raw sexp for functions where we can't
find the source code."
(eval '(defun test-foo-defined-interactively () 42))
- (should
- (not
- (null
- (helpful--source #'test-foo-defined-interactively t)))))
+ (-let* (((buf pos opened) (helpful--definition #'test-foo-defined-interactively t)))
+ (should
+ (not
+ (null
+ (helpful--source #'test-foo-defined-interactively t buf pos))))))
(ert-deftest helpful--outer-sexp ()
;; If point is in the middle of a form, we should return its position.
@@ -596,7 +599,10 @@ find the source code."
(ert-deftest helpful--summary--aliases ()
;; exclude the sym itself
"Ensure we mention that a symbol is an alias."
- (let* ((summary (helpful--summary '-select t)))
+ (-let* (((buf pos opened) (helpful--definition '-select t))
+ (summary (helpful--summary '-select t buf pos)))
+ (when opened
+ (kill-buffer buf))
;; Strip properties to make assertion messages more readable.
(set-text-properties 0 (1- (length summary)) nil summary)
(should