A video overview of the components that make up the clawe monorepo.
Relevant April 2023.
I did a stream covering clawe and this note on 4/28/23, here: https://www.twitch.tv/videos/1805970411?t=2h59m42s
I hope to crunch this into a shorter youtube video soon!
I'm big on dev tools! Developers need to keep their knives sharp! Tools are super important for leverage. Work is about feedback loops and flow. Yada yada yada.
Clawe is a monorepo. Hooray!
When I first switched from osx to linux, I was unlocked - I started realizing I could just write bash to do the things I wanted. I was in i3, but had been all about hammerspoon and mjolnir + alfred.
I started with a universal movement command, but integrating with emacs, i3, browsers, tmux, and vim posed an interesting design challenge. How to manage all that complexity?
ralphie offers nice data-driven apis
clawe.edn expresses them
clawe/wm/etc does whatever logic to make it work
(this list reminds me of yodo's integrations )
This could go on a bit too long. Too much love to share.
opinionated, but structured editing is quite excellent.
(lisps unlock the simplicity of repl-driven development)
The dream of the 90s (isomorphic javascript) is alive in clojure!
More than just front+back end clojure!
Now we're in the blissful land of bash scripting.
clojure is highly performant
very little code to do pretty much everything
Expressive, data-driven ( constraint-based ) database query engines
if you want the 'features' of types. (i.e. crashing)
ex: testing your keybindings in your editor
No more editing some whacky lua/i3/bash and then rerunning it.
You should only need to restart the whole thing (awesomeWM, i'm looking at you)
on the rarest of occasions
Tauri is basically a newer electron.
We can run the same logic for scripting as on the backend as on the frontend!
We just wrap react and then do whatever we want.
JS (and TS) are just so much code, and not much benefit to all the extra fluff.
Plus there's lots of nonsense... it honestly feels like arguing osx over linux.
Styling awesomeWM widgets vs writing hiccup and adding tailwind classes is not much fun, especially given the feedback loop of editing clojure on shadowcljs.
And then there's handling a datamodel - I want to send workspaces full of data into rich little components, full of metadata.
Tailwind css is an excellent tool for staying in the code and still getting everything out of css's latest features. That plus hiccup+cljs means you can write the structure, styling, and logic all in a cljs file, with live-reloading and repl-driven dev. It's glorious!
clojure all the things!
Now we're able to re-use our code when writing fancy dev-tooling scripts over many different integrations.
clojure as a glue language
Note that these are also consumable by 'backend' clojure code!
You know, if your keybindings need to parse your org-roam files, for example.
Not that anyone asked...
Ralphie gets into the nitty-gritty of the integrations, and presents reasonable map-based functions for the other parts of clawe to consume.
ralphie.browser
ralphie.spotify
ralphie.tmux
(tmux/fire
{:tmux.fire/command "echo 'hi'" :tmux/session
"dev"})
This will create the session if it doesn't exist, and create a new pane (via split) if the default one is busy.
Very useful for running any script/task/app, and keeping an eye on its logs.
ralphie.emacs
ralphie.awesome
ralphie.yabai
-x
supportTho there is some in-lining of functions in awesome-wm, kind of a fun performance hack.
I dug into building and stripping down bb
uberscripts (with carve
), and building jars, but the
-x
performance proved to be the same AND no
building-it overhead. It does have the problem of running
the live code, so there's no clawe executable - right now
it runs the code as-is from the machine's local
repo.
Inspired by emacs' interactive commands (m-x) - clawe-mx was originally a
rofi-menu expressing a macro called
defcom
, but
it's grown to include a number
of fancy actions, including:
I have a strong opinion on workspace usage. (Note that this is note a required opinion for working with clawe).
I create workspace per repo, and have workspace-context as an input to several keybindings.
mod + enter
-> toggle open/close/focus the
workspace's tmux sessionmod + shift +
enter
-> toggle
open/close/focus the workspace's emacs
sessionclawe-mx
suggests
tmux/fire
of the wsp-repo's
babashka
tasksA config file defining workspaces and clients, along with behaviors for them.
(e.g. how should a client react to a toggle request?)
This has not yet been broken out of the repo, but can be done without much effort (blog.config works the same without the file being local - it's likely just updating the paths and then providing a reasonable default/example config).
Undertow? Ring? I can't recall, there's so little to it.
like polybar, but cljs + tailwind + datascript
manages todos from org
manages reviewing and publishing org-roam notes
A review app? Maybe I should mention yodo?
This is where org-crud meets clawe/doctor's note and todo domain. Intended to support whatever features we need from integrating the mindgarden.
I originally implemented a clerk -based blog, but that process taught me how simple hiccup and slurp/spit can be, and i drooled over a proper clawe integration and using the clawe dashboard to manage publishing to multiple platforms (integrations like dev.to, reddit, mastodon, etc).
A datascript db, mostly consumed by doctor, but optionally available to ralphie and clawe (and other babashka needs).
I've not explored this much, but I'm hopeful it's reasonably accessible.
Intended to support agnostic full-stack features.
At one point doctor wasn't the only full-stack app, but I've recently deleted expo to keep things focused for now.
The hope with some of the
components.*
in particular is that they can be uix
and doctor.ui.db independent, so they are reusable in the
backend blog/hiccup work.
the lichess integration. Perhaps this should be moved to ralphie? It was originally a separate repo.
I owe a licensing update related to some of the components.chess code!!
Perhaps these should live in ralphie, but I'm reluctant to add db.core deps to ralphie namespaces.
I'm also reluctant to bury these in doctor, when they can still reasonably be consumed by clawe.
I'm also reluctant to bury these in clawe, which i hope to not litter with lots of integration-style namespaces.
Mostly I'm just reluctant... whatever, it's fine for now.
Similar to screenshots/wallpapers. Perhaps they _do_ belong in clawe... but I hate long namespaces if I can help it.
Often, working with a generic item is useful and common enough, so this namespace exists to provide resonable shared logic across integrations.
Utility libs, usable everywhere.
An old but still used for linux-keybindings abstraction.
In 2020, I spent an awful lot of time working on the end of todo apps, an idea I called 'Yodo'. The idea was to develop an app to cut out the overhead and just tell me the next thing on my list. It should be smart enough to make suggestions based on time of day, day of week, weather, current status of sprint, pomodoros, everything.
It was a great build, but at the end it was trapped in a web-app, and didn't dip quite low enough to be useful when working on other things. Ultimately, I dropped it in favor of: let's just make stuff for a while. I had some tastes of success making some scrappy love2d games, and then I got pulled into contract work for another year and a half.
Along the way, I ran into babashka, and I started ralphie, which eventually led to clawe for the window-management features. I also pulled the org bit of yodo OUT of yodo and into org-crud.
Several abstractions and refactors later ( defthing, expo, org-blog ), we're at today. Whow knows where we'll be next time?
plasma's defhandler lets you write backend functions in cljc files, then call them from cljs. Like, actually.
Then defstream lets you keep those requests up to date.
You consume them on the frontend via 'hooks' apis.
It takes time to get comfortable with these tools.
counter: it's much easier now than it was even 5 years ago (because doom emacs is five years further along).