lsp

ericdallo 2025-04-01T16:53:31.083109Z

I'm considering adding optional https://github.com/clojure-lsp/clojure-lsp/issues/1315 for format feature, especially because of cljfmt performance + missing vertical alignment configs, anyone had experience with zprint and knows if is possible to matches all cljfmt configs?

πŸ”₯ 1
❀️ 7
ericdallo 2025-04-01T16:54:03.100879Z

I found https://clojureverse.org/t/i-need-some-zprint-config-examples/3121/15 but seems a little bit old, any thoughts @pez?

jakemcc 2025-04-01T16:56:52.115379Z

my team uses zprint for formatting all our codebases. I think you'd be able to recreate pretty much any formatting style you want with it. It is incredibly configurable.

jakemcc 2025-04-01T16:57:38.044579Z

One gotcha, at least for however we have our formatters setup, is that we occasionally need to run it twice to get to a stable format.

ericdallo 2025-04-01T16:58:38.812049Z

> occasionally need to run it twice to get to a stable format. that's odd, do you know if it's a zprint bug or maybe some nested cleans and format of yours that can result in that need?

jakemcc 2025-04-01T17:04:45.717069Z

unsure. I think it might be neither a bug or something about our formatting choices but I'm struggling to find the documentation about it. I have a vague memory of there being some heuristics for getting code looking "good" that can result in the starting state affecting the output.

jakemcc 2025-04-01T17:05:09.820109Z

the maintainer is pretty active on github (at least, back when I was setting this up).

πŸ‘ 1
βž• 1
2025-04-01T17:05:44.278169Z

there are occasional bugs with zprint with consistency but kim responds fast if you find issues

2025-04-01T17:06:03.498729Z

i used to be the maintainer of our zprint config at my last job, we ran it over 120k lines of clojure

2025-04-01T17:12:43.965769Z

lol i can answer many questions about zprint if you have them

πŸ˜‚ 1
ericdallo 2025-04-01T17:14:09.277569Z

thanks! for now, I'll start implement the support in clojure-lsp with a flag to use it, but then I will start doing tests especially related with configs to have similar behavior of cljfmt

πŸ‘ 3
imre 2025-04-01T17:16:37.667589Z

Are you planning to also have https://github.com/oakmac/standard-clojure-style-js integrated in some form?

ericdallo 2025-04-01T17:23:39.523369Z

Not really @imre

πŸ‘ 1
pez 2025-04-01T17:24:05.985389Z

The maintainer of zprint and I have discussed things also among the issues on zprint, @ericdallo. He’s very responsive and generous with his time. It’s only because his and my attention span for it has never quite overlapped for long periods enough that we haven’t been able to get zprint implemented in Calva as a formatter. Calva uses zprint for formatting things still, just not for the formatting provider.

πŸ‘ 1
ericdallo 2025-04-01T17:24:10.897169Z

the biggest pains from cljfmt ATM mentioned in the original issue: performance + missing vertical aligment configs

pez 2025-04-01T17:24:56.847209Z

I wonder if performance is much better with zprint than with cljfmt, though. I have always thought it was the other way around (but never measured).

ericdallo 2025-04-01T17:24:57.469949Z

got it, one thing I'd love to see someday is calva delegate all format stuff to clojure-lsp like other editors

2025-04-01T17:25:33.445489Z

native zprint is pretty dang fast, clojure zprint is not very fast

ericdallo 2025-04-01T17:25:44.517219Z

at Nubank we are having big problems with cljfmt performance, there are files that take 10mins to format... zprint i wanna test those things

😡 1
πŸ‘€ 1
2025-04-01T17:25:52.740989Z

oh my god lol

2025-04-01T17:26:01.116869Z

zprint was never that bad

ericdallo 2025-04-01T17:26:14.233549Z

yeah, clojure-lsp is native, so we need to use zprint compiled with graal

ericdallo 2025-04-01T17:27:01.117729Z

also we can't have control over vertical alignment, or ensure any standard because cljfmt doesn't support it, and I've been following this cljfmt issue for years, saw multiple PRs that never got merged

pez 2025-04-01T17:29:56.096579Z

I think vertical alignment is pretty close to be added to cljfmt. It has been like that for very long, though, so I could be wrong. @weavejester is also very responsive so checking with him could shed some light on this particular issue. Calva is currently bundling an old fork of cljfmt to support targeted vertical alignment.

Stig Brautaset 2025-04-01T17:33:12.610629Z

What is this vertical alignment you speak up? Is it a Go-style "make my diffs bigger please" setting? πŸ˜„

1
βž• 2
borkdude 2025-04-01T17:35:13.937109Z

why would zprint be faster than cljfmt?

borkdude 2025-04-01T17:36:12.675759Z

> there are files that take 10mins to format huh...

ericdallo 2025-04-01T17:36:40.082009Z

@stig328 we can't ensure code to follow or not this

{:something 1
 :foo       2}
I personally dislike format like that, the point is that we can't ensure use or not that, so there are codebase with multiple standards related to that

