tools/eval: add +overlay feature
Now, inline evaluation will display results in an overlay next to the cursor, rather than in the minibuffer (unless it gets too big, in which case it'll use a popup buffer).
This commit is contained in:
parent
c2f6aa3e9d
commit
84a063ca78
7 changed files with 111 additions and 33 deletions
|
@ -76,7 +76,7 @@
|
||||||
;;docker
|
;;docker
|
||||||
;;editorconfig ; let someone else argue about tabs vs spaces
|
;;editorconfig ; let someone else argue about tabs vs spaces
|
||||||
;;ein ; tame Jupyter notebooks with emacs
|
;;ein ; tame Jupyter notebooks with emacs
|
||||||
eval ; run code, run (also, repls)
|
(eval +overlay) ; run code, run (also, repls)
|
||||||
flycheck ; tasing you for every semicolon you forget
|
flycheck ; tasing you for every semicolon you forget
|
||||||
;;flyspell ; tasing you for misspelling mispelling
|
;;flyspell ; tasing you for misspelling mispelling
|
||||||
;;gist ; interacting with github gists
|
;;gist ; interacting with github gists
|
||||||
|
|
|
@ -84,7 +84,7 @@ Small modules that give Emacs access to external tools & services.
|
||||||
+ [[file:tools/direnv/README.org][direnv]]:
|
+ [[file:tools/direnv/README.org][direnv]]:
|
||||||
+ [[file:tools/editorconfig/README.org][editorconfig]]:
|
+ [[file:tools/editorconfig/README.org][editorconfig]]:
|
||||||
+ [[file:tools/ein/README.org][ein]]:
|
+ [[file:tools/ein/README.org][ein]]:
|
||||||
+ [[file:tools/eval/README.org][eval]]: REPL & code evaluation support for a variety of languages
|
+ [[file:tools/eval/README.org][eval]] =+overlay=: REPL & code evaluation support for a variety of languages
|
||||||
+ flycheck: Live error/warning highlights
|
+ flycheck: Live error/warning highlights
|
||||||
+ flyspell: Spell checking
|
+ flyspell: Spell checking
|
||||||
+ gist:
|
+ gist:
|
||||||
|
|
|
@ -7,19 +7,23 @@
|
||||||
(defun +emacs-lisp-eval (beg end)
|
(defun +emacs-lisp-eval (beg end)
|
||||||
"Evaluate a region and print it to the echo area (if one line long), otherwise
|
"Evaluate a region and print it to the echo area (if one line long), otherwise
|
||||||
to a pop up buffer."
|
to a pop up buffer."
|
||||||
(require 'pp)
|
(+eval-display-results
|
||||||
(let ((debug-on-error t)
|
(let* ((buffer-file-name (buffer-file-name (buffer-base-buffer))))
|
||||||
(buffer-file-name (buffer-file-name (buffer-base-buffer)))
|
(string-trim-right
|
||||||
(doom--current-module (ignore-errors (doom-module-from-path buffer-file-name)))
|
(condition-case-unless-debug e
|
||||||
(temp-buffer-show-hook
|
(let ((result
|
||||||
(cons (if (fboundp '+word-wrap-mode)
|
(let ((debug-on-error t))
|
||||||
'+word-wrap-mode
|
(eval (read (buffer-substring-no-properties beg end))
|
||||||
'visual-line-mode)
|
`((buffer-file-name . ,buffer-file-name)
|
||||||
temp-buffer-show-hook)))
|
(doom--current-module
|
||||||
(pp-eval-expression
|
. ,(ignore-errors
|
||||||
(read (buffer-substring-no-properties beg end)))
|
(doom-module-from-path buffer-file-name))))))))
|
||||||
(when-let (win (get-buffer-window "*Pp Eval Output*"))
|
(if (stringp result)
|
||||||
(fit-window-to-buffer win))))
|
result
|
||||||
|
(require 'pp)
|
||||||
|
(pp-to-string result)))
|
||||||
|
(error (error-message-string e)))))
|
||||||
|
(current-buffer)))
|
||||||
|
|
||||||
(defvar +emacs-lisp--face nil)
|
(defvar +emacs-lisp--face nil)
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
|
|
|
@ -18,11 +18,13 @@
|
||||||
- [[Troubleshooting][Troubleshooting]]
|
- [[Troubleshooting][Troubleshooting]]
|
||||||
|
|
||||||
* Description
|
* Description
|
||||||
This modules adds inline code evaluation support to Emacs, and supplies a
|
This modules adds inline code evaluation support to Emacs and a universal
|
||||||
universal interface for opening and interacting with REPLs.
|
interface for opening and interacting with REPLs.
|
||||||
|
|
||||||
** Module Flags
|
** Module Flags
|
||||||
This module has no flags.
|
+ =+overlay= Enables the use of overlays (near the cursor) to display the result
|
||||||
|
of inline code evaluation (rather than the minibuffer). That is, unless the
|
||||||
|
results are too big, in which case it will still fall back to popup buffers.
|
||||||
|
|
||||||
** Plugins
|
** Plugins
|
||||||
+ [[https://github.com/syohex/emacs-quickrun][quickrun]]
|
+ [[https://github.com/syohex/emacs-quickrun][quickrun]]
|
||||||
|
|
|
@ -1,5 +1,51 @@
|
||||||
;;; tools/eval/autoload/eval.el -*- lexical-binding: t; -*-
|
;;; tools/eval/autoload/eval.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +eval-display-results-in-popup (output &optional source-buffer)
|
||||||
|
"Display OUTPUT in a popup buffer."
|
||||||
|
(let ((output-buffer (get-buffer-create "*doom eval*"))
|
||||||
|
(origin (selected-window)))
|
||||||
|
(with-current-buffer output-buffer
|
||||||
|
(setq-local scroll-margin 0)
|
||||||
|
(erase-buffer)
|
||||||
|
(insert output)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(if (fboundp '+word-wrap-mode)
|
||||||
|
(+word-wrap-mode +1)
|
||||||
|
(visual-line-mode +1)))
|
||||||
|
(when-let (win (display-buffer output-buffer))
|
||||||
|
(fit-window-to-buffer win))
|
||||||
|
(select-window origin)
|
||||||
|
output-buffer))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +eval-display-results-in-overlay (output &optional source-buffer)
|
||||||
|
"Display OUTPUT in a floating overlay next to the cursor."
|
||||||
|
(let ((this-command #'+eval/buffer-or-region)
|
||||||
|
eros-overlays-use-font-lock)
|
||||||
|
(with-current-buffer (or source-buffer (current-buffer))
|
||||||
|
(eros--make-result-overlay output
|
||||||
|
:where (line-end-position)
|
||||||
|
:duration eros-eval-result-duration))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +eval-display-results (output &optional source-buffer)
|
||||||
|
"Display OUTPUT in an overlay or a popup buffer."
|
||||||
|
(funcall (if (and (or current-prefix-arg
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert output)
|
||||||
|
(>= (count-lines (point-min) (point-max))
|
||||||
|
+eval-overlay-max-lines)))
|
||||||
|
(require 'eros nil t))
|
||||||
|
#'+eval-display-results-in-popup
|
||||||
|
#'+eval-display-results-in-overlay)
|
||||||
|
output source-buffer)
|
||||||
|
output)
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Commands
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +eval/buffer ()
|
(defun +eval/buffer ()
|
||||||
"Evaluate the whole buffer."
|
"Evaluate the whole buffer."
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
;;; tools/eval/config.el -*- lexical-binding: t; -*-
|
;;; tools/eval/config.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(defvar +eval-overlay-max-lines 4
|
||||||
|
"The output height threshold (inclusive) before output is displayed in a popup
|
||||||
|
buffer rather than an overlay on the line at point.")
|
||||||
|
|
||||||
;; remove ellipsis when printing sexps in message buffer
|
;; remove ellipsis when printing sexps in message buffer
|
||||||
(setq eval-expression-print-length nil
|
(setq eval-expression-print-length nil
|
||||||
eval-expression-print-level nil)
|
eval-expression-print-level nil)
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Packages
|
;;; Packages
|
||||||
|
|
||||||
(set-popup-rule!
|
(set-popup-rule!
|
||||||
(lambda (bufname _)
|
(lambda (bufname _)
|
||||||
|
@ -26,15 +30,6 @@
|
||||||
|
|
||||||
(set-popup-rule! "^\\*quickrun" :size 0.3 :ttl 0)
|
(set-popup-rule! "^\\*quickrun" :size 0.3 :ttl 0)
|
||||||
|
|
||||||
(defadvice! +eval--quickrun-auto-close-a (&rest _)
|
|
||||||
"Allows us to silently re-run quickrun from within the quickrun buffer."
|
|
||||||
:before '(quickrun quickrun-region)
|
|
||||||
(when-let (win (get-buffer-window quickrun--buffer-name))
|
|
||||||
(let ((inhibit-message t))
|
|
||||||
(quickrun--kill-running-process)
|
|
||||||
(message ""))
|
|
||||||
(delete-window win)))
|
|
||||||
|
|
||||||
(defadvice! +eval--quickrun-fix-evil-visual-region-a ()
|
(defadvice! +eval--quickrun-fix-evil-visual-region-a ()
|
||||||
"Make `quickrun-replace-region' recognize evil visual selections."
|
"Make `quickrun-replace-region' recognize evil visual selections."
|
||||||
:override #'quickrun--outputter-replace-region
|
:override #'quickrun--outputter-replace-region
|
||||||
|
@ -51,17 +46,47 @@
|
||||||
(insert output))
|
(insert output))
|
||||||
(setq quickrun-option-outputter quickrun--original-outputter))))
|
(setq quickrun-option-outputter quickrun--original-outputter))))
|
||||||
|
|
||||||
|
(defadvice! +eval--quickrun-auto-close-a (&rest _)
|
||||||
|
"Silently re-create the quickrun popup when re-evaluating."
|
||||||
|
:before '(quickrun quickrun-region)
|
||||||
|
(when-let (win (get-buffer-window quickrun--buffer-name))
|
||||||
|
(let ((inhibit-message t))
|
||||||
|
(quickrun--kill-running-process)
|
||||||
|
(message ""))
|
||||||
|
(delete-window win)))
|
||||||
|
|
||||||
(add-hook! 'quickrun-after-run-hook
|
(add-hook! 'quickrun-after-run-hook
|
||||||
(defun +eval-quickrun-shrink-window-h ()
|
(defun +eval-quickrun-shrink-window-h ()
|
||||||
"Shrink the quickrun output window once code evaluation is complete."
|
"Shrink the quickrun output window once code evaluation is complete."
|
||||||
(when-let (win (get-buffer-window quickrun--buffer-name))
|
(when-let (win (get-buffer-window quickrun--buffer-name))
|
||||||
(with-selected-window (get-buffer-window quickrun--buffer-name)
|
(with-selected-window (get-buffer-window quickrun--buffer-name)
|
||||||
(let ((ignore-window-parameters t))
|
(let ((ignore-window-parameters t))
|
||||||
(shrink-window-if-larger-than-buffer))))))
|
(shrink-window-if-larger-than-buffer)))))
|
||||||
|
|
||||||
(add-hook! 'quickrun-after-run-hook
|
|
||||||
(defun +eval-quickrun-scroll-to-bof-h ()
|
(defun +eval-quickrun-scroll-to-bof-h ()
|
||||||
"Ensures window is scrolled to BOF on invocation."
|
"Ensures window is scrolled to BOF on invocation."
|
||||||
(when-let (win (get-buffer-window quickrun--buffer-name))
|
(when-let (win (get-buffer-window quickrun--buffer-name))
|
||||||
(with-selected-window win
|
(with-selected-window win
|
||||||
(goto-char (point-min)))))))
|
(goto-char (point-min))))))
|
||||||
|
|
||||||
|
;; Display evaluation results in an overlay next to the cursor. If the output
|
||||||
|
;; is more than 4 lines long, it is displayed in a popup.
|
||||||
|
(when (featurep! +overlay)
|
||||||
|
(defadvice! +eval--inhibit-quickrun-popup-a (buf cb)
|
||||||
|
:override #'quickrun--pop-to-buffer
|
||||||
|
(setq quickrun--original-buffer (current-buffer))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(setq quickrun-option-outputter #'ignore)
|
||||||
|
(funcall cb)))
|
||||||
|
|
||||||
|
(advice-add #'quickrun--recenter :override #'ignore)
|
||||||
|
(add-hook! 'quickrun-after-run-hook
|
||||||
|
(defun +eval-display-in-popup-overlay-h ()
|
||||||
|
(+eval-display-results
|
||||||
|
(with-current-buffer quickrun--buffer-name
|
||||||
|
(string-trim (buffer-string)))
|
||||||
|
quickrun--original-buffer)))))
|
||||||
|
|
||||||
|
|
||||||
|
(use-package! eros
|
||||||
|
:when (featurep! +overlay)
|
||||||
|
:hook (emacs-lisp-mode . eros-mode))
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
;;; tools/eval/packages.el
|
;;; tools/eval/packages.el
|
||||||
|
|
||||||
(package! quickrun)
|
(package! quickrun)
|
||||||
|
(when (featurep! +overlay)
|
||||||
|
(package! eros))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue