Fork me on GitHub
#calva
<
2023-05-12
>
avocade14:05:08

Hey! Maybe a tricky syntax highlighting question, let's see if anyone understands what I mean (if not I'll try to rephrase): • Is it possible to add a special syntax highlighting to symbols that bind directly to a keyword? So they're not the same color (black) as regular symbols. • It’s currently impossible at a glance to distinguish symbols that bind to actual functions to symbols that bind to keywords, which makes the code unnecessarily harder to read and reason about (for me at least) without jumping to definitions (or using the Mouse shudder to hover on it). ◦ Eg when using a def:ed keyword (which we almost always do as "best practice") in (user-key contextmap) instead of the raw keyword (:something/user contextmap). • It seems like it should be possible for the editor to do this introspection, but maybe I'm wrong.

bringe15:05:17

Do you mean you want these two vars to be highlighted/colored differently?

(defn hello [name]
  (str "Hello " name))

(def user-key :product/user)

bringe15:05:24

hello and user-key?

bringe15:05:35

If so, I’m not sure if that’s possible but @U0ETXRFEW knows more about highlighting. Maybe there is some way to customize it.

pez15:05:39

I think that clojure-lsp could do it. Calva doesn’t collect this information.

👍 2
bringe15:05:43

You may want to ask in #CPABC1H61. It provides semantic highlighting for Calva when it’s running for a given project.

pez15:05:02

You can show the hover using the keyboard, @U06KD64RX. FYI. It’s cmd+k cmd+i on Mac.

pez15:05:44

What’s the reason behind that “best practice”, btw? If I am allowed to derail the discussion, now that we’ve determined that the question should be asked in #CPABC1H61, anyway. 😃

☝️ 2
bringe15:05:22

Yeah, at least with clojure-lsp support, keywords can be treated as symbols in terms of finding references and renaming, so I don’t see the benefit from a tooling perspective. Maybe it’s more about reducing bugs caused by keyword typos, and/or something else.

skylize16:05:19

I can't think of any negative against capturing whatever knowledge clj-kondo is already able to garner about the types (string, number, keyword, function, etc.) underlying symbols, and translating that to additional scopes in the grammar. (If not clear, I would expect to still also see the current more-generic scope) Users could then optionally extend themes to their hearts' content to display those differences.

pez17:05:43

Indeed. It would probably not make a difference for someone not using an aware theme.

avocade11:05:22

