Skip to content

Loading…

Make stacktrace buffer auto-selectable #271

Closed
wants to merge 1 commit into from

2 participants

@hugoduncan
clojure-emacs member

Adds nrepl-error-buffer-select to control selection of the stacktrace popup
window. To make this more useful, the popup buffer now tracks the window and
buffer that were active when the popup opened, and if they are still visible
when the popup closes, then they are re-selected.

@hugoduncan hugoduncan Make stacktrace buffer auto-selectable
Adds nrepl-error-buffer-select to control selection of the stacktrace popup
window.  To make this more useful, the popup buffer now tracks the window
and buffer that were active when the popup opened, and if they are still
visible when the popup closes, then they are re-selected.
866da82
@bbatsov
clojure-emacs member

This code looks very much like some buggy code @kingtim removed a while ago (maybe it's some port from SLIME?). I'll have to take a closer look at the code, but it seems overly complex to me compared to the relative benefit.

@hugoduncan
clojure-emacs member
@bbatsov
clojure-emacs member

Btw, I forgot to refer @kingtim's commit that removed the similar code, that used to be part of nrepl.el 928a3d0

@hugoduncan
clojure-emacs member

The logic that was removed was identical to slime's. The logic in the patch is simpler and tries to control the buffer that is selected when the stack trace closes, rather the buffer that the stacktrace is replaced with.

@bbatsov
clojure-emacs member

Makes sense. Please rebase this PR on top of the current master so we can have it merged.

@bbatsov
clojure-emacs member

@hugoduncan ping :-)

@bbatsov
clojure-emacs member

I'm closing this in favour of 13f6e0d

@bbatsov bbatsov closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 12, 2013
  1. @hugoduncan

    Make stacktrace buffer auto-selectable

    hugoduncan committed
    Adds nrepl-error-buffer-select to control selection of the stacktrace popup
    window.  To make this more useful, the popup buffer now tracks the window
    and buffer that were active when the popup opened, and if they are still
    visible when the popup closes, then they are re-selected.
Showing with 50 additions and 10 deletions.
  1. +2 −0 CHANGELOG.md
  2. +48 −10 nrepl.el
View
2 CHANGELOG.md
@@ -4,6 +4,8 @@
### New features
+* Add nrepl-error-buffer-select to control selection of the stacktrace popup
+ window.
* Add support for multiple nrepl session. A single session is closed with
`M-x nrepl-close`. A repl session is made default with
`M-x nrepl-make-repl-connection-default`.
View
58 nrepl.el
@@ -197,7 +197,7 @@ joined together.")
(defcustom nrepl-popup-stacktraces t
"Non-nil means pop-up error stacktraces for evaluation errors.
-Nil means show only an error message in the minibuffer. See also
+Nil means show only an error message in the minibuffer. See also
`nrepl-popup-stacktraces-in-repl', which overrides this setting
for REPL buffers."
:type 'boolean
@@ -210,6 +210,12 @@ overrides `nrepl-popup-stacktraces' in REPL buffers."
:type 'boolean
:group 'nrepl)
+(defcustom nrepl-error-buffer-select nil
+ "Non-nil means pop-up error stacktraces are selected.
+Nil means the pop-up buffer will not be selected"
+ :type 'boolean
+ :group 'nrepl)
+
(defcustom nrepl-tab-command 'nrepl-indent-and-complete-symbol
"Selects the command to be invoked by the TAB key.
The default option is `nrepl-indent-and-complete-symbol'. If
@@ -787,7 +793,8 @@ DONE-HANDLER as appropriate."
(nrepl-send-string "(if-let [pst+ (clojure.core/resolve 'clj-stacktrace.repl/pst+)]
(pst+ *e) (clojure.stacktrace/print-stack-trace *e))"
(nrepl-make-response-handler
- (nrepl-popup-buffer nrepl-error-buffer)
+ (nrepl-popup-buffer nrepl-error-buffer
+ nrepl-error-buffer-select)
nil
'nrepl-emit-into-color-buffer nil nil) nil session))
(with-current-buffer nrepl-error-buffer
@@ -838,6 +845,13 @@ DONE-HANDLER as appropriate."
(defvar nrepl-popup-buffer-quit-function 'nrepl-popup-buffer-quit
"The function that is used to quit a temporary popup buffer."))
+(defvar nrepl-popup-on-close-data nil
+ "Data used to control actions when closing popup windows.
+It is assigned a buffer local vaule of (POPUP-WINDOW OLD-WINDOW OLD-BUFFER).
+POPUP-WINDOW the window for the popup.
+OLD-WINDOW the window that was current when the popup was displayed.
+OLD-BUFFER the buffer that was in OLD-WINDOW.")
+
(defun nrepl-popup-buffer-quit-function (&optional kill-buffer-p)
"Wrapper to invoke the function `nrepl-popup-buffer-quit-function'.
KILL-BUFFER-P is passed along."
@@ -849,17 +863,41 @@ KILL-BUFFER-P is passed along."
If SELECT is non-nil, select the newly created window"
(with-current-buffer (nrepl-make-popup-buffer name)
(setq buffer-read-only t)
- (let ((new-window (display-buffer (current-buffer))))
- (set-window-point new-window (point))
- (when select
- (select-window new-window))
- (current-buffer))))
+ (nrepl-popup-display-buffer (current-buffer) select)))
+
+(defun nrepl-popup-display-buffer (buffer select)
+ "Displays the popup BUFFER.
+If SELECT is non-nil, select the newly created window."
+ (lexical-let ((old-window (selected-window))
+ (old-buffer (window-buffer)))
+ (with-current-buffer buffer
+ (let ((new-window (display-buffer (current-buffer))))
+ (set-window-point new-window (point))
+ (unless nrepl-popup-on-close-data
+ (set (make-local-variable 'nrepl-popup-on-close-data)
+ (list new-window old-window old-buffer)))
+ (when select
+ (select-window new-window))
+ buffer))))
(defun nrepl-popup-buffer-quit (&optional kill-buffer-p)
- "Quit the current (temp) window and bury its buffer using `quit-window'.
-If prefix argument KILL-BUFFER-P is non-nil, kill the buffer instead of burying it."
+ "Quit the current popup window and bury its buffer using `quit-window'.
+If prefix argument KILL-BUFFER-P is non-nil, kill
+the buffer instead of burying it. If the buffer that raised the
+popup is still visible, then select it."
(interactive)
- (quit-window kill-buffer-p (selected-window)))
+ (if nrepl-popup-on-close-data
+ (destructuring-bind (popup-window old-window old-buffer)
+ nrepl-popup-on-close-data
+ (kill-local-variable 'nrepl-popup-on-close-data)
+ (quit-window kill-buffer-p (selected-window))
+ (message "pq %s %s" (eq popup-window (selected-window)) old-buffer)
+ (when (and (eq popup-window (selected-window)) old-buffer)
+ (when (and old-buffer
+ (window-live-p old-window)
+ (eq old-buffer (window-buffer old-window)))
+ (select-window old-window))))
+ (quit-window kill-buffer-p (selected-window))))
(defun nrepl-make-popup-buffer (name)
"Create a temporary buffer called NAME."
Something went wrong with that request. Please try again.