Fork me on GitHub
#calva
<
2022-11-11
>
skylize01:11:01

Recently added Raise Sexp to my hotkey repertoire and it is glorious:

;; "|" = cursor position
(let [print-me |(long
                multiline
                expression)]
  (prn print-me)
  print-me)
Type Ctrl-Alt-P Ctrl-Alt-R twice to reduce to
(long
multiline
expression)

👍 1
1
seancorfield03:11:18

I often use Splice & Kill/Delete Backward where Raise Sexp would be more appropriate. Good tip! I'll try to remember to use that instead of ctrl+alt+shift+backspace in future!

pez06:11:37

Thanks for sharing, both of you! 🙏 It's funny with raise sexpr. When I learnt about it, I wondered why on earth I would ever want to do that? Then I find myself raising sexprs all day. 😃 I also use splice and kill backwards a lot. Two power edits, for sure.

seancorfield17:11:56

I even use convolute (occasionally!)...

metal 1
pez19:11:59

Respect!

dumrat15:11:51

Any way to delete enclosing sexp? I frequently find myself doing something like this (Caret indicated by '|' ): 1. Some exp:

(a| (b (c :d)))
2. Barf forward (Ctrl+Alt+,)
(a|) (b (c :d))
3. Now I want to delete first sexp and haven't found a single command to do this with. I would like to do it in one command. Basically how do I delete an entire sexp from inside?

skylize15:11:39

Raise Sexp. Demo in the post right before yours. Replaces surrounding form with either a selection or the next form after the cursor. https://clojurians.slack.com/archives/CBE668G4R/p1668129301017559

skylize15:11:58

As in... don't barf first, just use Raise Sexp for the entire action.

sashton15:11:36

But, in case you aren’t keeping anything (meaning, Raise Sexp wouldn’t be used), I have the following to Delete Enclosing Sexp: • installed macro-commander extension • macro config:

