Skip to content

Commit c374b18

Browse files
authored
cider-pprint-eval-last-sexp: use error overlays to indicate failure (#3558)
* `cider-pprint-eval-last-sexp`, `cider-eval-last-sexp-to-repl`, `cider-pprint-eval-last-sexp-to-repl`: use error overlays to indicate failure This also avoids showing an empty `*cider-result*` buffer. Fixes #3553
1 parent c60d2db commit c374b18

File tree

2 files changed

+107
-47
lines changed

2 files changed

+107
-47
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
- Improves performance for completions- and info-related functionality.
99
- Updates [Orchard](https://github.com/clojure-emacs/orchard/blob/v0.18.0/CHANGELOG.md#0180-2023-10-30)
1010
- Improves various Inspector presentational aspects.
11+
- [#3553](https://github.com/clojure-emacs/cider/issues/3553): `cider-pprint-eval-last-sexp`, `cider-eval-last-sexp-to-repl`, `cider-pprint-eval-last-sexp-to-repl`: use error overlays to indicate failure.
12+
- this also avoids showing an empty `*cider-result*` buffer.
1113
- [#3554](https://github.com/clojure-emacs/cider/issues/3554): CIDER macroexpand: handle errors more gracefully.
1214

1315
### Bugs fixed

cider-eval.el

Lines changed: 105 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -746,24 +746,46 @@ evaluation command. Honor `cider-auto-jump-to-error'."
746746

747747

748748
;;; Interactive evaluation handlers
749-
(defun cider-insert-eval-handler (&optional buffer)
750-
"Make an nREPL evaluation handler for the BUFFER.
749+
(defun cider-insert-eval-handler (&optional buffer bounds source-buffer on-success-callback)
750+
"Make an nREPL evaluation handler for the BUFFER,
751+
BOUNDS representing the buffer bounds of the evaled input,
752+
SOURCE-BUFFER the original buffer,
753+
and ON-SUCCESS-CALLBACK an optional callback.
754+
751755
The handler simply inserts the result value in BUFFER."
752756
(let ((eval-buffer (current-buffer))
753-
(res ""))
757+
(res "")
758+
(failed nil))
754759
(nrepl-make-response-handler (or buffer eval-buffer)
760+
;; value handler:
755761
(lambda (_buffer value)
756762
(with-current-buffer buffer
757763
(insert value))
758764
(when cider-eval-register
759765
(setq res (concat res value))))
766+
;; stdout handler:
760767
(lambda (_buffer out)
761768
(cider-repl-emit-interactive-stdout out))
769+
;; stderr handler:
762770
(lambda (_buffer err)
771+
(setq failed t)
772+
(when (and source-buffer
773+
(listp bounds)) ;; if it's a list, it represents bounds, otherwise it's a string (code) and we can't display the overlay
774+
(with-current-buffer source-buffer
775+
(let* ((phase (cider--error-phase-of-last-exception buffer))
776+
(end (or (car-safe (cdr-safe bounds)) bounds))
777+
(end (when end
778+
(copy-marker end))))
779+
(cider--maybe-display-error-as-overlay phase err end))))
780+
763781
(cider-handle-compilation-errors err eval-buffer))
782+
;; done handler:
764783
(lambda (_buffer)
765784
(when cider-eval-register
766-
(set-register cider-eval-register res))))))
785+
(set-register cider-eval-register res))
786+
(when (and (not failed)
787+
on-success-callback)
788+
(funcall on-success-callback))))))
767789

768790
(defun cider--emit-interactive-eval-output (output repl-emit-function)
769791
"Emit output resulting from interactive code evaluation.
@@ -841,6 +863,24 @@ and the suffix matched by `cider-module-info-regexp'."
841863
"")
842864
(string-trim)))
843865

866+
(defun cider--maybe-display-error-as-overlay (phase err end)
867+
"Possibly display ERR as an overlay honoring END,
868+
depending on the PHASE."
869+
(when (or
870+
;; if we won't show *cider-error*, because of configuration, the overlay is adequate because it compensates for the lack of info in a compact manner:
871+
(not cider-show-error-buffer)
872+
(not (cider-connection-has-capability-p 'jvm-compilation-errors))
873+
;; if we won't show *cider-error*, because of an ignored phase, the overlay is adequate:
874+
(and cider-show-error-buffer
875+
(member phase cider-clojure-compilation-error-phases)))
876+
;; Display errors as temporary overlays
877+
(let ((cider-result-use-clojure-font-lock nil)
878+
(trimmed-err (funcall cider-inline-error-message-function err)))
879+
(cider--display-interactive-eval-result trimmed-err
880+
'error
881+
end
882+
'cider-error-overlay-face))))
883+
844884
(declare-function cider-inspect-last-result "cider-inspector")
845885
(defun cider-interactive-eval-handler (&optional buffer place)
846886
"Make an interactive eval handler for BUFFER.
@@ -867,21 +907,8 @@ when `cider-auto-inspect-after-eval' is non-nil."
867907
(cider-emit-interactive-eval-err-output err)
868908

869909
(let ((phase (cider--error-phase-of-last-exception buffer)))
870-
(when (or
871-
;; if we won't show *cider-error*, because of configuration, the overlay is adequate because it compensates for the lack of info in a compact manner:
872-
(not cider-show-error-buffer)
873-
(not (cider-connection-has-capability-p 'jvm-compilation-errors))
874-
;; if we won't show *cider-error*, because of an ignored phase, the overlay is adequate:
875-
(and cider-show-error-buffer
876-
(member phase cider-clojure-compilation-error-phases)))
877-
;; Display errors as temporary overlays
878-
(let ((cider-result-use-clojure-font-lock nil)
879-
(trimmed-err (funcall cider-inline-error-message-function err)))
880-
(cider--display-interactive-eval-result
881-
trimmed-err
882-
'error
883-
end
884-
'cider-error-overlay-face)))
910+
911+
(cider--maybe-display-error-as-overlay phase err end)
885912

886913
(cider-handle-compilation-errors err
887914
eval-buffer
@@ -1018,24 +1045,51 @@ COMMENT-POSTFIX is the text to output after the last line."
10181045
(lambda (_buffer warning)
10191046
(setq res (concat res warning))))))
10201047

1021-
(defun cider-popup-eval-handler (&optional buffer)
1022-
"Make a handler for printing evaluation results in popup BUFFER.
1048+
(defun cider-popup-eval-handler (&optional buffer bounds source-buffer)
1049+
"Make a handler for printing evaluation results in popup BUFFER,
1050+
BOUNDS representing the buffer bounds of the evaled input,
1051+
and SOURCE-BUFFER the original buffer
1052+
10231053
This is used by pretty-printing commands."
10241054
;; NOTE: cider-eval-register behavior is not implemented here for performance reasons.
10251055
;; See https://github.com/clojure-emacs/cider/pull/3162
1026-
(nrepl-make-response-handler
1027-
(or buffer (current-buffer))
1028-
(lambda (buffer value)
1029-
(cider-emit-into-popup-buffer buffer (ansi-color-apply value) nil t))
1030-
(lambda (_buffer out)
1031-
(cider-emit-interactive-eval-output out))
1032-
(lambda (_buffer err)
1033-
(cider-emit-interactive-eval-err-output err))
1034-
nil
1035-
nil
1036-
nil
1037-
(lambda (buffer warning)
1038-
(cider-emit-into-popup-buffer buffer warning 'font-lock-warning-face t))))
1056+
(let ((chosen-buffer (or buffer (current-buffer))))
1057+
(nrepl-make-response-handler
1058+
chosen-buffer
1059+
;; value handler:
1060+
(lambda (buffer value)
1061+
(cider-emit-into-popup-buffer buffer (ansi-color-apply value) nil t))
1062+
;; stdout handler:
1063+
(lambda (_buffer out)
1064+
(cider-emit-interactive-eval-output out))
1065+
;; stderr handler:
1066+
(lambda (buffer err)
1067+
(cider-emit-interactive-eval-err-output err)
1068+
(when (and source-buffer
1069+
(listp bounds)) ;; if it's a list, it represents bounds, otherwise it's a string (code) and we can't display the overlay
1070+
(with-current-buffer source-buffer
1071+
(let* ((phase (cider--error-phase-of-last-exception buffer))
1072+
(end (or (car-safe (cdr-safe bounds)) bounds))
1073+
(end (when end
1074+
(copy-marker end))))
1075+
(cider--maybe-display-error-as-overlay phase err end)))))
1076+
;; done handler:
1077+
nil
1078+
;; eval-error handler:
1079+
(lambda ()
1080+
(when (and (buffer-live-p chosen-buffer)
1081+
(member (buffer-name chosen-buffer)
1082+
cider-ancillary-buffers))
1083+
(with-selected-window (get-buffer-window chosen-buffer)
1084+
(cider-popup-buffer-quit-function t)))
1085+
;; also call the default nrepl-err-handler, so that our custom behavior doesn't void the base behavior:
1086+
(when nrepl-err-handler
1087+
(funcall nrepl-err-handler)))
1088+
;; content type handler:
1089+
nil
1090+
;; truncated handler:
1091+
(lambda (buffer warning)
1092+
(cider-emit-into-popup-buffer buffer warning 'font-lock-warning-face t)))))
10391093

10401094

10411095
;;; Interactive valuation commands
@@ -1325,27 +1379,31 @@ If INSERT-BEFORE is non-nil, insert before the form, otherwise afterwards."
13251379

13261380
(declare-function cider-switch-to-repl-buffer "cider-mode")
13271381

1382+
(defun cider--eval-last-sexp-to-repl (switch-to-repl request-map)
1383+
"Evaluate the expression preceding point and insert its result in the REPL,
1384+
honoring SWITCH-TO-REPL, REQUEST-MAP."
1385+
(let ((bounds (cider-last-sexp 'bounds)))
1386+
(cider-interactive-eval nil
1387+
(cider-insert-eval-handler (cider-current-repl)
1388+
bounds
1389+
(current-buffer)
1390+
(lambda ()
1391+
(when switch-to-repl
1392+
(cider-switch-to-repl-buffer))))
1393+
bounds
1394+
request-map)))
1395+
13281396
(defun cider-eval-last-sexp-to-repl (&optional prefix)
13291397
"Evaluate the expression preceding point and insert its result in the REPL.
13301398
If invoked with a PREFIX argument, switch to the REPL buffer."
13311399
(interactive "P")
1332-
(cider-interactive-eval nil
1333-
(cider-insert-eval-handler (cider-current-repl))
1334-
(cider-last-sexp 'bounds)
1335-
(cider--nrepl-pr-request-map))
1336-
(when prefix
1337-
(cider-switch-to-repl-buffer)))
1400+
(cider--eval-last-sexp-to-repl prefix (cider--nrepl-pr-request-map)))
13381401

13391402
(defun cider-pprint-eval-last-sexp-to-repl (&optional prefix)
13401403
"Evaluate expr before point and insert its pretty-printed result in the REPL.
13411404
If invoked with a PREFIX argument, switch to the REPL buffer."
13421405
(interactive "P")
1343-
(cider-interactive-eval nil
1344-
(cider-insert-eval-handler (cider-current-repl))
1345-
(cider-last-sexp 'bounds)
1346-
(cider--nrepl-print-request-map fill-column))
1347-
(when prefix
1348-
(cider-switch-to-repl-buffer)))
1406+
(cider--eval-last-sexp-to-repl prefix (cider--nrepl-print-request-map fill-column)))
13491407

13501408
(defun cider-eval-print-last-sexp (&optional pretty-print)
13511409
"Evaluate the expression preceding point.
@@ -1363,7 +1421,7 @@ With an optional PRETTY-PRINT prefix it pretty-prints the result."
13631421
"Pretty print FORM in popup buffer."
13641422
(let* ((buffer (current-buffer))
13651423
(result-buffer (cider-popup-buffer cider-result-buffer nil 'clojure-mode 'ancillary))
1366-
(handler (cider-popup-eval-handler result-buffer)))
1424+
(handler (cider-popup-eval-handler result-buffer form buffer)))
13671425
(with-current-buffer buffer
13681426
(cider-interactive-eval (when (stringp form) form)
13691427
handler

0 commit comments

Comments
 (0)