@U90R0EPHA yes definitely, extending it even further would not be a downside at all (since it's fully opt-in), and a massive upside for those that want/need it.

avocade11:05:24

@U9A1RLFNV @U0ETXRFEW thanks for the suggestion of posting in #CPABC1H61, that seems more appropriate when I think of it as well 🙂 but thanks for a good discussion!

avocade11:05:14

@U0ETXRFEW more a tongue in cheek way of describing it, since noone ever agrees on Best Practices. that's why I wrote them in quotes (ironic quotes should be its own utf-8 maybe 😄)

skylize13:05:49

Oh yeah. An air-quotes emoji would be great. ...Though I don't think anyone on the Calva team is a member of the Unicode committee. So maybe not the right place for that suggestion? 😉:rolling_on_the_floor_laughing:

ericdallo14:05:08

The idea makes sense, but I can't see how we would make that work reliable. LSP (and clj-kondo) use static analysis, so no runtime information, how could it know these are keywords:

(def my-key-def (keyword "foo"))

(def my-other-key-def (if *something* :some-keyword "not-keyword")
Even supporting basic defs or let bindings, we would need to make kondo return that analysis, and since that would be applicable only for simple specific cases, not sure it's worth it

skylize14:05:42

I don't think that possible difficulty in reporting the type of (def foo (keyword bar)) should at all stand in the way of reporting the type for (def foo :bar)). Although in that specific example (def foo (keyword bar)), the type can be statically analyzed quite accurately as keyword-or-nil (ignoring throws-an-exception cases). And your second example is a keyword-or-string. Depending on how much work it is to get clj-kondo to inform of that, I think sum types could be reasonably up for grabs too.

ericdallo14:05:59

That is trying to emulate runtime from static, it's not assertive and those are a few examples of lots of possible others that would make it hard to know. I think it's something that is not worth it unless @U04V15CAJ sees any other way, maybe he can give his opinion as well

borkdude14:05:07

can you summarize the question?

pez14:05:41

The feature request is something like: > Make clojure-lsp provide special semantic tokens for symbols that represent keywords. And the question would be if you see a viable way to know if a symbol does that. (I think).

borkdude14:05:09

a symbol that represents a keyword?

borkdude14:05:18

you mean like:

(def a ::foo)
?

yes 2
borkdude14:05:22

this is not something suited for static analysis

skylize14:05:39

OP was hoping to color highlight symbols that point to keywords. And I expanded on that to suggest creating grammar (highlighting) scopes for the underlying types of all symbols that clj-kondo essentially should already know the type from the static analysis that is already being run anyway.

pez14:05:04

> this is not something suited for static analysis That brings the feature request back to Calva or nREPL, I think.

borkdude14:05:34

is it just about the type?

borkdude14:05:59

yeah that would be possible, I guess

borkdude14:05:18

but how common is it really that someone does (def foo ::foo) and then uses foo in multiple places?

pez14:05:18

Appearantly “best practice” (scare quotes) in the @U06KD64RX’s project. 😃

skylize14:05:34

> but how common is it really that someone does (def foo ::foo) and then uses foo in multiple places? > I don't know. But magic numbers are certainly common, or urls created as config, and used across the app. In my suggestion, keyword would just be one possible type available to know.

avocade15:05:56

@U04V15CAJ @U0ETXRFEW 😄 yeah we actually do that a lot, but definitely not common-law Best Practice™ (yet…), or this would have been implemented long ago I guess. I'm very heartened by the rich discussion about the topic, so a big thanks to everyone for that. very interesting to get more insight into if this is a) possible at all, and b) feasible enough to actually do.

Jacob Emcken15:05:22

Is this a clojure-lsp bug? I have a namespace:

(ns my-ns)

(defn my-fn
  [x]
  x)
add src/data_readers.clj with the content (see https://clojure.org/reference/reader#tagged_literals):
{my-obj my-ns/my-fn}
Now clojure-lsp reports my-fn as Unused public var in Calva?

pez15:05:44

I think it is clojure-lsp doing this. Could be clj-kondo, but I seem to recall that this particular linter is from lsp. You can try deleting both .lsp/cache and .clj-kondo/cache and restart clojure-lsp and see if that helps.

skylize16:05:28

Maybe because you are trying to use an unqualified tag? > Reader tags without namespace qualifiers are reserved for Clojure. > --https://clojure.org/reference/reader#tagged_literals > What happens is you change it to ... ?

{foo/my-obj my-ns/my-fn}

Jacob Emcken19:05:32

> What happens is you change ... Same "warning":

ericdallo13:05:22

Yep, LSP bug, since data readers is not really a normal clojure file, it has a namespace without requires, I'm not sure if we can fix only in clojure-lsp, we would need clj-kondo analysis for the val in that map, @U04V15CAJ does clj-kondo emit analysis for data readers files?

ericdallo13:05:11

I mean: src/data_readers.clj

{my-obj my-ns/my-fn}
Does clj-kondo return analysis of var-usages of my-fn there? Or it just lint like a def-catch-all ignoring elements of that file?

borkdude13:05:24

Hmm, not sure.... let me check

borkdude14:05:00

navigation works for me in this example:

src/data_readers.clj

{f/foo clojure.core/vec}
so I guess it emits the right analysis

borkdude14:05:47

I do get an unresolved symbol for f if it's not qualified which might be a bug, but it's not recommended to use unqualified symbols there anyway (should be fixed tho)

borkdude14:05:03

when I hover the symbol in data_readers.clj I get "LSP internal server error" when it's something custom and not a clojure.core symbol

ericdallo14:05:19

yeah me too, I just tested and there are no analysis for data_readers.clj :thinking_face:

ericdallo14:05:35

you can confirm running lsp-clojure-cursor-info , it show the analysis of the cursor that kondo returned for LSP

ericdallo14:05:24

ahh, only for clojure.core symbols there are analysis, for custom user namespaces no, so it seems that is missing in kondo

borkdude14:05:35

please make a repro (+ issue if applicable)

borkdude14:05:18

ah right, I think I know what's the issue, since clj-kondo doesn't regard those namespaces as already required, it does not regard those symbols to refer to vars

borkdude14:05:22

issue welcome

borkdude14:05:27

thanks. I hope to release a new clj-kondo on Wednesday. If I don't get to it before then, PR welcome

👍 4
🙏 4
pez15:05:48

You guys rock! 🎸 :the_horns:

gratitude 4