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:
@@ -12,9 +12,13 @@
|
|||||||
buffers. Indeed, this implies a single REPL per language per project. Is this
|
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.")
|
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
|
(define-minor-mode syd-repl-mode
|
||||||
"A minor mode for repl buffers. One use is to universally customise the
|
"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 ()
|
(defun syd--repl-from-major-mode ()
|
||||||
"TODO:"
|
"TODO:"
|
||||||
@@ -29,19 +33,36 @@ not-alive buffer."
|
|||||||
(remhash repl-key +syd-repl-buffers)))
|
(remhash repl-key +syd-repl-buffers)))
|
||||||
+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.
|
"Call REPL-HANDLER, and error out if it does not return a buffer.
|
||||||
|
|
||||||
REPL-HANDLER will be called interactively if supported."
|
REPL-HANDLER will be called interactively if supported."
|
||||||
(let ((repl-buffer (save-window-excursion
|
(let ((repl-buffer
|
||||||
(if (commandp repl-handler)
|
(if (buffer-live-p maybe-repl-buffer)
|
||||||
(call-interactively repl-handler)
|
maybe-repl-buffer
|
||||||
(funcall repl-handler)))))
|
(let ((repl-buffer*
|
||||||
(cond ((null repl-buffer)
|
(save-window-excursion
|
||||||
(error "REPL handler %S couldn't open the REPL buffer" repl-handler))
|
(if (commandp repl-handler)
|
||||||
((not (bufferp repl-buffer))
|
(call-interactively repl-handler)
|
||||||
(error "REPL handler %S failed to return a buffer" repl-handler))
|
(funcall repl-handler)))))
|
||||||
(t repl-buffer))))
|
(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 ()
|
(defun syd--goto-end-of-repl ()
|
||||||
"Move point to the last comint prompt or the end of the buffer."
|
"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."
|
PLIST is a plist of repl-specific options."
|
||||||
(syd--clean-repl-buffers)
|
(syd--clean-repl-buffers)
|
||||||
(let* ((root (syd-project-root))
|
(let* ((repl-key (syd--get-repl-key))
|
||||||
(repl-key (cons major-mode root))
|
|
||||||
(maybe-repl-buffer (gethash repl-key +syd-repl-buffers)))
|
(maybe-repl-buffer (gethash repl-key +syd-repl-buffers)))
|
||||||
(cl-check-type maybe-repl-buffer (or buffer null))
|
(cl-check-type maybe-repl-buffer (or buffer null))
|
||||||
(unless (or (eq maybe-repl-buffer (current-buffer))
|
(unless (or (eq maybe-repl-buffer (current-buffer))
|
||||||
(null repl-handler))
|
(null repl-handler))
|
||||||
(let* ((repl-buffer (if (buffer-live-p maybe-repl-buffer)
|
(let* ((repl-buffer (syd--call-repl-handler repl-handler
|
||||||
maybe-repl-buffer
|
plist
|
||||||
(syd--call-repl-handler repl-handler)))
|
maybe-repl-buffer))
|
||||||
(displayed-repl-buffer (funcall display-fn repl-buffer)))
|
(displayed-repl-buffer (funcall display-fn repl-buffer)))
|
||||||
;; Repl buffers are to be saved in `+syd-repl-buffers'; we've just
|
(when (bufferp displayed-repl-buffer)
|
||||||
;; opened one, so do so!
|
(with-current-buffer displayed-repl-buffer
|
||||||
(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)
|
|
||||||
(syd--goto-end-of-repl))
|
(syd--goto-end-of-repl))
|
||||||
repl-buffer)))))
|
displayed-repl-buffer)))))
|
||||||
|
|
||||||
(defun syd--known-repls ()
|
(defun syd--known-repls ()
|
||||||
"Return a list of all known mode-repl pairs, each as a two-element list.
|
"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!
|
(set-popup-rule!
|
||||||
(lambda (bufname _)
|
(lambda (bufname _)
|
||||||
(when (boundp 'syd-repl-mode)
|
(pp bufname)
|
||||||
(buffer-local-value 'syd-repl-mode (get-buffer bufname))))
|
(with-current-buffer bufname
|
||||||
:ttl (lambda (buf)
|
(pp (boundp 'syd-repl-mode))
|
||||||
(unless (plist-get +eval-repl-plist :persist)
|
(pp syd-repl-mode))
|
||||||
(when-let (process (get-buffer-process buf))
|
(when (boundp 'syd-repl-mode)
|
||||||
(set-process-query-on-exit-flag process nil)
|
(buffer-local-value 'syd-repl-mode (get-buffer bufname))))
|
||||||
(kill-process process)
|
:ttl (lambda (buf)
|
||||||
(kill-buffer buf))))
|
(unless (plist-get syd-repl-plist :persist)
|
||||||
:size 0.25
|
(when-let (process (get-buffer-process buf))
|
||||||
:quit nil)
|
(set-process-query-on-exit-flag process nil)
|
||||||
|
(kill-process process)
|
||||||
|
(kill-buffer buf))))
|
||||||
|
:size 0.25
|
||||||
|
:quit nil)
|
||||||
|
|
||||||
(provide 'syd-handle-repl)
|
(provide 'syd-handle-repl)
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ adjustment.")
|
|||||||
(when (featurep 'evil)
|
(when (featurep 'evil)
|
||||||
;; For maximum escape coverage in emacs state buffers; this only works in
|
;; For maximum escape coverage in emacs state buffers; this only works in
|
||||||
;; GUI Emacs, in tty Emacs use C-g instead
|
;; GUI Emacs, in tty Emacs use C-g instead
|
||||||
(define-key map [escape] #'doom/escape))
|
(define-key map [escape] #'syd/escape))
|
||||||
map)
|
map)
|
||||||
"Active keymap in popup windows. See `doom-popup-buffer-mode'.")
|
"Active keymap in popup windows. See `doom-popup-buffer-mode'.")
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,39 @@ are active.")
|
|||||||
(evil-define-key* syd-alt-leader-key-states map (kbd syd-alt-leader-key) 'syd/leader))
|
(evil-define-key* syd-alt-leader-key-states map (kbd syd-alt-leader-key) 'syd/leader))
|
||||||
(general-override-mode 1))
|
(general-override-mode 1))
|
||||||
|
|
||||||
|
(defvar syd-escape-hook nil
|
||||||
|
"A hook run when C-g is pressed (or ESC in normal mode, for evil users).
|
||||||
|
|
||||||
|
More specifically, when `syd/escape' is pressed. If any hook returns non-nil,
|
||||||
|
all hooks after it are ignored.")
|
||||||
|
|
||||||
|
(defun syd/escape (&optional interactive)
|
||||||
|
"Run `syd-escape-hook'."
|
||||||
|
(interactive (list 'interactive))
|
||||||
|
(let ((inhibit-quit t))
|
||||||
|
(cond ((minibuffer-window-active-p (minibuffer-window))
|
||||||
|
;; quit the minibuffer if open.
|
||||||
|
(when interactive
|
||||||
|
(setq this-command 'abort-recursive-edit))
|
||||||
|
(abort-recursive-edit))
|
||||||
|
;; Run all escape hooks. If any returns non-nil, then stop there.
|
||||||
|
((run-hook-with-args-until-success 'syd-escape-hook))
|
||||||
|
;; don't abort macros
|
||||||
|
((or defining-kbd-macro executing-kbd-macro) nil)
|
||||||
|
;; Back to the default
|
||||||
|
((unwind-protect (keyboard-quit)
|
||||||
|
(when interactive
|
||||||
|
(setq this-command 'keyboard-quit)))))))
|
||||||
|
|
||||||
|
|
||||||
|
(with-eval-after-load 'eldoc
|
||||||
|
(eldoc-add-command 'syd/escape))
|
||||||
|
|
||||||
(defun syd-keybinds-initialise ()
|
(defun syd-keybinds-initialise ()
|
||||||
(syd--initialise-leader)
|
(syd--initialise-leader)
|
||||||
|
|
||||||
|
(global-set-key [remap keyboard-quit] #'syd/escape)
|
||||||
|
|
||||||
;; Buffer
|
;; Buffer
|
||||||
(require 'syd-buffers)
|
(require 'syd-buffers)
|
||||||
(general-def
|
(general-def
|
||||||
|
|||||||
Reference in New Issue
Block a user