lsp

juhoteperi 2024-09-12T10:57:16.590879Z

Any opinions what is best way to sort JS lib requires where letter case might affect the sort? • Cljstyle: uppercase letters are sorted first, no option to change • Clj-kondo/clojure-lsp (clean-ns): letter case is ignored and MUI styles ns is sorted together with components starting with S, no option to change • Clj-kondo :unsorted-required-namespaces is off by default (the project has the linter enabled, and some ns disable it to hide warnings from mui styles require) • Cljfmt/clojure-lsp (format) doesn't sort requires by default, you need to enable :sort-ns-references?, upper case letters are sorted first, same as cljstyle! Differs from clean-ns! • Though the project uses cljstyle, I'd like to be able to use clean-ns from clojure-lsp in the editor This has frustrated me for long time, but I'm not even sure which which project(s) to open issue at. Now that I see lsp clean-ns and format work differently, I think clj-kondo and clean-ns should match the cljfmt sort.

juhoteperi 2024-09-24T08:56:32.733539Z

:unsorted-required-namespaces {:level :warning
                                          :sort :lexicographically}
@borkdude :sort key ok? Should we specify what is the "default" value or do we just support this value and all other values / unset ignores case?

borkdude 2024-09-24T09:01:12.214419Z

let's just do whatever clojure-lsp has?

borkdude 2024-09-24T09:01:36.153839Z

(haven't checked)

juhoteperi 2024-09-24T09:01:55.109669Z

:sort {:require true/false/:lexicographically}

juhoteperi 2024-09-24T09:02:02.990569Z

so it doesn't quite fit to clj-kondo config

borkdude 2024-09-24T09:02:29.985789Z

why not?

juhoteperi 2024-09-24T09:03:56.153469Z

Well clj-kondo already has the :level option to toggle if the linter is enabled or not, but we can't use the level to also control how the sort should happen

borkdude 2024-09-24T09:04:42.516279Z

can you link me to the config that clojure-lsp uses?

borkdude 2024-09-24T09:04:56.841599Z

I have trouble finding it in their docs

juhoteperi 2024-09-24T09:05:09.162819Z

https://clojure-lsp.io/settings/#require

juhoteperi 2024-09-24T09:05:47.366409Z

false disables the sorting completely, true enables with default sorting, :lexicographically enables with different sorting

borkdude 2024-09-24T09:06:18.756919Z

ah yes

borkdude 2024-09-24T09:07:30.491109Z

the default, let's not change it as it is now, but also give it a name

juhoteperi 2024-09-24T09:07:51.963179Z

:default?

borkdude 2024-09-24T09:07:58.669939Z

that's not a good name

juhoteperi 2024-09-24T09:08:02.709589Z

True 😄

😆 1
juhoteperi 2024-09-24T09:08:24.067469Z

(Lunch now, will be back in moment, I have tests written already.)

borkdude 2024-09-24T09:08:49.542719Z

lexicographically-lowercased
or case-insensitive?

borkdude 2024-09-24T09:08:56.794849Z

something like that. thanks!

juhoteperi 2024-09-24T10:00:58.488309Z

Do linters validate the options values generally?

juhoteperi 2024-09-24T10:01:07.871539Z

Or is there some schema for the options?

borkdude 2024-09-24T10:02:34.506349Z

there is a built-in linter that does some of this

juhoteperi 2024-09-24T10:20:25.117459Z

Done: https://github.com/clj-kondo/clj-kondo/pull/2399/files

juhoteperi 2024-09-24T10:22:54.104379Z

Though lexicographically matches clojure-lsp, I wonder if it would be more obvious to just call these :case-sensitive and :case-insensitive/`:lower-cased` or something

juhoteperi 2024-09-24T10:23:16.848149Z

I wonder if the clojure-lsp :lexicographically also has some other differences vs. just the case? "to do a lexicographic sort that places unwrapped namespaces last."

borkdude 2024-09-24T10:23:17.446309Z

yeah probably that's a better name

borkdude 2024-09-24T10:23:36.665209Z

I like case-(in)sensitive better than lower-cased

juhoteperi 2024-09-24T10:23:53.861789Z

I'll update the PR to that 👍

borkdude 2024-09-12T11:05:04.154819Z

I think the clj-kondo way matches what emacs / CIDER / clj-refactor did . Can you paste the code, then I can test what it did

juhoteperi 2024-09-12T11:05:55.552349Z

(ns foo
  (:require ["@mui/material/Avatar$default" :as Avatar]
            ["@mui/material/Stack$default" :as Stack]
            ["@mui/material/Tab$default" :as Tab]
            ["@mui/material/Tabs$default" :as Tabs]
            ["@mui/material/Typography$default" :as Typography]
            ["@mui/material/styles" :as styles]
            ["moment/src/moment$default" :as moment]))

juhoteperi 2024-09-12T11:07:30.245849Z

The difference between lsp clean-ns and format isn't obvious because it requires one to turn on cljfmt :sort-ns-references?, and similar require forms which likely doesn't happen unless you use some JS libs

borkdude 2024-09-12T11:09:49.405009Z

clojure-sort-ns says the above ns form is already sorted

borkdude 2024-09-12T11:10:02.741579Z

in emacs

juhoteperi 2024-09-12T11:10:07.484199Z

so that is same as cljfmt and cljstyle

juhoteperi 2024-09-12T11:10:28.505839Z

clj-kondo and clojure-lsp clean-ns differ from that

borkdude 2024-09-12T11:10:41.814819Z

how does clj-kondo complain about this then? I don't see it

juhoteperi 2024-09-12T11:11:29.786249Z

❯ clj-kondo --config '{:linters {:unsorted-required-namespaces {:level :warning}}}' --lint foo.cljs
foo.cljs:4:14: warning: Unsorted namespace: @mui/material/styles
linting took 8ms, errors: 0, warnings: 1

borkdude 2024-09-12T11:11:30.204889Z

ah yes, I do see it:

src/foo.cljs:7:14: warning: Unsorted namespace: @mui/material/styles

borkdude 2024-09-12T11:11:54.932399Z

so it should behave case-sensitive, right?

juhoteperi 2024-09-12T11:12:47.167119Z

I think so. I think for MUI case it makes sense to separate the utility file from the components, like their naming does.

borkdude 2024-09-12T11:13:05.916419Z

alright, issue welcome. no clue why clj-kondo disregards case

borkdude 2024-09-12T11:13:31.962269Z

the lsp clean-ns issue is probably independent

juhoteperi 2024-09-12T11:13:34.963609Z

👍 I'll start from clj-kondo

juhoteperi 2024-09-12T11:18:32.767239Z

There is a test case that sort is case insensitive, test/clj_kondo/main_test.clj line 2933

juhoteperi 2024-09-12T11:19:35.255199Z

How do other tools handle symbols? Could there be different between symbol and string sort

borkdude 2024-09-12T11:20:48.387569Z

oh the issue was: https://github.com/clj-kondo/clj-kondo/issues/1718 "this aligns better with clojure-lsp"

borkdude 2024-09-12T11:20:49.200719Z

hmm

borkdude 2024-09-12T11:21:25.422229Z

cc @ericdallo @dpsutton @snoe I'm open to changing this, it doesn't make sense to me immediately, but perhaps y'all remember why we did this?

juhoteperi 2024-09-12T11:24:12.422199Z

cljfmt wants to sort Bar before bar (if the sort option is enabled)

borkdude 2024-09-12T11:25:13.467589Z

yeah, there seems to be a conflict here

juhoteperi 2024-09-12T11:25:45.977599Z

maybe that commit was to match with lsp clean-ns, but formatting tools weren't considered at that time

borkdude 2024-09-12T11:26:03.466749Z

clojure-sort ns also sorts Boo in front of boo

juhoteperi 2024-09-12T11:34:45.864989Z

https://github.com/clj-kondo/clj-kondo/issues/2394

🙏 1
borkdude 2024-09-23T12:36:32.347519Z

ping @ericdallo @dpsutton @snoe. If I don't hear back what is the rationale to divert from other clojure tools with respect to sorting ns forms, I'll probably revert to whatever the other main tools are doing, since sorting case insensitively doesn't make sense to me.

ericdallo 2024-09-23T12:37:33.447909Z

I lost that msg, will take a look

borkdude 2024-09-23T12:39:09.084329Z

Thanks! Github issue here: https://github.com/clj-kondo/clj-kondo/issues/2394

ericdallo 2024-09-23T12:48:39.080119Z

@juhoteperi I think using: .lsp/config.edn

{:clean {:sort {:require :lexicographically}}}
makes the sorting equals to what you want, is that enough for clojure-lsp? https://clojure-lsp.io/settings/#require

juhoteperi 2024-09-23T13:49:19.713079Z

Aha yes. That does seem to fix clojure-lsp part of this. I didn't connect the documentation to this case. true mentions sort according to the Clojure Style Guide but I don't know if that is the case? (Not sure if Style Guide has an example for this case)

ericdallo 2024-09-23T13:50:42.969379Z

yeah, I don't think it has, we can improve the docs

dpsutton 2024-09-23T13:52:36.591849Z

i don’t remember any context unfortunately. This stuff gets so tricky and can be a really sharp pain for no real reason. I wish i remembered the motivating example originally.

borkdude 2024-09-23T14:11:58.466329Z

What I could do is remove the case insensitivity and wait for that context to come back ;)