πŸ‘ 1
ericdallo 2025-04-01T17:36:54.073879Z

> why would zprint be faster than cljfmt? I don't know if it's, it's something to be tested yet

borkdude 2025-04-01T17:37:12.954529Z

I guess you could test before going through the hoops of building it into clojure-lsp first?

ericdallo 2025-04-01T17:37:44.698949Z

yes, that's what I'm researching right now, how to have a similar config to cljfmt to then compare

weavejester 2025-04-01T17:38:23.281749Z

Vertical alignment is difficult due to the many edge conditions. I made some progress on it, and there's a branch on the repository, but other work interrupted my progress. It's one of those problems that takes a while to get back into due to its complexity.

πŸ‘ 1
lread 2025-04-01T17:43:13.272679Z

I was getting close to finishing a vertical alignment effort for cljfmt, but completely lost my mojo when I got some "why don't you just" feedback (rare in the clojure community, but I actually accidentally asked for it, so kind of my bad!). Never got back to the effort. I was thinking some inline tagging might be interesting because you might not want to vertically align everything.

lread 2025-04-01T17:45:54.298569Z

When working with kkinnear on zprint rewrite-clj-isms/issues, I've always found him very nice to work with. But I also would say the same of weavejester on cljfmt!

borkdude 2025-04-01T17:46:25.459089Z

The zprint config is turing-complete due to SCI. Not sure if that's good or bad though!

πŸ˜‚ 3
lread 2025-04-01T17:47:20.439749Z

There are many many knobs to turn in zprint. The docs can be overwhelming.

πŸ€” 1
weavejester 2025-04-01T17:47:21.033769Z

It's a difficult problem. I can understand getting demotivated!

❀️ 3
lread 2025-04-01T17:49:25.805099Z

@ericdallo when you get some numbers, I'd be interested to see the results of your zprint vs cljfmt perf tests. They both use rewrite-clj zippers under the hood, so I always assumed they would have similar performance.

weavejester 2025-04-01T17:50:39.980869Z

I'm not too surprised that cljfmt ends up being less performant. There are a number of parts of the code that could be made to be more efficient.

πŸ‘ 2
ericdallo 2025-04-01T17:51:27.028139Z

interesting @lee, will do!

weavejester 2025-04-01T17:52:47.678499Z

The design of cljfmt emphasizes clarity over efficiency, as it's easier to start from a clear base and optimize out bottlenecks, than it is to try to begin with something performant but complex. cljfmt is hard enough for me to hold in my head as it is!

ericdallo 2025-04-01T17:53:22.235689Z

yeah, makes total sense @weavejester, thanks for sharing

ericdallo 2025-04-01T17:53:45.627709Z

I will do some tests later with big codebases to understand the tradeoffs, thanks all for the input

weavejester 2025-04-01T17:55:16.382169Z

I do think it wouldn't be hard to improve cljfmt's performance. We could probably do quite well via just memoizing some key functions.

πŸ‘€ 1
borkdude 2025-04-01T17:55:53.093009Z

The design of cljfmt emphasizes clarity over efficiency,probably the reason why cljfmt works in bb as well 😎 babashka

bb -Sdeps '{:deps {dev.weavejester/cljfmt {:mvn/version "0.13.0"}}}' -m cljfmt.main fix ~/dev/clojure/src/clj/clojure/core.clj

pez 2025-04-01T19:15:27.664719Z

I’m curious about the files that take 10m to format. πŸ˜ƒ

ericdallo 2025-04-01T19:17:21.281189Z

one of them is a single edn file, with a single set`#{}` of uuids, like #{#uuid "1234.."} , but with 100k uuids, I know it's a lot, but >10m to format a single set looks weird

2025-04-01T19:57:02.661359Z

well, i spit 100k uuids into a single set in an edn file and zprint crashed after 12 minutes when trying to format it so it's hard to know if it's better than cljfmt in this case

πŸ‘€ 1
2025-04-01T19:58:41.044599Z

however, it did format a 5Mb file of varying shapes and sizes from a single line to a formatted 94k lines in 6 minutes

ericdallo 2025-04-01T20:02:58.676449Z

yeah, of course we excluded this file from formatting after we found out, but there are other cases where the problem is not a single file, but a medium/big size project, so harder to find the performance issues there

2025-04-01T20:05:33.819679Z

comparatively, fipp formats a set of 100k uuids in 1.3 seconds lol

borkdude 2025-04-01T20:11:35.367469Z

why even format that large file, it's not like someone wants to open that in emacs :P

ericdallo 2025-04-01T20:13:14.755799Z

it's part of the classpath, so clojure-lsp considers it when linting/formatting, it took some time to find that file was the culprit

Reut Sharabani 2025-04-02T23:34:19.910479Z

If anyone is interested I recently rebased my PRs for adding vertical alignment (re-implemented by weavejester, so I mostly wrote the tests IIRC): https://github.com/weavejester/cljfmt/pull/299

πŸ‘ 4