branch: elpa/flamegraph
commit 1839b6daa19ffc15bff626671c42979f524ba55f
Author: Dmitry Gutov <[email protected]>
Commit: Dmitry Gutov <[email protected]>
Support RET on code snippet lines
---
flamegraph.el | 38 ++++++++++++++++++++++++++++++--------
test/flamegraph-tests.el | 23 +++++++++++++++++++++++
2 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/flamegraph.el b/flamegraph.el
index a098c289e6..b3134a44a6 100644
--- a/flamegraph.el
+++ b/flamegraph.el
@@ -557,12 +557,33 @@ necessarily its definition."
(string-trim-right (substring entry 0 (match-beginning 0)) "[ (:-]+")
(flamegraph--entry-name entry)))
-(defun flamegraph--snippet-line (n marked)
+(defvar-keymap flamegraph--snippet-line-map
+ :doc "Keymap active on source snippet lines."
+ "RET" #'flamegraph--snippet-visit-source)
+
+(defun flamegraph--snippet-visit-source ()
+ "Visit the source line described by text properties at point."
+ (interactive)
+ (let ((path (get-text-property (point) 'flamegraph-source-path))
+ (line (get-text-property (point) 'flamegraph-source-line)))
+ (when (and path line)
+ (flamegraph--visit-file path line))))
+
+(defun flamegraph--snippet-line (path n marked)
"Format buffer line N for the snippet, marking it when MARKED."
- (format " %s %4d %s"
- (if marked "▸" " ")
- n
- (buffer-substring (line-beginning-position) (line-end-position))))
+ (let ((line (format " %s %4d %s
+"
+ (if marked "▸" " ")
+ n
+ (buffer-substring (line-beginning-position)
+ (line-end-position)))))
+ (add-text-properties
+ 0 (length line)
+ `(keymap ,flamegraph--snippet-line-map
+ flamegraph-source-path ,path
+ flamegraph-source-line ,n)
+ line)
+ line))
(defun flamegraph--source-snippet (path line &optional node shown context)
"Return source context around LINE of PATH as a fontified string, or nil.
@@ -628,7 +649,8 @@ defaults to 4."
(let ((prev nil) (out nil))
(dolist (n keep)
(when (and prev (> n (1+ prev)))
- (push " ⋯" out))
+ (push " ⋯
+" out))
(goto-char (point-min))
(forward-line (1- n))
(ignore-errors
@@ -643,9 +665,9 @@ defaults to 4."
(when (and (<= bol rb) (>= eol re))
(add-face-text-property
rb re (flamegraph--call-site-face w))))))
- (push (flamegraph--snippet-line n (= n line)) out)
+ (push (flamegraph--snippet-line path n (= n line)) out)
(setq prev n))
- (mapconcat #'identity (nreverse out) "\n"))))))))
+ (apply #'concat (nreverse out)))))))))
(defun flamegraph--skip-through-p (entry)
"Non-nil if ENTRY is a frame to descend through transparently when
diff --git a/test/flamegraph-tests.el b/test/flamegraph-tests.el
index 4601c9db3b..d118e64343 100644
--- a/test/flamegraph-tests.el
+++ b/test/flamegraph-tests.el
@@ -447,6 +447,29 @@ foo at 100% of outer is hot; bar at 10% is warm."
(should (flamegraph-test--has-face s 'flamegraph-call-site-hot))
(should (flamegraph-test--has-face s 'flamegraph-call-site-warm)))))
+(ert-deftest flamegraph-test-source-snippet-lines-ret-visits-source ()
+ "RET on a snippet source line, including the final EOL, visits that line."
+ (flamegraph-test--with-temp-source path
+ "(defun outer ()
+ (foo)
+ (bar))
+"
+ (let ((snippet (flamegraph--source-snippet path 2 nil))
+ visited)
+ (should snippet)
+ (cl-letf (((symbol-function 'flamegraph--visit-file)
+ (lambda (p l) (setq visited (cons p l)))))
+ (with-temp-buffer
+ (insert snippet)
+ (goto-char (point-min))
+ (re-search-forward " 3 ")
+ (end-of-line)
+ (should-not (button-at (point)))
+ (let ((map (get-text-property (point) 'keymap)))
+ (should map)
+ (call-interactively (lookup-key map (kbd "RET")))))
+ (should (equal visited (cons path 3)))))))
+
;;; Calls-tree rendering — `flamegraph--insert-call-tree'
(defun flamegraph-test--render-call-tree (node ref &optional shown-nodes)