fix: Enable syd-repl-mode /before/ displaying the buffer

This ensures that display-buffer-alist predicates can test for repl buffers.
This commit is contained in:
Madeleine Sydney
2025-01-30 03:26:07 -07:00
parent 4a3551ed12
commit d27a3b60ce
3 changed files with 85 additions and 36 deletions

View File

@@ -12,9 +12,13 @@
buffers. Indeed, this implies a single REPL per language per project. Is this
limitation worth overcoming? I'm not sure! I've yet to butt heads with it.")
(defvar-local syd-repl-plist nil)
;;;###autoload
(define-minor-mode syd-repl-mode
"A minor mode for repl buffers. One use is to universally customise the
display of all repl buffers.")
display of all repl buffers."
:after-hook (format "syd-repl-mode after %s" (current-buffer)))
(defun syd--repl-from-major-mode ()
"TODO:"
@@ -29,19 +33,36 @@ not-alive buffer."
(remhash repl-key +syd-repl-buffers)))
+syd-repl-buffers))
(defun syd--call-repl-handler (repl-handler)
(defun syd--get-repl-key ()
(cons major-mode (syd-project-root)))
(defun syd--call-repl-handler (repl-handler &optional plist maybe-repl-buffer)
"Call REPL-HANDLER, and error out if it does not return a buffer.
REPL-HANDLER will be called interactively if supported."
(let ((repl-buffer (save-window-excursion
(if (commandp repl-handler)
(call-interactively repl-handler)
(funcall repl-handler)))))
(cond ((null repl-buffer)
(error "REPL handler %S couldn't open the REPL buffer" repl-handler))
((not (bufferp repl-buffer))
(error "REPL handler %S failed to return a buffer" repl-handler))
(t repl-buffer))))
(let ((repl-buffer
(if (buffer-live-p maybe-repl-buffer)
maybe-repl-buffer
(let ((repl-buffer*
(save-window-excursion
(if (commandp repl-handler)
(call-interactively repl-handler)
(funcall repl-handler)))))
(cond ((null repl-buffer*)
(error "REPL handler %S couldn't open the REPL buffer" repl-handler))
((not (bufferp repl-buffer*))
(error "REPL handler %S failed to return a buffer" repl-handler))
(t repl-buffer*))))))
;; Repl buffers are to be saved in `+syd-repl-buffers'; we've just
;; opened one, so do so.
(puthash (syd--get-repl-key) repl-buffer +syd-repl-buffers)
;; If it isn't a buffer, we return nil.
(when (bufferp repl-buffer)
(with-current-buffer repl-buffer
(when plist
(setq syd-repl-plist plist))
(syd-repl-mode 1))
repl-buffer)))
(defun syd--goto-end-of-repl ()
"Move point to the last comint prompt or the end of the buffer."
@@ -62,25 +83,19 @@ by the given DISPLAY-FN.
PLIST is a plist of repl-specific options."
(syd--clean-repl-buffers)
(let* ((root (syd-project-root))
(repl-key (cons major-mode root))
(let* ((repl-key (syd--get-repl-key))
(maybe-repl-buffer (gethash repl-key +syd-repl-buffers)))
(cl-check-type maybe-repl-buffer (or buffer null))
(unless (or (eq maybe-repl-buffer (current-buffer))
(null repl-handler))
(let* ((repl-buffer (if (buffer-live-p maybe-repl-buffer)
maybe-repl-buffer
(syd--call-repl-handler repl-handler)))
(let* ((repl-buffer (syd--call-repl-handler repl-handler
plist
maybe-repl-buffer))
(displayed-repl-buffer (funcall display-fn repl-buffer)))
;; Repl buffers are to be saved in `+syd-repl-buffers'; we've just
;; opened one, so do so!
(puthash repl-key repl-buffer +syd-repl-buffers)
;; If it isn't a buffer, we return nil.
(when (bufferp repl-buffer)
(with-current-buffer repl-buffer
(syd-repl-mode 1)
(when (bufferp displayed-repl-buffer)
(with-current-buffer displayed-repl-buffer
(syd--goto-end-of-repl))
repl-buffer)))))
displayed-repl-buffer)))))
(defun syd--known-repls ()
"Return a list of all known mode-repl pairs, each as a two-element list.
@@ -154,16 +169,20 @@ prefix argument is given, in which case the user will be prompted for a repl."
(set-popup-rule!
(lambda (bufname _)
(when (boundp 'syd-repl-mode)
(buffer-local-value 'syd-repl-mode (get-buffer bufname))))
:ttl (lambda (buf)
(unless (plist-get +eval-repl-plist :persist)
(when-let (process (get-buffer-process buf))
(set-process-query-on-exit-flag process nil)
(kill-process process)
(kill-buffer buf))))
:size 0.25
:quit nil)
(lambda (bufname _)
(pp bufname)
(with-current-buffer bufname
(pp (boundp 'syd-repl-mode))
(pp syd-repl-mode))
(when (boundp 'syd-repl-mode)
(buffer-local-value 'syd-repl-mode (get-buffer bufname))))
:ttl (lambda (buf)
(unless (plist-get syd-repl-plist :persist)
(when-let (process (get-buffer-process buf))
(set-process-query-on-exit-flag process nil)
(kill-process process)
(kill-buffer buf))))
:size 0.25
:quit nil)
(provide 'syd-handle-repl)