This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-11-11
Channels
- # asami (19)
- # babashka (41)
- # beginners (115)
- # biff (7)
- # calva (78)
- # clj-kondo (29)
- # cljs-dev (9)
- # clojure (39)
- # clojure-europe (17)
- # clojure-gamedev (29)
- # clojure-nl (1)
- # clojure-norway (9)
- # clojure-spec (2)
- # clojure-uk (3)
- # clojurescript (7)
- # core-async (26)
- # cursive (16)
- # datomic (13)
- # emacs (1)
- # events (5)
- # fulcro (2)
- # funcool (4)
- # gratitude (1)
- # helix (1)
- # holy-lambda (1)
- # humbleui (1)
- # introduce-yourself (4)
- # java (1)
- # jobs (2)
- # jobs-discuss (9)
- # lsp (28)
- # matcher-combinators (2)
- # mathematics (1)
- # membrane (1)
- # nbb (12)
- # off-topic (10)
- # pathom (52)
- # polylith (38)
- # portal (32)
- # re-frame (4)
- # reagent (16)
- # reitit (2)
- # remote-jobs (1)
- # reveal (1)
- # rewrite-clj (10)
- # sci (67)
- # shadow-cljs (45)
- # squint (1)
- # tools-build (13)
- # tools-deps (16)
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)
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!
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.
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?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
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 wantAs for your case of having already barfed, Splice & Kill/Delete Backward
works to clean up the leftover form.
@U90R0EPHA Splice & Kill/Delete Backward
This is what I wanted. I missed it somehow :S
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
@U90R0EPHA Actually I'd like a command that'd delete the entire enclosing sexp
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.
What I have been doing is Move Back Up Sexp
-> Select Forward Sexp
-> Backspace
. But this seems more direct.
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 definedI 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))])
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
Though I guess stats isn't defined until that closing ]
... is that where the issue lies?
@U03QBKTVA0N I guess that whatever ctrl+alt+enter
is doing doesn't know about stats
.
@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.I figured as much
I do wonder if there's a way to do this though
Unless I misunderstand something, this is where Evaluate Selection, Closing Bracket comes in. See https://calva.io/evaluation/#evaluate-selection-closing-brackets
No, evidently this is what I need. I was only selecting up until [
and not back to (let ...
thank you @U0ETXRFEW!
I think it would work but it doesn't know what default is then, right @UC1DTFY1G?
(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.Which version of Calva are you using, @UC1DTFY1G?
Ok maybe I'm mistaken too, I get nil
instead of a syntax error :thinking_face:
@U0ETXRFEW [2.0.293] - 2022-08-18
@UC1DTFY1G, is ”does nothing for me” the same as ”returns nil
”?
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)
and then I can see what I want to see
[2.0.308] - 2022-10-19 • https://github.com/BetterThanTomorrow/calva/issues/1901 • https://github.com/BetterThanTomorrow/calva/issues/424
That was the version I had installed in my WSL2. Somehow the WSL2 version didn't auto update.
We should consider a command that did what you tried to do with that let binding, @UC1DTFY1G. I wonder what it would be like...
Re-write and eval like this?
(let [r (range 10)]
(->> r (map inc))
I am obviously unaware how eval worksLet me see how other commands are implemented in Calva and perhaps I can figure out something...
I guess your original suggestion about prn
would be useful here as well, though I have not yet tried it
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))])
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.
I would never have thought to do this but that is quite useful. Thanks @U9A1RLFNV
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. 😃
@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
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")))
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")))
member
and the first clause get one space, the second (and any subsequent) clause(s) get two spaces.
I've tried enabling/disabling calva-fmt
and I've tried the New Indent Engine
and they all seem to give the same layout.
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.
It is not the case. I have pressed tab
on every part of that form, trying to see if it will reindent things.
I think the formatting rule for as->
is just broken.
Actually all that stuff lining up perfectly with (as->
is strange, should be some indent there
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).
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.
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")))
Again, 1 char indent for the first clause, 2 char indent for all the rest.
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-rulesSo it's basically wrong 🙂
Both as->
and cond->
(and probably a few others) should have different indent behavior inside ->
pipelines.