clojure-emacs / cider

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

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

Open filipesilva opened 7 months ago

filipesilva commented 7 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 7 months ago

Thanks! The Expected behavior seems a reasonable expectation.

bbatsov commented 7 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 7 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 7 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 7 months ago

'Append' would seem better to me since:

yuhan0 commented 7 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 7 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 7 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.

narimiran commented 1 week ago

Any progress on this?

One more situation where the current behavior is problematic is if you have code on the line right below the one you are trying to evaluate, e.g.:

(put-at [3 4 5] 1)
(put-at [3 4 5] 2)

Evaluating the first line to comment, you get this:

(put-at [3 4 5] 1)
;; => [() (3 4 5)](put-at [3 4 5] 2)

Notice that, on the other hand, cider-pprint-eval-last-sexp-to-comment correctly adds a newline every time it is invoked.