[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master d6b364e 05/19: Lazily print backtrace frame local v
From: |
Gemini Lasswell |
Subject: |
[Emacs-diffs] master d6b364e 05/19: Lazily print backtrace frame local variables |
Date: |
Fri, 3 Aug 2018 13:32:54 -0400 (EDT) |
branch: master
commit d6b364edfe582be24cb54693c5aaf52c0add22d5
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
local variables display for the entire buffer.
* lisp/emacs-lisp/backtrace.el (backtrace-view): Mention
:show-locals in docstring.
(backtrace-get-section-end): Remove function.
(backtrace-toggle-locals): Add prefix argument.
(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): Remove function.
(backtrace-toggle-feature): Remove TODO comment.
(backtrace--print-locals): Skip printing the locals if they are not
visible.
---
lisp/emacs-lisp/backtrace.el | 134 +++++++++++++++++++++++++++----------------
1 file changed, 83 insertions(+), 51 deletions(-)
diff --git a/lisp/emacs-lisp/backtrace.el b/lisp/emacs-lisp/backtrace.el
index bcff147..b896904 100644
--- a/lisp/emacs-lisp/backtrace.el
+++ b/lisp/emacs-lisp/backtrace.el
@@ -146,7 +146,7 @@ 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 and :print-circle.")
+Possible entries are :show-flags, :show-locals and :print-circle.")
(defvar-local backtrace-insert-header-function nil
"Function for inserting a header for the current Backtrace buffer.
@@ -231,14 +231,6 @@ POS, if omitted or nil, defaults to point."
(next-single-property-change (or pos (point))
'backtrace-index nil (point-max)))
-(defun backtrace-get-section-end (&optional pos)
- "Return the position of the end of the frame section at POS.
-POS, if omitted or nil, defaults to point."
- (let* ((frame-end (backtrace-get-frame-end pos))
- (section-end (next-single-property-change
- (or pos (point)) 'backtrace-section nil frame-end)))
- (min frame-end section-end)))
-
(defun backtrace-forward-frame ()
"Move forward to the beginning of the next frame."
(interactive)
@@ -272,24 +264,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))))
+ (setq backtrace-view (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))
+ (setq view (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)
@@ -319,7 +361,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
@@ -342,15 +383,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
@@ -633,21 +665,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] master updated (e65ec81 -> da0054c), Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master 9aa9d79 07/19: Add links in backtraces to functions written in C (bug#25393), Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master 5b50fa5 04/19: Always make buttons from function names in backtraces, Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master 2ede75c 10/19: Change keybinding for backtrace-collapse from '=' to '-', Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master 8a76209 02/19: Add methods for strings to cl-print, Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master d6b364e 05/19: Lazily print backtrace frame local variables,
Gemini Lasswell <=
- [Emacs-diffs] master eba16e5 01/19: Support ellipsis expansion in cl-print, Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master af5f377 08/19: Add link in backtraces to position in buffer being evaluated (bug#14081), Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master 95b2ab3 18/19: Fix some documentation formatting nits, Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master 58be6cb 17/19: Fix typo in edebug-backtrace-hide-instrumentation's docstring., Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master ca98377 14/19: Add new commands to Edebug backtraces, Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master bb9de87 06/19: Add prefix argument to backtrace-toggle-print-circle, Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master 9879151 12/19: * lisp/emacs-lisp/debug.el (debugger-mode-map): Use easy-menu-define., Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master 1459ad2 13/19: Add a menu for backtrace-mode, Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master 3cd6a68 16/19: Give two backtrace-mode commands better names, Gemini Lasswell, 2018/08/03
- [Emacs-diffs] master 83af893 15/19: Move 'backtrace' from subr.el to backtrace.el, Gemini Lasswell, 2018/08/03