dpsutton 2024-09-23T14:12:16.789959Z

100%. Turn it off and see who complains 🙂

ericdallo 2024-09-23T14:13:27.017519Z

I think clj-kondo and clojure-lsp should be aligned as otherwise we will have clj-kondo complaining and clojure-lsp sorting differently which seems worst than current behavior

borkdude 2024-09-23T14:14:12.656499Z

clj-kondo also (at least originally) aligns with other clojure tools like clojure-mode in emacs though

borkdude 2024-09-23T14:14:18.785859Z

and cljfmt

borkdude 2024-09-23T14:14:34.821099Z

and cljfmt is used in clojure-lsp which seem not to align by default, so maybe it's clojure-lsp that should change the default

ericdallo 2024-09-23T14:15:11.989709Z

yeah, I think so, I just not sure if changing that config will add other side effects, but agree

dpsutton 2024-09-23T14:18:08.431339Z

oh i think i remember now. The casing stuff just feels awkward. I think it was in imports

(:import
  (org.A Klass)
  (org.G Klass)
  (org.X Klass)
  (org.a Klass)
  (org.g Klass))
it’s really annoying that the entire upper case comes before the entire lowercase. Because you can’t quickly scan for the import you need, you have to remember the casing.

juhoteperi 2024-09-23T14:18:25.514529Z

Luckily I think this sorting only matters for people who • use JS libs • use JS libs with file naming conventions with both lower and upper case letters • use specific files from those libs so the letter case matters I haven't seen any other cases where tools would sort requires different than this @mui/material/styles

dpsutton 2024-09-23T14:18:45.190199Z

so this is “correctly” lexicographically sorted and you have to remember casing to quickly find your imports.

borkdude 2024-09-23T14:23:07.162489Z

ok so maybe clj-kondo just needs to add an option :lexicographically then as well, to make it behave case insensitive?

borkdude 2024-09-23T14:23:29.196059Z

PR welcome