(defvar-local backtrace-view nil
"A plist describing how to render backtrace frames.
-Possible entries are :show-flags, :show-locals and :print-circle.")
+Possible entries are :show-flags, :show-locals, :print-circle
+and :print-gensym.")
(defvar-local backtrace-insert-header-function nil
"Function for inserting a header for the current Backtrace buffer.
(define-key map "p" 'backtrace-backward-frame)
(define-key map "v" 'backtrace-toggle-locals)
(define-key map "#" 'backtrace-toggle-print-circle)
+ (define-key map ":" 'backtrace-toggle-print-gensym)
(define-key map "s" 'backtrace-goto-source)
(define-key map "\C-m" 'backtrace-help-follow-symbol)
(define-key map "+" 'backtrace-multi-line)
:active (backtrace-get-index)
:selected (plist-get (backtrace-get-view) :show-locals)
:help "Show or hide the local variables for the frame at point"]
+ ["Show Circular Structures" backtrace-toggle-print-circle
+ :style toggle
+ :active (backtrace-get-index)
+ :selected (plist-get (backtrace-get-view) :print-circle)
+ :help
+ "Condense or expand shared or circular structures in the frame at point"]
+ ["Show Uninterned Symbols" backtrace-toggle-print-gensym
+ :style toggle
+ :active (backtrace-get-index)
+ :selected (plist-get (backtrace-get-view) :print-gensym)
+ :help
+ "Toggle unique printing of uninterned symbols in the frame at point"]
["Expand \"...\"s" backtrace-expand-ellipses
:help "Expand all the abbreviated forms in the current frame"]
["Show on Multiple Lines" backtrace-multi-line
`(let ((print-escape-control-characters t)
(print-escape-newlines t)
(print-circle (plist-get ,view :print-circle))
+ (print-gensym (plist-get ,view :print-gensym))
(standard-output (current-buffer)))
,@body))
(defun backtrace-toggle-print-circle (&optional all)
"Toggle `print-circle' for the backtrace frame at point.
-With prefix argument ALL, toggle the value of :print-circle in
-`backtrace-view', which affects all of the backtrace frames in
-the buffer."
+With prefix argument ALL, toggle the default value bound to
+`print-circle' for all the frames in the buffer."
(interactive "P")
(backtrace--toggle-feature :print-circle all))
+(defun backtrace-toggle-print-gensym (&optional all)
+ "Toggle `print-gensym' for the backtrace frame at point.
+With prefix argument ALL, toggle the default value bound to
+`print-gensym' for all the frames in the buffer."
+ (interactive "P")
+ (backtrace--toggle-feature :print-gensym all))
+
(defun backtrace--toggle-feature (feature all)
"Toggle FEATURE for the current backtrace frame or for the buffer.
FEATURE should be one of the options in `backtrace-view'. If ALL
(goto-char (point-min))
(while (and (not (eql index (backtrace-get-index)))
(< (point) (point-max)))
- (goto-char (backtrace-get-frame-end)))))
- (let ((index (backtrace-get-index)))
- (unless index
- (user-error "Not in a stack frame"))
- (backtrace--set-feature feature
- (not (plist-get (backtrace-get-view) feature))))))
+ (goto-char (backtrace-get-frame-end))))
+ (message "%s is now %s for all frames"
+ (substring (symbol-name feature) 1) value))
+ (unless (backtrace-get-index)
+ (user-error "Not in a stack frame"))
+ (let ((value (not (plist-get (backtrace-get-view) feature))))
+ (backtrace--set-feature feature value)
+ (message "%s is now %s for this frame"
+ (substring (symbol-name feature) 1) value))))
(defun backtrace--set-feature (feature value)
"Set FEATURE in the view plist of the frame at point to VALUE.
(should (string-match-p results
(backtrace-tests--get-substring (point-min) (point-max)))))))
+(ert-deftest backtrace-tests--print-gensym ()
+ "Backtrace buffers can toggle `print-gensym' syntax."
+ (ert-with-test-buffer (:name "print-gensym")
+ (let* ((print-gensym nil)
+ (arg (list (gensym "first") (gensym) (gensym "last")))
+ (results (backtrace-tests--make-regexp
+ (backtrace-tests--result arg)))
+ (results-gensym (regexp-quote (let ((print-gensym t))
+ (backtrace-tests--result arg))))
+ (last-frame (backtrace-tests--make-regexp
+ (format (nth (1- backtrace-tests--line-count)
+ (backtrace-tests--backtrace-lines))
+ arg)))
+ (last-frame-gensym (regexp-quote
+ (let ((print-gensym t))
+ (format (nth (1- backtrace-tests--line-count)
+ (backtrace-tests--backtrace-lines))
+ arg)))))
+ (backtrace-tests--make-backtrace arg)
+ (backtrace-print)
+ (should (string-match-p results
+ (backtrace-tests--get-substring (point-min) (point-max))))
+ ;; Go to the last frame.
+ (goto-char (point-max))
+ (forward-line -1)
+ ;; Turn on print-gensym for that frame.
+ (backtrace-toggle-print-gensym)
+ (should (string-match-p last-frame-gensym
+ (backtrace-tests--get-substring (point) (point-max))))
+ ;; Turn off print-gensym for the frame.
+ (backtrace-toggle-print-gensym)
+ (should (string-match-p last-frame
+ (backtrace-tests--get-substring (point) (point-max))))
+ (should (string-match-p results
+ (backtrace-tests--get-substring (point-min) (point-max))))
+ ;; Turn print-gensym on for the buffer.
+ (backtrace-toggle-print-gensym '(4))
+ (should (string-match-p last-frame-gensym
+ (backtrace-tests--get-substring (point) (point-max))))
+ (should (string-match-p results-gensym
+ (backtrace-tests--get-substring (point-min) (point-max))))
+ ;; Turn print-gensym off.
+ (backtrace-toggle-print-gensym '(4))
+ (should (string-match-p last-frame
+ (backtrace-tests--get-substring
+ (point) (+ (point) (length last-frame)))))
+ (should (string-match-p results
+ (backtrace-tests--get-substring (point-min) (point-max)))))))
+
(defun backtrace-tests--make-regexp (str)
"Make regexp from STR for `backtrace-tests--print-circle'.
Used for results of printing circular objects without