sanel / monroe

Clojure nREPL client for Emacs
161 stars 21 forks source link

Unable to eval forms inside (comment ... ) form. #25

Closed zentrope closed 6 years ago

zentrope commented 6 years ago

I like to use something like this at the bottom of some files:

(comment

  (def spec {:this “that”})

  (defn do-whatever [spec a & as]
    (apply a spec as))
  ;;
)

And, when working at the repl, evaluate some of those forms within the (comment ...) form to set up a REPL session to debug a certain problem.

When I attempt to C-c C-c a form within a (comment ...) form, monroe prints a nil, and the form isn’t evaluated. Is there a way to make this work?

Interestingly, eval-region (C-c C-r) does work.

zentrope commented 6 years ago

The problem is that (end-of-defun) and (beginning-of-defun) in monroe-eval-expression-at-point do the proper thing, which is expand to the entire (comment ...) top-level form and then evaluate it.

What I want to do is evaluate a sexp inside that form.

I’ve added my own function to solve this:

(defun kfi-monroe-eval-previous-sexp-at-point ()
  (interactive)
  (save-excursion
    (let ((end (point)))
      (backward-sexp)
      (monroe-eval-region (point) end))))

(I’m not an Elisp programmer. Perhaps there are better safeguards?)

This is bound to C-c C-e as a means of evaluating the preceding expression, just as C-x C-e does for Emacs lisp. Useful for inspecting inner forms of functions or data structures, turns out.

Maybe add this as an extra evaluative strategy to monroe? If something like this seems a bad fit, I’m happy to close the issue. My use case is solved using the above function.

technomancy commented 6 years ago

I think the problem here is that C-c C-c is bound to a function with a misleading name; it's not actually evaluating the expression at point but the top-level form that the point is currently in, despite being called monroe-eval-expression-at-point.

I also agree that having this function would be useful as an addition to monroe. Defining my own version of that was one of the first things I did after installing monroe.

sanel commented 6 years ago

Thanks @zentrope for catching this. I'm aware of this and (I could say) it was intentional, because I didn't wan't to accidentally evaluate something inside (comment ...) block.

However, I agree with you and @technomancy. So, to have something like C-c C-e that will evaluate expression only?

sanel commented 6 years ago

Pushed changes and adding @zentrope implementation. Since I usually don't use functions like this (also in CL/Scheme modes) but *-eval-defun to evaluate top-level expression, is this expected usecase? (^ is place where cursor is placed and evaluated with C-c C-e)


user=> (println "foo")  -> "foo"
                     ^
user=> (println "foo")   -> prints "foo"
                      ^
user=> (println "foo")   -> println object
               ^
user=> (println "foo")   -> error, Unable to resolve symbol: prin
            ^
technomancy commented 6 years ago

That does the job nicely, though it is not fully backwards-compatible. If you're concerned about this you might want to make monroe-eval-expression-at-point into an alias for monroe-eval-defun and find a new name for the expression-centric command. But I don't care personally.

Thanks!

zentrope commented 6 years ago

I assume that with “eval expression” (rather than defun), it’s up to the user to make sure the cursor is at the right place, but then I tend to use these tools simply. The examples you show seem right to me.

It’s an interesting debugging tool. I think it’s Cider that actually prints out the C-x C-e value right after the function itself (as a brief overlay), which is handier than I would have thought. Lets you inspect and verify without a visible repl.