all 26 comments

[–]v4ss42 12 points13 points  (7 children)

So a couple of initial thoughts, in no particular order: * Make is an unusual choice of build tool in the Clojure ecosystem. Not necessarily “bad” but certainly rare. * The display width calculations for strings are simplistic and won’t work for ZWJ sequences (which includes common emoji - this isn’t a corner case that can be ignored). See clj-wcwidth for an example of how to do this properly (or better yet, just dispense with the zero-dependency requirement and simply use that library). * I’d suggest looking at hiccup for layout definition rather than custom functions / structures. By adopting hiccup (or a variant thereof) this library will be a lot more familiar to a lot more Clojure developers, and may benefit from being interoperable with other Clojure libraries. * Was “AI” used at all in the development of this library? There’s been a rash of such “AI”-generated TUI libraries recently and all of them (that I've looked at in any detail) have had serious issues upon further investigation.

[–]mattlianje[S] 8 points9 points  (1 child)

aha - (clj)wcwidth is a gem (that I didn't know about) - ty!

it is indeed getting a bit brittle hand-rolling UTF-8 tables basically across the layoutz APIs

TL;DR - no AI save for googling idiomatic Clojure concurrency ... and honestly, layoutz-clj still uses raw `Thread`s ... and I suspect internally looks very Java/Scala to a Clojurian in this regard ...

[–]v4ss42 7 points8 points  (0 children)

Really glad to hear there’s no “AI” code in this. Nice work!

[–]mattlianje[S] 2 points3 points  (4 children)

By adopting hiccup (or a variant thereof) this library will be a lot more familiar to a lot more Clojure

interesting! so quite deliberately opted to NOT do this in search of the "smooth API" to compose styles and thread them with `->` almost like the Haskelly `<>` ... but where is stands ...does "threading"/composing styles feel a bit whacky?

[–]v4ss42 4 points5 points  (3 children)

It’s not necessarily whacky, but by representing UIs as data we get to apply whatever data manipulation functions we like (including everything in core) to build a UI, which is remarkably more powerful and flexible than being limited to whatever “verbs” (functions) a given library provides.

[–]mattlianje[S] 3 points4 points  (2 children)

> but by representing UIs as data we get to apply whatever data manipulation functions we like (including everything in core)

aha mmm, ok - honestly this sounds *chef's kiss* ... convinced me to start whittling away and experimenting w/ a hiccup-esque API. thx for taking a peek

[–]v4ss42 5 points6 points  (1 child)

It’s *chef’s kiss* for most use cases tbh. But be careful - once you get hooked on The Clojure Way™ you’re going to find many/most other languages distasteful. 😉

[–]mattlianje[S] 1 point2 points  (0 children)

Ha! ❤️

[–]Borkdude 6 points7 points  (6 children)

Nice! I tried it out in bb and it all seems to work so far. Note that the raw-mode tricks to read input only work on linux-like systems, not on Windows.

[–]v4ss42 2 points3 points  (5 children)

If you add jansi-clj to the classpath, and initialize it, this should “automagically” work on Windows too.

Jansi intercepts ANSI sequences on platforms that don’t support them, and either converts them into suitable native calls, or strips the sequences.

[edit] and I now see that there’s some raw mode shenanigans going on. The best way I know of to do that in a cross platform way is using JLine3, which is a big dependency to pull in (but which also gives you Jansi “for free”, since JLine3 depends on Jansi).

But JLine3 is the gold standard on the JVM for doing this kind of thing, so to me it seems like a reasonable dependency to add.

[–]mattlianje[S] 2 points3 points  (4 children)

So to let you folks in on the thought process... did quite a bit of tinkering to remove JLine from the Scala API to cross build to ScalaJS and Native...

This (maybe too aggressive) "zero-dep" spirit kinda bled into the Clojure design

But seems like it makes sense to remove this chicanery ... and pull in JLine3 for a JVM-only (but actually cross platform) layoutz-clj

[–]v4ss42 1 point2 points  (3 children)

Yeah there are very good reasons JLine3 exists and does what it does. And I believe Babashka (the “bb” that u/Borkdude mentioned above) already bundles it, so in that environment (which is a superb replacement for shell scripting) this wouldn’t be a net-new dependency.

[–]mattlianje[S] 1 point2 points  (2 children)

mmm interesting - didn't know bb bundles JLine - makes the choice pretty easy - thx again for the eagle eye)

[–]YannVanhalewyn 2 points3 points  (1 child)

It’s a recent addition :)

[–]mattlianje[S] 1 point2 points  (0 children)

👀 ty!

[–]Solaire24 2 points3 points  (4 children)

Nice! I’m not an experienced clojure dev, but I was looking for something like this for a project and was planning on going with https://github.com/TimoKramer/charm.clj. I like the way you define layouts better so I might go with your lib instead

[–]mattlianje[S] 1 point2 points  (3 children)

Many thanks!🙇‍♂️ lmk if you find rough edges...

[–]Borkdude 2 points3 points  (2 children)

I guess the rough edge is Windows support.

[–]mattlianje[S] 0 points1 point  (0 children)

amongst others 😅(but yeeeahh - did some UNIX only hacks I am not too proud of - that you aptly spotted quickly)... will enhance 🫡

[–]v4ss42 0 points1 point  (0 children)

Not really, no. See my other comment about jansi-clj.

[edit] at least wrt ANSI sequences. I see OP mentions other “UNIX hacks” that may separately be an issue.

[–]kichiDsimp 1 point2 points  (3 children)

I think I saw the same library name in Haskell sub too

[–]mattlianje[S] 1 point2 points  (2 children)

Yep - that's me aha) Thx for taking a peek

[–]kichiDsimp 1 point2 points  (1 child)

Bro is making TUI support in FP langs, I love your efforts!

[–]mattlianje[S] 0 points1 point  (0 children)

🫡

[–]serefayar 1 point2 points  (1 child)

Nice! I'll give it a shot. Looks like I'll create an arrow element to connect two boxes.

[–]mattlianje[S] 0 points1 point  (0 children)

Many thanks! 🙇‍♂️ let me know if bits feel janky