Fork me on GitHub
#cursive
<
2022-06-30
>
onetom05:06:19

I seems, that in a REPL command definition, with the options shown on the screenshot, Before executing: Sync all modified files happens BEFORE Save all files before executing. 1. is it really the case? 2. what's the rationale for this order? 3. would it be possible to swap the order? Reason for the swap: If my REPL command would run eg. kaocha.repl/run, I would expect the current editor tab to be saved AND also reloaded, because now it's considered modified (on the filesystem too). This would enable me to change the implementation of a function-under-test and re-run the corresponding tests with a single keystroke, without jumping to the test namespace. It would also work, if I would be modifying the test namespace only, OR if i modified the implementation (without explicitly saving it), BUT also jumped to the test namespace.

onetom05:06:45

for reference, the rest of the REPL command is: > Name: Run all tests or selected one with Kaocha Execute command:

(do (when-not (resolve 'user/focused-test) (intern 'user 'focused-test (atom nil)))
    (when (:test (meta #'~current-var)) (reset! user/focused-test '~current-var))
    (time
      (if-let [t @user/focused-test]
        (do (require (symbol (namespace t)) :reload)
            ((requiring-resolve 'kaocha.repl/run) t))
        ((requiring-resolve 'kaocha.repl/run-all)))))

onetom05:06:29

this would be a great workflow enhancement, because it has derailed our though processes numerous times, when we saw unexpected test results, because the tests ran against an older implementation. practically all of our namespaces are reload-friendly and won't reset any application state, so instead of keeping track of what defs and defns being modified and evaluating them all the time, we just load complete namespaces, or simply all modified namespaces.

onetom05:06:54

that way we can trust that whatever is in our editor buffers is what runs in the REPL.

onetom05:06:49

we also have a Re-execute last command REPL command, as shown on the screenshot. and a probe function, which is available in most of our namespaces:

(defn probe
  ([x]
   (println "\nPROBE: ")
   (pp x)
   x)
  ([xform x]
   (probe (xform x))
   x))

onetom05:06:37

having these to facilities, we can just drop a probe - without any parens - into threading forms, in any implementation namespace, and without saving or evaluating the changed def or defn, we can either 1. with Cmd-R, re-run the last test 2. with Cmd-Ctrl-Enter, re-run the expression, we evaluated the last time

onetom05:06:33

it would be a wonderfully simple workflow, if it wouldn't be for the issues arising from the ordering of saving and loading files before executing REPL commands.

onetom03:07:51

i just remembered, that this issue was already filed here: https://github.com/cursive-ide/cursive/issues/2612

stammi06:06:21

Hey all, I was delighted to find the menu item Help -&gt; Show Cursive Cheat Sheet, which I imagine to be quite helpful in our team. Unfortunately it opens file:///tmp/cheat-sheet.html in the browser, which does not exist.

onetom01:07:51

i guess, it must be an OS-specific issue, because for me, on macOS, it works and it opened file:///private/var/folders/bf/twwtz52n1mxc4psynq8xkfb40000gn/T/cheat-sheet.html on Cursive 1.12.4-2022.1 & IntelliJ Ultimate 2022.1.3

stammi06:06:09

Just realized that feature is quite old 😀

Rachel Westmacott10:06:33

Minor feature request: if I (:require [foo.core :as-alias foo]) and then later I try to actually use foo (f.e. (foo/some-function x y z) it would be super handy if Cursive told me off before it failed to load in the REPL.

imre10:06:47

I wonder if #clj-kondo has a linter for this (cc @U04V15CAJ)? If yes, you should be able to use that via #clj-extras-plugin on top of Cursive to get a warning/error.

Rachel Westmacott10:06:51

oh, that's a good point. Last time I tried clj-extras-plugin it all went horribly wrong, but I heard more recently that it's quite good so I should give it another try anyway!

Rachel Westmacott10:06:33

(not sure what happened - it may have been a case of pebkac rather than anything wrong with the tools)

imre10:06:35

I’ve been using it without trouble lately. Mind that if you want to use it with 2022.2 EAP you’ll need a custom build

borkdude10:06:30

clj-kondo might not already have a linter for this

borkdude10:06:39

but feel free to post an issue and or PR

onetom01:07:06

on the release version - 2022.1.3 - of intellij ultimate, i don't have any serious issues with the #clj-extras-plugin either.

onetom01:07:40

i do see an occasional false positive warning, but it doesn't throw exceptions randomly. my main reason for using it is to have the namespace part of keywords and symbols highlighted differently. clj-kondo integration in it is nice, too but it very very rarely tells me anything useful, which i wouldn't already know or Cursive itself wouldn't indicate anyway. on the other hand, the false positives as are annoying... but i guess, that's just me, because im staring at clojure code for ~7+ years by now and my brain already does a lot of linting 🙂 the inline evaluation is also very nice, but i don't use that either, because i often pair-program, and having ephemeral evaluation results gets in the way for staying in sync with the pairing partner. but even alone, i find myself scrolling back the evaluation history to review the results of previous evaluations, to revise the conclusions i made about them. i can clearly see, if i forgot to evaluate a form or forgot to reload a namespace. that's all lost with inline eval, so i don't quite understand why so many people want it. regardless, it great to have these options and clj-extras is a solid addition to the clojure toolbox!

onetom01:07:00

@U0FR9C8RZ > ... Cursive told me off before it failed to load in the REPL why is it a problem to find out the issue at load time? i have the feeling, that you are not reloading your REPL namespace often and routinely for some reason. probably, because u have some state in it, which u don't want to lose. that can be avoided by using defonce. i also combine it with redelay (https://functionalbytes.nl/clojure/redelay/rmap/2020/06/26/redelay.html), so i can do something like this:

(defonce some-state (redelay #(define initial state 123)))
(comment
  (.close some-state)
  (-> @some-state ...)
  )
or if u don't like the @, u can also have (defn some-state [] @some-state*) or perhaps it does side-effects at load time? u can put those into try/catch, if u really must do some side-effects. otherwise, just define a function and keep an example invocation of it in a rich-comment. that means, now 2 have to load the REPL NS, find the side-effecting call in the rich-comment and eval it. it's slightly more involved, BUT now it's extremely unlikely to end up with a broken REPL NS. finally, i can imagine that you are putting stuff, which can break, into a user.clj. don't do that, because it's indeed annoying, that u can't even have a REPL, which would allow u to start diagnosing some problems. instead, we are using a bunch of *-repl namespaces, which are under a dev/ source path, so they won't get deployed.

Rachel Westmacott08:07:00

It would be better to find out from a specific linting rule, rather than from a REPL error, because the message could be more helpful and more local to the problem. FWIW I think I load/reload my namespaces quite a lot (I too have been staring at Clojure code for 7+ years 😉 - maybe as many as 10 in fact.)

borkdude08:07:36

@U0FR9C8RZ I posted an issue here: https://github.com/clj-kondo/clj-kondo/issues/1742 I agree that it would be quite useful.

👍 1