[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] scratch/backtrace-mode 2276cc2 05/11: Lazily print backtra
From: |
Gemini Lasswell |
Subject: |
[Emacs-diffs] scratch/backtrace-mode 2276cc2 05/11: Lazily print backtrace frame local variables |
Date: |
Sun, 15 Jul 2018 15:06:18 -0400 (EDT) |
branch: scratch/backtrace-mode
commit 2276cc2dad28040781ae21409cafd71549ddb385
Author: Gemini Lasswell <address@hidden>
Commit: Gemini Lasswell <address@hidden>
Lazily print backtrace frame local variables
Instead of printing the local variables for all frames when the
backtrace buffer is created, print them when they are first made
visible. Add a prefix argument to backtrace-toggle-locals to toggle
locals display for the entire buffer.
* lisp/emacs-lisp/backtrace.el (backtrace-view): Mention
:show-locals in docstring.
(backtrace-get-frame-end): Handle the possibility that the locals
section might not exist.
(backtrace-toggle-locals): Add prefix argument to toggle visibility of
locals for the whole buffer.
(backtrace--with-output-variables): Move before first use.
(backtrace--set-frame-locals-visible): New function.
(backtrace--set-locals-visible-overlay): New function.
(backtrace--set-locals-visible): Deleted.
(backtrace-toggle-print-circle): Remove TODO comment.
(backtrace--print-locals): Skip printing the locals if they are not
visible.
---
lisp/emacs-lisp/backtrace.el | 127 ++++++++++++++++++++++++++++---------------
1 file changed, 84 insertions(+), 43 deletions(-)
diff --git a/lisp/emacs-lisp/backtrace.el b/lisp/emacs-lisp/backtrace.el
index 5fc436e..a8759c1 100644
--- a/lisp/emacs-lisp/backtrace.el
+++ b/lisp/emacs-lisp/backtrace.el
@@ -142,7 +142,8 @@ This should be a list of `backtrace-frame' objects.")
(defvar-local backtrace-view nil
"A plist describing how to render backtrace frames.
-Possible entries are :show-flags, :do-xrefs and :print-circle.")
+Possible entries are :show-flags, :show-locals, :do-xrefs and
+:print-circle.")
;; TODO not used yet, maybe for Edebug
;; (defvar-local backtrace-printer #'backtrace-print-frame
@@ -287,24 +288,74 @@ It runs `backtrace-revert-hook', then calls
`backtrace-print'."
(run-hooks 'backtrace-revert-hook)
(backtrace-print t))
-(defun backtrace-toggle-locals ()
- "Toggle the display of local variables for the backtrace frame at point.
-TODO with argument, toggle all frames."
- (interactive)
- (let ((index (backtrace-get-index)))
- (unless index
- (user-error "Not in a stack frame"))
- (let ((pos (point)))
- (goto-char (backtrace-get-frame-start))
- (while (and (eq index (backtrace-get-index))
- (not (eq (backtrace-get-section) 'locals)))
- (goto-char (next-single-property-change (point) 'backtrace-section)))
- (let ((end (backtrace-get-section-end)))
- (backtrace--set-locals-visible (point) end (invisible-p (point)))
-
- (goto-char (if (invisible-p pos) end pos))))))
+(defmacro backtrace--with-output-variables (view &rest body)
+ "Bind output variables according to VIEW and execute BODY."
+ (declare (indent 1))
+ `(let ((print-escape-control-characters t)
+ (print-escape-newlines t)
+ (print-circle (plist-get ,view :print-circle))
+ (standard-output (current-buffer)))
+ ,@body))
-(defun backtrace--set-locals-visible (beg end visible)
+(defun backtrace-toggle-locals (&optional all)
+ "Toggle the display of local variables for the backtrace frame at point.
+With prefix argument ALL, toggle the value of :show-locals in
+`backtrace-view', which affects all of the backtrace frames in
+the buffer."
+ (interactive "P")
+ (if all
+ (let ((pos (make-marker))
+ (visible (not (plist-get backtrace-view :show-locals))))
+ (plist-put backtrace-view :show-locals visible)
+ (set-marker-insertion-type pos t)
+ (set-marker pos (point))
+ (goto-char (point-min))
+ ;; Skip the header.
+ (unless (backtrace-get-index)
+ (goto-char (backtrace-get-frame-end)))
+ (while (< (point) (point-max))
+ (backtrace--set-frame-locals-visible visible)
+ (goto-char (backtrace-get-frame-end)))
+ (goto-char pos)
+ (when (invisible-p pos)
+ (goto-char (backtrace-get-frame-start))))
+ (let ((index (backtrace-get-index)))
+ (unless index
+ (user-error "Not in a stack frame"))
+ (backtrace--set-frame-locals-visible
+ (not (plist-get (backtrace-get-view) :show-locals))))))
+
+(defun backtrace--set-frame-locals-visible (visible)
+ "Set the visibility of the local vars for the frame at point to VISIBLE."
+ (let ((pos (point))
+ (index (backtrace-get-index))
+ (start (backtrace-get-frame-start))
+ (end (backtrace-get-frame-end))
+ (view (copy-sequence (backtrace-get-view)))
+ (inhibit-read-only t))
+ (plist-put view :show-locals visible)
+ (goto-char (backtrace-get-frame-start))
+ (while (not (or (= (point) end)
+ (eq (backtrace-get-section) 'locals)))
+ (goto-char (next-single-property-change (point)
+ 'backtrace-section nil end)))
+ (cond
+ ((and (= (point) end) visible)
+ ;; The locals section doesn't exist so create it.
+ (let ((standard-output (current-buffer)))
+ (backtrace--with-output-variables view
+ (backtrace--print-locals
+ (nth index backtrace-frames) view))
+ (add-text-properties end (point) `(backtrace-index ,index))
+ (goto-char pos)))
+ ((/= (point) end)
+ ;; The locals section does exist, so add or remove the overlay.
+ (backtrace--set-locals-visible-overlay (point) end visible)
+ (goto-char (if (invisible-p pos) start pos))))
+ (add-text-properties start (backtrace-get-frame-end)
+ `(backtrace-view ,view))))
+
+(defun backtrace--set-locals-visible-overlay (beg end visible)
(backtrace--change-button-skip beg end (not visible))
(if visible
(remove-overlays beg end 'invisible t)
@@ -334,7 +385,6 @@ FEATURE should be one of the options in `backtrace-view'.
After toggling the feature, reprint the frame and position
point at the start of the section of the frame it was in
before."
- ;; TODO preserve (in)visibility of locals
(let ((index (backtrace-get-index))
(view (copy-sequence (backtrace-get-view))))
(unless index
@@ -357,15 +407,6 @@ before."
'backtrace-section section)))
(goto-char pos))))))
-(defmacro backtrace--with-output-variables (view &rest body)
- "Bind output variables according to VIEW and execute BODY."
- (declare (indent 1))
- `(let ((print-escape-control-characters t)
- (print-escape-newlines t)
- (print-circle (plist-get ,view :print-circle))
- (standard-output (current-buffer)))
- ,@body))
-
(defun backtrace-expand-ellipsis (button)
"Expand display of the elided form at BUTTON."
;; TODO a command to expand all ... in form at point
@@ -664,21 +705,21 @@ Format it according to VIEW."
(insert "\n")
(put-text-property beg (point) 'backtrace-section 'func)))
-(defun backtrace--print-locals (frame _view)
- "Print a backtrace FRAME's local variables.
-Make them invisible initially."
- (let* ((beg (point))
- (locals (backtrace-frame-locals frame)))
- (if (null locals)
- (insert " [no locals]\n")
- (pcase-dolist (`(,symbol . ,value) locals)
- (insert " ")
- (backtrace--print symbol)
- (insert " = ")
- (insert (backtrace--print-to-string value))
- (insert "\n")))
- (put-text-property beg (point) 'backtrace-section 'locals)
- (backtrace--set-locals-visible beg (point) nil)))
+(defun backtrace--print-locals (frame view)
+ "Print a backtrace FRAME's local variables according to VIEW.
+Print them only if :show-locals is non-nil in the VIEW plist."
+ (when (plist-get view :show-locals)
+ (let* ((beg (point))
+ (locals (backtrace-frame-locals frame)))
+ (if (null locals)
+ (insert " [no locals]\n")
+ (pcase-dolist (`(,symbol . ,value) locals)
+ (insert " ")
+ (backtrace--print symbol)
+ (insert " = ")
+ (insert (backtrace--print-to-string value))
+ (insert "\n")))
+ (put-text-property beg (point) 'backtrace-section 'locals))))
(defun backtrace--print (obj)
"Attempt to print OBJ using `backtrace-print-function'.
- [Emacs-diffs] branch scratch/backtrace-mode created (now fb3578b), Gemini Lasswell, 2018/07/15
- [Emacs-diffs] scratch/backtrace-mode db5f876 08/11: Add link in backtraces to position in buffer being evaluated (bug#14081), Gemini Lasswell, 2018/07/15
- [Emacs-diffs] scratch/backtrace-mode 2ed27cf 07/11: Add links in backtraces to functions written in C (bug#25393), Gemini Lasswell, 2018/07/15
- [Emacs-diffs] scratch/backtrace-mode 86f69ed 04/11: Initialize backtrace display options in backtrace-mode, Gemini Lasswell, 2018/07/15
- [Emacs-diffs] scratch/backtrace-mode 2e73307 10/11: Change keybinding for backtrace-collapse from '=' to '-', Gemini Lasswell, 2018/07/15
- [Emacs-diffs] scratch/backtrace-mode 923d3a6 06/11: Add prefix argument to backtrace-toggle-print-circle, Gemini Lasswell, 2018/07/15
- [Emacs-diffs] scratch/backtrace-mode 2276cc2 05/11: Lazily print backtrace frame local variables,
Gemini Lasswell <=
- [Emacs-diffs] scratch/backtrace-mode 3c4f9e9 02/11: Add methods for strings to cl-print, Gemini Lasswell, 2018/07/15
- [Emacs-diffs] scratch/backtrace-mode 8d270bd 01/11: Support ellipsis expansion in cl-print, Gemini Lasswell, 2018/07/15
- [Emacs-diffs] scratch/backtrace-mode fb3578b 11/11: Add new command to expand all "..."s in a backtrace frame, Gemini Lasswell, 2018/07/15
- [Emacs-diffs] scratch/backtrace-mode 425cb61 09/11: Add more tests for backtrace-mode, Gemini Lasswell, 2018/07/15
- [Emacs-diffs] scratch/backtrace-mode 6c62b9e 03/11: Add backtrace-mode and use it in the debugger, ERT and Edebug, Gemini Lasswell, 2018/07/15