Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cider-eval-list-at-point eval's outer sexp #3318

Open
bo-tato opened this issue Feb 2, 2023 · 4 comments
Open

cider-eval-list-at-point eval's outer sexp #3318

bo-tato opened this issue Feb 2, 2023 · 4 comments

Comments

@bo-tato
Copy link

bo-tato commented Feb 2, 2023

Expected behavior

On this code (println (+ 1 (* 2 3)))
with the cursor anywhere in (* 2 3) we expect to eval 6, as I understand from: #2881

This adds a new function cider-eval-list-at-point, that evaluates a list around point [as in: code delimited by the nearest pair of parens surrounding point]

Actual behavior

with the cursor anywhere from * 2 3) we get 7, from evaling (+ 1 (* 2 3)), and on the opening ( of (* 2 3) it evals the outer println

CIDER version information

;; CIDER 1.5.0 (Strasbourg), nREPL 1.0.0
;; Clojure 1.11.1, Java 17.0.5

Emacs version

28.1

Operating system

Ubuntu 22.04.1 LTS

JDK distribution

OpenJDK 64-Bit Server VM Temurin-17.0.5+8

@bo-tato
Copy link
Author

bo-tato commented Feb 4, 2023

it seems this is something to do with evil mode, if I turn off evil mode cider-eval-list-at-point works as expected

@bo-tato
Copy link
Author

bo-tato commented Feb 4, 2023

I found this thread talking about similar behaviour with evil/cider: https://www.reddit.com/r/emacs/comments/10f3eff/comment/j4wrt6t/

they link this source which is where evil is modifying the last-sexp behaviour: https://github.com/emacs-evil/evil/blob/8a05eb99c6ee60eb502a2c586fa2e771a513c417/evil-integration.el#L241-L251

so if you enable evil-move-beyond-eol then it disables that and cider-eval-list-at-point works as expected, but then it has the weird (for vimmers) behaviour of cursor moving one past the end of the line, and you need to position cursor one past what you want to evaluate

I "fixed" it for me by adding 1- in cider-eval-list-at-point:

    (goto-char (1- (cadr (cider-list-at-point 'bounds))))

obviously I'm not proposing making that change in cider as it'd break non-evil users. I'm new with emacs, maybe someone more experienced can suggest the right way to fix this or the right way for me to get the behaviour I want.
basically I just want three shortcuts, with cursor on foo in (+ 1 (* 2 foo) 2)
one will eval foo: currently I have set to cider-eval-last-sexp
one will eval (* 2 foo): currently I have set to cider-eval-list-at-point with this hacky 1- patch
and one will eval base form, set to cider-eval-defun-at-point
also the one other behaviour I miss from vim was be able to eval mark, so if I'm editing some function, and have some code that calls into the function, I can mark the code that calls the function, and then eval mark while editing the function to test it, without having to move back and forth. I don't know if that's possible or easy to configure here.

Feel free to close this issue cause it's really with evil mode and not cider, but maybe there is other cider users with evil mode that can suggest how to fix this

@bo-tato
Copy link
Author

bo-tato commented Feb 7, 2023

that 1- doesn't even fix it in evil mode, as then it doesn't work right in insert mode or inside strings. I have a new try for a fix, that I'm not sure if it's the right change to make but at least this I've tested and behaves as it should in evil whatever mode normal or insert, and also behaves correctly for normal users without evil mode:
in cider-eval-list-at-point I remove:

(goto-char (cadr (cider-list-at-point 'bounds)))
(cider-eval-last-sexp output-to-current-buffer)))

and replace with:

(skip-chars-forward "^)")
(cider-eval-sexp-up-to-point output-to-current-buffer)

And I think this is actually a minor improvement, as previously cider-eval-list-at-point would eval a string or [] or {} if you were inside them, rather than evaluating the surrounding parens. strings or vec/map are data literals you generally already see them in your source and what you actually want to eval in repl is the surrounding function, this is also the behaviour the docstring implies:
Evaluate the list (eg. a function call, surrounded by parens) around point.

Edit: oops, I can't just goto to next ), I have goto next matching ), I changed (skip-chars-forward "^)") to (evil-next-close-paren), I can't find if emacs/cider has an easy function to go to next matching close paren (just sexp that also includes ] } etc) that works without evil

@bbatsov
Copy link
Member

bbatsov commented Feb 9, 2023

I think there are just sexp-based helper functions currently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants