[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/inf-ruby cd50ce8432 249/265: Creating eval overlay feature
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/inf-ruby cd50ce8432 249/265: Creating eval overlay feature |
Date: |
Sat, 9 Jul 2022 21:59:30 -0400 (EDT) |
branch: elpa/inf-ruby
commit cd50ce8432d5ff77ec1b16aaaf75dac316d7acb5
Author: tunnes <ayrton.tunes@outlook.com>
Commit: tunnes <ayrton.tunes@outlook.com>
Creating eval overlay feature
Currently we have the print feature built in inf-ruby mode that inserts the
result of a inferior Ruby evaluation
on the current buffer, but this feature does not provide a similar
experience that we might find on Lisp family
languages so given that we decided on this issue to
https://github.com/nonsequitur/inf-ruby/issues/148 to bring
this feature more close to this behaviour using the Cider overlays
implementation
https://github.com/clojure-emacs/cider/blob/master/cider-eval.el#L829-L844
Also we dicussed about the chain evaluation on Ruby that might by
problematic evaluating onluy the last expression
so to solve that we decided to implement the ruby-send-last-stmt on this
comment
https://github.com/nonsequitur/inf-ruby/issues/148#issuecomment-1007841475,
please noticed that the support to
enh-ruby-mode was not priorized on this first moment but we are open to
community support to improve that.
# Please enter the commit message for your changes. Lines starting
---
inf-ruby.el | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 130 insertions(+), 1 deletion(-)
diff --git a/inf-ruby.el b/inf-ruby.el
index b35f7d9495..2a82f5c4ff 100755
--- a/inf-ruby.el
+++ b/inf-ruby.el
@@ -62,6 +62,7 @@
;;; Code:
+(require 'cl-lib)
(require 'comint)
(require 'compile)
(require 'ruby-mode)
@@ -505,10 +506,138 @@ Must not contain ruby meta characters.")
(comint-send-string (inf-ruby-proc) (concat "\n" term "\n"))
(when print (ruby-print-result))))
+(defface inf-ruby-result-overlay-face
+ '((((class color) (background light)) :background "black" :box (:line-width
-1 :color "yellow")))
+ "Face used to display evaluation results at the end of line.")
+
+;; Overlay
+
+(defun inf-ruby--make-overlay (l r type &rest props)
+ "Place an overlay between L and R and return it.
+TYPE is a symbol put on the overlay's category property. It is
+used to easily remove all overlays from a region with:
+ (remove-overlays start end 'category TYPE)
+PROPS is a plist of properties and values to add to the overlay."
+ (let ((o (make-overlay l (or r l) (current-buffer))))
+ (overlay-put o 'category type)
+ (overlay-put o 'inf-ruby-temporary t)
+ (while props (overlay-put o (pop props) (pop props)))
+ (push #'inf-ruby--delete-overlay (overlay-get o 'modification-hooks))
+ o))
+
+(defun inf-ruby--delete-overlay (ov &rest _)
+ "Safely delete overlay OV.
+Never throws errors, and can be used in an overlay's
+modification-hooks."
+ (ignore-errors (delete-overlay ov)))
+
+(cl-defun inf-ruby--make-result-overlay (value &rest props &key where duration
(type 'result)
+ (format (concat " => %s "))
+ (prepend-face
'inf-ruby-result-overlay-face)
+ &allow-other-keys)
+ "Place an overlay displaying VALUE at the end of line.
+VALUE is used as the overlay's after-string property, meaning it
+is displayed at the end of the overlay. The overlay itself is
+placed from beginning to end of current line.
+Return nil if the overlay was not placed or if it might not be
+visible, and return the overlay otherwise.
+Return the overlay if it was placed successfully, and nil if it
+failed.
+This function takes some optional keyword arguments:
+- If WHERE is a number or a marker, apply the overlay over the
+ entire line at that place (defaulting to `point'). If it is a
+ cons cell, the car and cdr determine the start and end of the
+ overlay.
+- TYPE is passed to `inf-ruby--make-overlay' (defaults to `result').
+- FORMAT is a string passed to `format'. It should have exactly
+ one %s construct (for VALUE).
+All arguments beyond these (PROPS) are properties to be used on
+the overlay."
+ (declare (indent 1))
+ (while (keywordp (car props))
+ (setq props (cddr props)))
+ ;; If the marker points to a dead buffer, don't do anything.
+ (let ((buffer (cond
+ ((markerp where) (marker-buffer where))
+ ((markerp (car-safe where)) (marker-buffer (car where)))
+ (t (current-buffer)))))
+ (with-current-buffer buffer
+ (save-excursion
+ (when (number-or-marker-p where)
+ (goto-char where))
+ ;; Make sure the overlay is actually at the end of the sexp.
+ (skip-chars-backward "\r\n[:blank:]")
+ (let* ((beg (if (consp where)
+ (car where)
+ (save-excursion
+ (backward-sexp 1)
+ (point))))
+ (end (if (consp where)
+ (cdr where)
+ (line-end-position)))
+ (display-string (format format value))
+ (o nil))
+ (remove-overlays beg end 'category type)
+ (funcall #'put-text-property
+ 0 (length display-string)
+ 'face prepend-face
+ display-string)
+ ;; If the display spans multiple lines or is very long, display it at
+ ;; the beginning of the next line.
+ (when (or (string-match "\n." display-string)
+ (> (string-width display-string)
+ (- (window-width) (current-column))))
+ (setq display-string (concat " \n" display-string)))
+ ;; Put the cursor property only once we're done manipulating the
+ ;; string, since we want it to be at the first char.
+ (put-text-property 0 1 'cursor 0 display-string)
+ (when (> (string-width display-string) (* 3 (window-width)))
+ (setq display-string
+ (concat (substring display-string 0 (* 3 (window-width)))
+ "...\nResult truncated.")))
+ ;; Create the result overlay.
+ (setq o (apply #'inf-ruby--make-overlay
+ beg end type
+ 'after-string display-string
+ props))
+ (pcase duration
+ ((pred numberp) (run-at-time duration nil
#'inf-ruby--delete-overlay o))
+ (`command (if this-command
+ (add-hook 'pre-command-hook
+ #'inf-ruby--remove-result-overlay
+ nil 'local)
+ (inf-ruby--remove-result-overlay))))
+ (let ((win (get-buffer-window buffer)))
+ ;; Left edge is visible.
+ (when (and win
+ (<= (window-start win) (point))
+ ;; In 24.3 `<=' is still a binary predicate.
+ (<= (point) (window-end win))
+ ;; Right edge is visible. This is a little conservative
+ ;; if the overlay contains line breaks.
+ (or (< (+ (current-column) (string-width value))
+ (window-width win))
+ (not truncate-lines)))
+ o)))))))
+
+(defun inf-ruby--remove-result-overlay ()
+ "Remove result overlay from current buffer.
+This function also removes itself from `pre-command-hook'."
+ (remove-hook 'pre-command-hook #'inf-ruby--remove-result-overlay 'local)
+ (remove-overlays nil nil 'category 'result))
+
+(defun inf-ruby--eval-overlay (value)
+ "Make overlay for VALUE at POINT."
+ (inf-ruby--make-result-overlay (format "%S" value)
+ :where (point)
+ :duration 'command)
+ value)
+
+
(defun ruby-print-result ()
"Print the result of the last evaluation in the current buffer."
(let ((proc (inf-ruby-proc)))
- (insert
+ (inf-ruby--eval-overlay
(with-current-buffer (or (inf-ruby-buffer)
inf-ruby-buffer)
(while (not (and comint-last-prompt
- [nongnu] elpa/inf-ruby f6a6b89e08 161/265: Adapting code to use looking-at over re-search-forward., (continued)
- [nongnu] elpa/inf-ruby f6a6b89e08 161/265: Adapting code to use looking-at over re-search-forward., ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 505a7bc140 170/265: Merge pull request #84 from janpath/patch-1, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 4d82095424 174/265: inf-ruby-console-gem: Only try to load Ruby files, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 4f6a265640 178/265: Add support for zeus console, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby af4f238ef4 200/265: Merge pull request #99 from dgopstein/master, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 4893dd6426 208/265: Describe how to add custom prompt patterns (#108), ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 49d59a7897 216/265: Merge pull request #115 from p-sdk/add-ruby-send-and-go-commands, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby a4c766e605 231/265: Use pry_instance, _pry_ is not in Pry 0.13 anymore, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 9f0f79ff45 232/265: inf-ruby-console-rails: Try to handle IRB's "multiline" thing here, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby c2a28ef6a1 242/265: Replace toggle-read-only-mode with read-only-mode, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby cd50ce8432 249/265: Creating eval overlay feature,
ELPA Syncer <=
- [nongnu] elpa/inf-ruby 57642c27fd 053/265: inf-ruby-completions: support non-"current" inf-ruby-mode buffers and Pry, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 33e17e055f 037/265: Move keys to a new minor mode, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 91bbd7763d 071/265: Avoid error when trying to switch to non-existing inf-ruby buffer, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 54508a9923 011/265: Mac OS: Fix completion output splitting for Ruby 1.8.7 compatibility., ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 74e96360b1 034/265: Added macruby to inf-ruby-implementations, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby a7bb5f99e3 013/265: Pesky header stuff., ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 164f2dda53 065/265: Add commands to launch different types of consoles, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby d776551688 087/265: Add pry to inf-ruby-implementations, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 28b84de084 122/265: Advertise using the .pryrc workaround, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 562fa9a422 094/265: Close #37, ELPA Syncer, 2022/07/09