clojure-emacs / cider

The Clojure Interactive Development Environment that Rocks for Emacs
https://cider.mx
GNU General Public License v3.0
3.52k stars 643 forks source link

cider-pprint-eval-defun-to-comment inside form does not print comments in newline #3639

Open filipesilva opened 2 months ago

filipesilva commented 2 months ago

Expected behavior

;; cider-pprint-eval-defun-to-comment twice, with cursor on 1
(inc 1)
;; => 2
;; => 2

Actual behavior

;; cider-pprint-eval-defun-to-comment twice, with cursor on 1
(inc 1)
;; => 2;; => 2

Steps to reproduce the problem

Write (inc 1) as above. Put cursor on 1, before or after. Run cider-pprint-eval-defun-to-comment twice.

Environment & Version information

CIDER version information

;; CIDER 1.14.0-snapshot (package: 1.14.0-snapshot), nREPL 1.1.1
;; Clojure 1.11.1, Java 21.0.2

Lein / Clojure CLI version

Clojure CLI version 1.11.1.1435

Emacs version

29.2

Operating system

Mac Sonoma 14.4.1

JDK distribution

openjdk 21.0.2 2024-01-16

vemv commented 2 months ago

Thanks! The Expected behavior seems a reasonable expectation.

bbatsov commented 2 months ago

Or probably we should overwrite the first comment, as I don't see much point in inserting multiple comments for evaluation results.

yuhan0 commented 2 months ago

Or probably we should overwrite the first comment, as I don't see much point in inserting multiple comments for evaluation results.

I've had this implemented locally for some time:

(defun cider-maybe-insert-multiline-comment (result comment-prefix continued-prefix comment-postfix)
  "Insert eval RESULT at current location if RESULT is not empty.
RESULT will be preceded by COMMENT-PREFIX.
CONTINUED-PREFIX is inserted for each additional line of output.
COMMENT-POSTFIX is inserted after final text output."
  (unless (string= result "")
    ;; replace existing comment
    (when (and (skip-chars-forward " \t")
               (looking-at-p (regexp-quote cider-comment-prefix)))
      (delete-region (point)
                     (progn (while (and (forward-line 1)
                                        (looking-at-p cider-comment-continued-prefix)))
                            (point))))
    ;; follow indentation
    (clojure-indent-line)
    (let ((lines (split-string result "[\n]+" t))
          (beg (point))
          (col (current-indentation)))
      ;; only the first line gets the normal comment-prefix
      (insert (concat comment-prefix (pop lines)))
      (dolist (elem lines)
        (insert (concat "\n" continued-prefix elem)))
      (unless (string= comment-postfix "")
        (insert comment-postfix))
      (indent-rigidly beg (line-end-position) col))))

But I'm aware it's a bit of a hack and might not work in the odd case where someone set up the prefix/postifix to use #_ or (comment)

filipesilva commented 2 months ago

I've no strong opinion regarding replacing or appending the comment in a newline, but when doing this command outside the form it will append. I guessed this was the right behaviour.

vemv commented 2 months ago

'Append' would seem better to me since:

yuhan0 commented 2 months ago

Sorry if this might be off-topic from the original issue - at least from my usage, the vast majority of the time I'm using eval-to-comment almost like a 'persistent' version of the regular eval overlays. Having to manually 'clean up' the accumulated stacks of comment evals ended up being so annoying that I modified the function as above, and the rare couple of times I do want to append I can simply place a newline above the previous ;; => line that I want to keep around.

Edit: a quick screen capture of what I meant

https://github.com/clojure-emacs/cider/assets/22216124/30f27023-e1b2-42d3-b95e-24ab5c34e083

vemv commented 2 months ago

Yeah there are definitely many ways to use CIDER - for example I tend to send stuff to the repl so that I have a trail of past evals

We could have a defcustom for capturing the two styles of intended behavior.

bbatsov commented 2 months ago

Sorry if this might be off-topic from the original issue - at least from my usage, the vast majority of the time I'm using eval-to-comment almost like a 'persistent' version of the regular eval overlays.

This is the way the feature was intended to be used, therefore my previous comment. But I do acknowledge that different people might have different expectations/use-cases. Perhaps some defcustom is the way to go indeed.