"macros": {
    "paredit.killCurrentSexp": [
      "paredit.backwardUpSexp",
      "paredit.killSexpForward"
    ],
• then I bound paredit.killCurrentSexp to whatever I want

👍 1
skylize15:11:59

As for your case of having already barfed, Splice & Kill/Delete Backward works to clean up the leftover form.

👋 1
dumrat15:11:45

@U90R0EPHA Splice & Kill/Delete Backward This is what I wanted. I missed it somehow :S

skylize15:11:28

Note that with Splice Kill Back, any forms to the right of the cursor, but inside of the current one (the one being killed) are spliced up instead of being deleted with the form. (And Splice Kill Forward does the opposite.

((:foo |:bar))  --> (|:bar)  ;; SKBack
((:foo |:bar))  --> (:foo |) ;; SKForward

dumrat15:11:08

@U90R0EPHA Actually I'd like a command that'd delete the entire enclosing sexp

skylize16:11:30

I think you need 2 commands as @U08TWB99B demonstrates in his macro above. I think the commands he chose will give inconsistent results, but either of these combos should work consistently: Kill/Delete Forward to End of List -> Splice & Kill/Delete Backward or Kill/Delete Backward to Start of List Back -> Splice & Kill/Delete Forward Kills anything that would be spliced, and then kills the rest, splicing nothing into the surrounding form. The List-Forward-> Splice-Back variation feels pretty natural to me, and I will probably start practicing it. You can pretend it is a key chord instead of two separate commands.

👍 1
skylize16:11:47

What I have been doing is Move Back Up Sexp -> Select Forward Sexp -> Backspace. But this seems more direct.

Ben Lieberman15:11:01

Hey, how can I evaluate this let binding

(let [stats (merge default rest?)
        body (->> stats (m/encode "application/edn") |(HttpRequest$BodyPublishers/ofByteArray))])
up until that | ? I want to know the value after stats has been pushed through m/encode but I am getting a syntax error saying stats is not defined

dumrat15:11:40

I guess you put a tap> or prn here. Unless I'm mistaken.

(let [stats (merge default rest?)
        body (->> stats (m/encode "application/edn") (tap>) (HttpRequest$BodyPublishers/ofByteArray))])

Ben Lieberman15:11:44

I would think there'd be a Calva shortcut for this @UC1DTFY1G, no? Usually when I'm working with the various thread macros I can use Ctrl+Alt+Enter but that does not seem to play nicely with let

Ben Lieberman15:11:40

Though I guess stats isn't defined until that closing ]... is that where the issue lies?

👍 1
dumrat15:11:44

@U03QBKTVA0N I guess that whatever ctrl+alt+enter is doing doesn't know about stats.

dumrat15:11:19

@U03QBKTVA0N Sorry didn't read your last comment. Yes, I guess so.

(let [stats (merge default rest?)
        body (->> (range 10) (map inc) | (HttpRequest$BodyPublishers/ofByteArray))])
Here, Ctrl+Alt+Enter works and gives result.

👌 1
Ben Lieberman15:11:24

I figured as much

Ben Lieberman15:11:47

I do wonder if there's a way to do this though thinking-face

pez15:11:00

Unless I misunderstand something, this is where Evaluate Selection, Closing Bracket comes in. See https://calva.io/evaluation/#evaluate-selection-closing-brackets

Ben Lieberman15:11:35

No, evidently this is what I need. I was only selecting up until [ and not back to (let ... facepalm thank you @U0ETXRFEW!

😂 1
🙏 1
dumrat15:11:24

Funny, it's not working for me

Ben Lieberman15:11:07

I think it would work but it doesn't know what default is then, right @UC1DTFY1G?

dumrat15:11:18

(let [r (range 10) 
      s (->> r (map inc) | (filter odd?))]
  s)
Ctrl+Shift+Up Thrice here, then Ctrl+Alt+Enter does nothing for me. Perhaps I'm missing something here.

pez15:11:15

Which version of Calva are you using, @UC1DTFY1G?

Ben Lieberman15:11:36

Ok maybe I'm mistaken too, I get nil instead of a syntax error :thinking_face:

dumrat15:11:28

@U0ETXRFEW [2.0.293] - 2022-08-18

pez15:11:46

Well, the let will not be returning anything there. nil is to be expected.

pez15:11:51

@UC1DTFY1G, is ”does nothing for me” the same as ”returns nil”?

dumrat15:11:12

No, doesn't even return nil. I am updating. let's see

pez15:11:08

This is what you should get:

pez15:11:47

Because what is evaluated here is:

(let [r (range 10)
      s (->> r (map inc)])

Ben Lieberman15:11:57

Yeah, that makes sense @U0ETXRFEW. I guess the easy workaround here which I just did is to use #_ on that last form like so

(let [stats (merge {:a 1} {:b 2})
        body (->> stats (m/encode "application/edn") #_(HttpRequest$BodyPublishers/ofByteArray))]
    body)

👍 1
dumrat15:11:03

Yeah, returns nil after update

Ben Lieberman15:11:21

and then I can see what I want to see

pez15:11:59

2.0.293 is ancient! 😃

dumrat15:11:53

That was the version I had installed in my WSL2. Somehow the WSL2 version didn't auto update.

pez15:11:36

We should consider a command that did what you tried to do with that let binding, @UC1DTFY1G. I wonder what it would be like...

dumrat15:11:27

Re-write and eval like this?

(let [r (range 10)]
  (->> r (map inc))
I am obviously unaware how eval works

dumrat15:11:58

I should look at this 😄

dumrat15:11:38

Let me see how other commands are implemented in Calva and perhaps I can figure out something...

Ben Lieberman15:11:44

I guess your original suggestion about prn would be useful here as well, though I have not yet tried it

👍 1
dumrat15:11:11

I think tap> is more useful perhaps

dumrat15:11:23

Especially if you are using something like portal

Ben Lieberman15:11:35

Yeah, just got into Portal the other day. It's great

👍 1
dumrat15:11:15

Yeah, it's really nice. Though I don't much like the single click zoom-in

pez16:11:46

Maybe some way to insert tap> before closing brackets?

dumrat16:11:27

ok, that'd work

bringe04:11:02

I’m late here, but one thing I might do in a case like this is use an inline def with the same name as the binding.

(let [stats (merge default rest?)
      _ (def stats stats)
      body (->> stats (m/encode "application/edn")(HttpRequest$BodyPublishers/ofByteArray))])

👀 2
bringe04:11:51

It’s not something you want to leave in your code (clj-kondo will help you remember not to), but it’s very helpful for evaluating smaller pieces of code in functions.

Ben Lieberman04:11:52

I would never have thought to do this but that is quite useful. Thanks @U9A1RLFNV

bringe04:11:09

Yeah, I learned this a while back and I use it often now.

bringe04:11:54

And, you’re welcome simple_smile

pez06:11:53

Inline def is a power move. I use it all the time. It will litter down your namespace, which seldom is a problem, but could be good to have ns-unmap ready for use. 😃

pez07:11:46

@U03QBKTVA0N maybe this video, that just aired, could interest you. It shows me using inline def to inspect the application. https://www.youtube.com/watch?v=fMtvtAfdr90

❤️ 1
seancorfield20:11:19

Does anyone else think this indentation is a bit weird:

new-user (-> (field/as-user db-spec new-user-id)
                               (as-> member
                                     (settings/update! (:database app)
                                                       member
                                                       :view "s")
                                 (settings/update! (:database app)
                                                   member
                                                   :like "s")))

🌚 1
seancorfield20:11:04

If I put member on the next line, it's even weirder:

new-user (-> (field/as-user db-spec new-user-id)
                               (as->
                                member
                                (settings/update! (:database app)
                                                  member
                                                  :view "s")
                                 (settings/update! (:database app)
                                                   member
                                                   :like "s")))

seancorfield20:11:44

member and the first clause get one space, the second (and any subsequent) clause(s) get two spaces.

seancorfield20:11:39

I've tried enabling/disabling calva-fmt and I've tried the New Indent Engine and they all seem to give the same layout.

skylize20:11:58

That first one looks like it only went through the more lax "as you type" formatting. I would expect pressing Tab to line up the second settings/update! with the first. Is that not the case? Other than that, looks to me like what I normallly see, I think.

seancorfield20:11:41

It is not the case. I have pressed tab on every part of that form, trying to see if it will reindent things.

seancorfield20:11:05

I think the formatting rule for as-> is just broken.

skylize20:11:28

Actually all that stuff lining up perfectly with (as-> is strange, should be some indent there

skylize20:11:23

Oh, there is a 1 char indent ?

seancorfield20:11:11

I suspect whoever implemented the as-> rule looked at as-> expr sym clauses* and based it off that instead of thinking about how as-> is supposed to be used (inside ->, so that first expr will be missing).

seancorfield20:11:41

Re: "1 char indent?" -- as I said above: member and the first clause get one space, the second (and any subsequent) clause(s) get two spaces.

seancorfield20:11:31

FWIW, cond-> also gets bad indentation inside ->:

new-user (-> (field/as-user db-spec new-user-id)
                               (cond->
                                (settings/update! (:database app)
                                                  member
                                                  :view "s")
                                 (settings/update! (:database app)
                                                   member
                                                   :like "s")))

seancorfield20:11:53

Again, 1 char indent for the first clause, 2 char indent for all the rest.

skylize20:11:26

I think this is expected from cljfmt. as-> has the same default setting of [[:block 2]] as condp, which treats the first 2 arguments as special.

(condp :foo :bar
  :baz
  :buz)

(condp :foo
       :bar
  :baz
  :buz)

(condp
 :foo
 :bar
  :baz
  :buz)
https://github.com/weavejester/cljfmt#block-rules

seancorfield20:11:15

So it's basically wrong 🙂

seancorfield20:11:02

Both as-> and cond-> (and probably a few others) should have different indent behavior inside -> pipelines.

pez21:11:05

I don't think there is a way to express as-> inside -> in the indentation rule format for cljfmt... I could be wrong, I am certainly not an expert on the subject.