This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-11-24
Channels
- # announcements (2)
- # beginners (130)
- # calva (72)
- # cider (4)
- # cljdoc (15)
- # cljs-dev (3)
- # cljsrn (2)
- # clojars (4)
- # clojure (55)
- # clojure-nl (1)
- # clojure-uk (19)
- # clojurescript (46)
- # cursive (95)
- # datomic (6)
- # figwheel (40)
- # fulcro (12)
- # hyperfiddle (3)
- # off-topic (11)
- # onyx (3)
- # parinfer (6)
- # pathom (15)
- # protorepl (38)
- # re-frame (67)
- # reitit (18)
- # shadow-cljs (45)
- # tools-deps (2)
Personally I like use test editor as an editor with paredit assistance but not as real "lisp" editor 🙂
Personally I like use text editor as an editor with paredit assistance but not as real "lisp" editor 🙂
I released the fix on the marketplace, should show up soon there. It has only one tab key binding, as it used to be.
I could update it from the marketplace now, please try it and let me know what you think about it.
ctrl+i actually should implement parinfer’s tabstops, but I was lazy and started like this. I choose 1 space to make it work for nudging stuff just 1 space, while in hiccup code and such. You’ll have to type twice as many ctrl+i, sorry. 🙂
About you being stupid, I doubt it. Maybe something is broken… If you type this and have the cursor where the vertical bar is and press tab, what happens?
(-> foo
|
bar)
What formatCurrentForm
should do is find the closest enclosing form and format it. It’s a bit of a performance thing, because formatting the whole document can be a bit slow. There is a command for that too, and if you have a formatted document then formatting the current form when needed is enough to keep the document formatted.
This latest release is an attempt to make it a bit less painful to drop parinfer. Therefore the Indent/dedent and Infer Perens commands where added.
@pez I saw your message in #clojure and decided to hack a bit…
(def opening (set "{[("))
(def closing (set "}])"))
(def mapping (apply assoc {} (interleave opening closing)))
(defn -enclosing [{:keys [queue first?]} c]
(if (and (not first?) (empty? queue))
(reduced {:queue (conj queue c)})
{:first? false
:queue (cond
(opening c) (conj queue (mapping c))
(closing c) (if (= c (peek queue))
(pop queue)
(reduced (conj queue c)))
:else queue)}))
(defn enclosing? [text]
(-> (reduce -enclosing? {:queue [] :first? true} text)
(:queue)
(empty?)))
(enclosing? "[]\n[]")
Works like a charm. Can you talk some about it. Seems I can learn a bit about programming here.
the first problem to solve was just detecting if parens/brackets were balanced or not
I pretty much copied the approach I found here: https://codereview.stackexchange.com/a/180569
it creates a queue, adds a closing bracket to the queue each time an open bracket is detected, removes the last closing bracket if it matches
the way we know if it’s balanced at the end is if the queue is empty - all brackets that were added to the queue got popped off
once that was solved, the next problem was: how do we disallow "[][]"
, "() [a]"
, etc.?
basically, we want to know if the queue is empty (all the parens/brackets have been matched up to now) but we still have characters left to check
example:
(enclosing? "[][]")
;; args passed into `-enclosing` look like:
;; {:first? true :queue []} \[
;; {:first? false :queue [\]]} \]
;; {:first? false :queue []} \[
;; we stop here, because `first?` is false and `queue` is empty
;; we return the queue with the final character included in to represent that it was not fully balanced correctly
;; final returned value by -enclosing:
;; {:queue [\[]}
a valid string would look like this:
(enclosing? "(([][]))")
;; {:first? true :queue []} \(
;; {:first? false :queue [\)]} \(
;; {:first? false :queue [\) \)]} \[
;; {:first? false :queue [\) \) \]} \]
;; {:first? false :queue [\) \)]} \[
;; {:first? false :queue [\) \) \]} \]
;; {:first? false :queue [\) \)]} \)
;; {:first? false :queue [\)]} \)
;; we're all done, final returned value by -enclosing:
;; {:first? false :queue []}
Thanks a ton! I have struggled with this for quite some time and only come up with totally horrible solutions.
happy to help! I have lots of practice doing these little problems from doing coding challenges like code wars, Advent of Code and such 😛
also that Python solution ended up transferring to Clojure and the problem we actually needed to solve quite nicely
btw I’m excited for Calva. I’m onboarding a few new devs at work and suggested they give it a shot in lieu of Cursive
That’s cool. Please help them with the dependency hell until I’ve added some jack-in functionality.
you mean adding nrepl? luckily these are already projects we’ve been developing for a bit so I just have them lein repl
and connect
ahh actually I’m not sure that some of my projects include cider/nrepl. I’ll keep that in mind
Yeah, but Calva needs quite recent nREPL and such. Many people stumble on this and I think a lot of them give up without even asking me for help.
Yes, cider/nrepl too. Calva should offer ways to inject the dependencies in the repl startup. And that isn’t even very hard to solve, I just haven’t done it yet.
Lot’s of combinations. But right now I leave the users a bit abandoned assuming they know stuff about dependency chains and class path and stuff, when they probably (since they are using VS Code, are just trying out Clojure for the first time).
A big point with Calva is to make Clojure accessible, which is why it pains me that I haven’t spent more time on this problem. Maybe tomorrow! 🙂