cursive

danm 2025-01-22T13:22:05.033139Z

Is it possible to configure Cursive's parinfer to consider ;(;) comments to be allowed to be at the 'end' of forms? A lot of my team have a habit (that I don't particularly like, but I am in the minority and it's just not worth fighting over) of doing this sort of thing:

(let [....]
  (some forms)
  (some more forms)
  ;; A useful comment about how the above might be invoked for testing/in a REPL when it's not immediately obvious/simple
  )

(comment
  (defn repl-debug-fn [arg]
    ...)
  ;; locally: (debug-fn x)
  ;; deployed: (debug-fn y)
  )

(def var {:map-key-1 "map-val-1" ; Comment for purpose
          :map-key-2 "map-val-2" ; Comment for purpose
          :map-key-3 "map-val-3" ; Comment for purpose
         })
Which parinfer reformats to:
(let [....]
  (some forms)
  (some more forms))
  ;; A useful comment about how the above might be invoked for testing/in a REPL when it's not immediately obvious/simple

(comment
  (defn repl-debug-fn [arg]
    ...))
  ;; locally: (debug-fn x)
  ;; deployed: (debug-fn y)

(def var {:map-key-1 "map-val-1" ; Comment for purpose
          :map-key-2 "map-val-2" ; Comment for purpose
          :map-key-3 "map-val-3"}) ; Comment for purpose
and then I get asked about 'spurious code changes' in my PRs...

cfleming 2025-01-24T02:37:45.438359Z

Ha, I love the smiley face, I'll have to switch to using that!

➕ 1
onetom 2025-01-24T04:31:00.961969Z

The smiley face is something i can get onboard with too! If clj-standard doesn't affect it, then it's even better. I think the hanging paren is really useful, not just as a visual clue/separator, but also allows appending new rich comment forms to an existing block, because it's easy to position to the right insertion point. the comments definitely shouldn't be moved out, because they clearly belong within the comment expression, but i'd recommend the following convention changes: 1. leave helper functions outside of the rich comment a. so it's clear at dev time already, that their var's name won't conflict with other vars b. if they rely on some code, which is not needed by the production code, hence not required in the ns form, just call those with ((requiring-resolve 'some.dbg/fn) args ,,,) c. it allows just loading the whole namespace when the definition of that function changes, as opposed to evaling just that single form, which makes sure that stack traces coming from inside those functions will have correct line numbers, as opposed to line numbers relative to the 1st line of that function d. it opens up the very efficient workflow of I. eval (debug-fn x) II. edit debug-fn or any other function it calls, in any other namespace III. without navigating anywhere, with a single keychord (or key sequence, like C-c .), run a Cursive REPL command, which i. loads the current namespace ii. Re-executes the last command (`(debug-fn x)` in its original namespace) 2. don't line-comment the example invocations a. so they can by syntax highlighted b. supply dummy args if needed, to avoid successfully evaluating them unintentionally, like (debug-fn ???) c. it would already get rid of this whole "trailing line-comments in a rich-comment expression" 3. put a triple-semicolon comment as a heading, which is understood by emacs' outline-mode, before rich-comment or even its debug-fns, if there are any, so u will end up with a "source code as TUI", if u Collapse all lines with Cmd-Shift-Minus, eg:

;;; Administer frobs
(defn debug-fn [arg] ,,,)

(comment
  ;; Locally
  (debug-fn x)

  ;; Deployed
  (debug-fn x)

  :-)

onetom 2025-01-24T04:33:54.789269Z

@carr0t btw, your locally running code is also a deployment of your code. it's a development deployment. it was just done manually, not with your automated deployment procedure, which deploys only computers, which are not used for development.

imre 2025-01-22T13:28:23.231489Z

I think this is a parinfer thing: https://github.com/parinfer/parinfer.js/issues/92

danm 2025-01-22T13:33:19.034179Z

Hah

danm 2025-01-22T13:33:37.485529Z

That's one of the folks in the same team as me 😉

😁 1
imre 2025-01-22T13:34:35.098379Z

Well, the issue is still open 🙂

imre 2025-01-22T13:35:12.696699Z

(I did comment on it back in the autumn but I'm not a parinfer user myself)

cfleming 2025-01-22T18:14:15.993799Z

I'm planning to sit down and do a bunch of parinfer changes soon, I'll try to look at this then. Parinfer is so complicated that I can't keep it in my head, so every time I have to fix something I have to load it all into my brain cache again. So I try to fix it in batches, and it's overdue for one.

👌 2
👌🏻 1
imre 2025-01-22T18:25:50.047149Z

Would be nice if at the same time agreement between Cursive, Parinfer, and Standard Clojure Style could be reached on these edge cases

cfleming 2025-01-22T19:00:06.772579Z

I think that SCS is (by design) compatible with Parinfer so I think that's automatically true? I can't think of cases where it wouldn't be, but if you have some I'm all ears.

cfleming 2025-01-22T19:01:25.825279Z

@carr0t The classic way to make parinfer keep parens in place is to put something there to keep it there, which is a little ugly (and maybe not popular with non-parinfer users), I tend to do something like:

(comment
  ; some comment here, or something else
  #_nil)
One change I'm planning to make to parinfer is to only have it affect the top-level form you're working on. This will keep the changes local, and should really help cases like this.

👍🏻 1
imre 2025-01-22T22:29:24.694209Z

here's one I saw in a related thread:

(comment
  (foo) ; asdf
  :-)

😂 1
imre 2025-01-22T22:30:31.789809Z

> so I think that's automatically true I meant this very edge case is an open issue in both SCS and Parinfer, and there could be others I'm not aware of.