From af5f3771fd49bba579d3a2047bab1b278317eb5f Mon Sep 17 00:00:00 2001 From: Gemini Lasswell Date: Sat, 7 Jul 2018 12:48:18 -0700 Subject: [PATCH] Add link in backtraces to position in buffer being evaluated (bug#14081) * lisp/emacs-lisp/backtrace.el (backtrace-frame): Add buffer field. (backtrace-get-frames): Set buffer field of frame. (backtrace-buffer-pos): New button type. (backtrace--pop-to-buffer-pos): New function. (backtrace--print-func-and-args): Create a button for the buffer position if it is set. --- lisp/emacs-lisp/backtrace.el | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/lisp/emacs-lisp/backtrace.el b/lisp/emacs-lisp/backtrace.el index bec57f29245..aac43fec8e4 100644 --- a/lisp/emacs-lisp/backtrace.el +++ b/lisp/emacs-lisp/backtrace.el @@ -65,7 +65,7 @@ guaranteed." (cl-defstruct (backtrace-frame (:constructor backtrace-make-frame)) - evald fun args flags locals pos) + evald fun args flags locals buffer pos) (cl-defun backtrace-get-frames (&optional base &key (constructor #'backtrace-make-frame)) @@ -102,9 +102,26 @@ frames before its nearest activation frame are discarded." ;; eval-region calls for the same buffer. That's not a very ;; useful case. (with-current-buffer (pop eval-buffers) + (setf (backtrace-frame-buffer frame) (current-buffer)) (setf (backtrace-frame-pos frame) (point)))))) frames)) +;; Button definition for jumping to a buffer position. + +(define-button-type 'backtrace-buffer-pos + 'action #'backtrace--pop-to-buffer-pos + 'help-echo "mouse-2, RET: Show reading position") + +(defun backtrace--pop-to-buffer-pos (button) + "Pop to the buffer and position for the BUTTON at point." + (let* ((buffer (button-get button 'backtrace-buffer)) + (pos (button-get button 'backtrace-pos))) + (if (buffer-live-p buffer) + (progn + (pop-to-buffer buffer) + (goto-char (max (point-min) (min (point-max) pos)))) + (message "Buffer has been killed")))) + ;; Font Locking support (defconst backtrace--font-lock-keywords @@ -685,8 +702,12 @@ Format it according to VIEW." ;; After any frame that uses eval-buffer, insert a comment that ;; states the buffer position it's reading at. (when (backtrace-frame-pos frame) - (insert (format " ; Reading at buffer position %d" - (backtrace-frame-pos frame)))) + (insert " ; Reading at ") + (let ((pos (point))) + (insert (format "buffer position %d" (backtrace-frame-pos frame))) + (make-button pos (point) :type 'backtrace-buffer-pos + 'backtrace-buffer (backtrace-frame-buffer frame) + 'backtrace-pos (backtrace-frame-pos frame)))) (insert "\n") (put-text-property beg (point) 'backtrace-section 'func))) -- 2.39.2