This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-04-22
Channels
- # adventofcode (12)
- # announcements (17)
- # babashka (46)
- # beginners (105)
- # calva (7)
- # chlorine-clover (7)
- # cider (9)
- # clj-kondo (41)
- # cljsrn (16)
- # clojure (67)
- # clojure-australia (1)
- # clojure-europe (24)
- # clojure-france (6)
- # clojure-germany (10)
- # clojure-italy (1)
- # clojure-losangeles (3)
- # clojure-nl (4)
- # clojure-uk (11)
- # clojurescript (8)
- # cursive (8)
- # data-oriented-programming (1)
- # data-science (1)
- # datomic (11)
- # defnpodcast (4)
- # events (1)
- # fulcro (34)
- # graalvm (6)
- # helix (3)
- # jackdaw (19)
- # jobs-discuss (1)
- # leiningen (9)
- # luminus (2)
- # malli (15)
- # mathematics (2)
- # meander (5)
- # mental-health (1)
- # off-topic (4)
- # pathom (23)
- # podcasts-discuss (1)
- # polylith (4)
- # quil (3)
- # re-frame (81)
- # react (1)
- # reagent (19)
- # reitit (4)
- # releases (1)
- # reveal (11)
- # shadow-cljs (54)
- # specter (14)
- # tools-deps (16)
- # vscode (2)
- # xtdb (3)
Hi, I have an unusual linter use-case, I'm not sure how to resolve it. I have a pair of macros defined, simplified example:
(defmacro defn-frame-binding
([name args body]
`(defn ~name ~args (do (with-frame-bindings ~body))))
([name docstr args body]
`(defn ~name ~docstr ~args (do (with-frame-bindings ~body)))))
(defmacro with-frame-bindings
([body]
`(with-frame-bindings ~'frame ~body))
([frame body]
`(let [frame# ~frame
~'state (:state ~'connection)]
(~@body))))
let's say this is in the kondo-test.macro namespace.
then in kondo-test.core,
(defn-frame-binding example
[frame connection]
(do
state))
kondo-test.core> (example nil {:state "hello, world!"})
"hello, world!"
However, any variables introduced in the with-frame-bindings macro, for e.g. state
in this case, are linted as unresolved symbols. I figure I have to do something like:
{:lint-as {kondo-test.macro/defn-frame-binding clojure.core/defn
kondo-test.macro/with-frame-bindings clojure.core/let}}
Though, while it works for the custom defn-like macro, bindings set in with-frame-bindings don't appear to be picked up, probably because it doesn't look like a let, but is an anaphoric macro.
Any ideas?@dsp First of all, anaphoric macros are bad. :) But you can tell clj-kondo in the unresolved-symbol config to ignore certain symbols within specific functions.
I wondered if there was some more generic way to do that, since otherwise it will get quite unwieldy. I use this macro in lots of functions, so will probably be a lot of repeated lines.
(defn-frame-binding Tauth
"auth – messages to establish a connection
size[4] Tauth tag[2] afid[4] uname[s] aname[s]
size[4] Rauth tag[2] aqid[13]"
[frame connection]
(error! "no authentication required"))
within these functions, frame-{fieldname} get predefined and pulled out of the network frame.Makes it much more convenient, especially if I modify the underlying data type, since I can just modify the macro that pulls them out, separating the concern for anyone using them.
@dsp I mean, they are bad in the sense that they are a bit magical, but there are trade-offs, I was being a bit blunt.
Can you please take a look at the docs? There are good examples for other anaphoric macros and it works quite well.
e.g. the streams
macro introduces a magical where
:
https://github.com/clj-kondo/clj-kondo/blob/master/doc/linters.md#unresolved-symbol
Yes, I had looked at that already. However, it seems like I'd have to define it for any function that calls the macro, unless I'm mistaken.
you only write it once for streams
and then it works everywhere you call the streams macro
{:linters
{:unresolved-symbol
{:exclude [(kondo-test.macro/with-frame-bindings [state])]}}}
With this, (if I have interpreted the docs correctly), I would expect state
to no longer be reported as unresolved.when you write
(require '[kondo-test.macro :refer [with-frame-bindings]])
(with-frame-bindings state)
that should then work without errorYou are correct. It is a spacemacs bug, had to kill all the buffers to get it to update with that.
spacemacs integration seems quite janky, but that is not the fault of the tool. Lots of strange behaviours, but I guess I will investigate that separately. Thanks a lot for the help.
@jtlocsei An alternative is to try the intellij LSP plugin. Some people have reported it worked better for them than the filewatcher approach
Yup, LSP works great, I tried it after I couldn't get the filewatcher way working. I noticed the clj-kondo docs say "The LSP server does not provide features other than diagnostics." Does that mean that the LSP approach somehow has less functionality than the filewatcher approach?
No, it means that an LSP server usually also provides things like finding references, refactoring etc
Having said that, you might even be able to get clojure-lsp working with the LSP plugin, which does provide a lot more
OK, got it! So LSP + clj-kondo has all the same functionality as filewatcher + clj-kondo. Thank you! BTW, I'm a huge fan of the tools you've created. I use Babashka for scripts now and it's awesome.
clojure-lsp should work with intellij indeed: https://clojure-lsp.github.io/clojure-lsp/clients/#intellij-cursive
I'm making a macro that should be linted like a let
with ternary bindings (it's an in-house convenience gizmo and there's a method to my madness...) something like:
(with-new [a "app/object" {:label "a"}
b "app/type" {:id 25}]
(str a b))
@euccastro either disable the unresolved-symbol linter in this macro or write a hook