tools/eval: associate plist with repl handlers
Also consolidates all REPLs (opened through the :tools eval module) under one popup rule, which inhibits ESC from prematurely closing them (#1944), and cleans up after their buffers *only* if their handlers weren't specified to :persist, e.g. (set-repl-handler! 'some-mode #'some-repl-handler :persist t) Also standardized ESS's REPL commands.
This commit is contained in:
parent
e6094f262f
commit
0b67251159
9 changed files with 71 additions and 47 deletions
|
@ -3,10 +3,12 @@
|
|||
(defvar +eval-repl-buffers (make-hash-table :test 'equal)
|
||||
"The buffer of the last open repl.")
|
||||
|
||||
(defvar-local +eval-repl-plist nil)
|
||||
|
||||
(define-minor-mode +eval-repl-mode
|
||||
"A minor mode for REPL buffers.")
|
||||
|
||||
(defun +eval--ensure-in-repl-buffer (&optional command displayfn)
|
||||
(defun +eval--ensure-in-repl-buffer (&optional fn plist displayfn)
|
||||
(maphash (lambda (key buffer)
|
||||
(unless (buffer-live-p buffer)
|
||||
(remhash key +eval-repl-buffers)))
|
||||
|
@ -21,14 +23,16 @@
|
|||
buffer
|
||||
(setq buffer
|
||||
(save-window-excursion
|
||||
(if (commandp command)
|
||||
(call-interactively command)
|
||||
(funcall command))))
|
||||
(if (commandp fn)
|
||||
(call-interactively fn)
|
||||
(funcall fn))))
|
||||
(cond ((null buffer)
|
||||
(error "REPL handler %S couldn't open the REPL buffer" command))
|
||||
(error "REPL handler %S couldn't open the REPL buffer" fn))
|
||||
((not (bufferp buffer))
|
||||
(error "REPL handler %S failed to return a buffer" command)))
|
||||
(error "REPL handler %S failed to return a buffer" fn)))
|
||||
(with-current-buffer buffer
|
||||
(when plist
|
||||
(setq +eval-repl-plist plist))
|
||||
(+eval-repl-mode +1))
|
||||
(puthash key buffer +eval-repl-buffers)
|
||||
buffer)))
|
||||
|
@ -42,11 +46,10 @@
|
|||
buffer)))
|
||||
|
||||
(defun +eval-open-repl (prompt-p &optional displayfn)
|
||||
(let ((command (cdr (assq major-mode +eval-repls)))
|
||||
(region (if (use-region-p)
|
||||
(buffer-substring-no-properties (region-beginning)
|
||||
(region-end)))))
|
||||
(when (or (not command) prompt-p)
|
||||
(cl-destructuring-bind (mode fn . plist)
|
||||
(or (assq major-mode +eval-repls)
|
||||
(list))
|
||||
(when (or (not fn) prompt-p)
|
||||
(let* ((choices (or (cl-loop for sym being the symbols
|
||||
for sym-name = (symbol-name sym)
|
||||
if (string-match "^\\(?:\\+\\)?\\([^/]+\\)/open-\\(?:\\(.+\\)-\\)?repl$" sym-name)
|
||||
|
@ -60,20 +63,27 @@
|
|||
(choice-split (split-string choice " " t))
|
||||
(module (car choice-split))
|
||||
(repl (substring (cadr choice-split) 1 -1)))
|
||||
(setq command
|
||||
(setq fn
|
||||
(intern-soft
|
||||
(format "+%s/open-%srepl" module
|
||||
(if (string= repl "default")
|
||||
""
|
||||
repl))))))
|
||||
(unless (commandp command)
|
||||
(error "Couldn't find a valid REPL for %s" major-mode))
|
||||
(with-current-buffer (+eval--ensure-in-repl-buffer command displayfn)
|
||||
(when (bound-and-true-p evil-mode)
|
||||
(call-interactively #'evil-append-line))
|
||||
(when region
|
||||
(insert region))
|
||||
t)))
|
||||
(let ((region (if (use-region-p)
|
||||
(buffer-substring-no-properties (region-beginning)
|
||||
(region-end)))))
|
||||
(unless (commandp fn)
|
||||
(error "Couldn't find a valid REPL for %s" major-mode))
|
||||
(with-current-buffer (+eval--ensure-in-repl-buffer fn plist displayfn)
|
||||
(when (bound-and-true-p evil-mode)
|
||||
(call-interactively #'evil-append-line))
|
||||
(when region
|
||||
(insert region))
|
||||
t))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun +eval/open-repl-same-window (&optional arg)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue