I’m putting together an overview of this whole project on my blog.
A stream covering the motivation and showing some of the namespaces is available on twitch.
I hope to cut it to something shorter and more presentable soon!
–
Buzz: This is an intergalactic emergency. I need to commandeer your vessel to Sector 12. Who’s in charge here?
All Aliens: [pointing up] The clawwwwwwwww[e]!
Alien #1: The claw is our master.
Alien #2: The claw chooses who will go and who will stay.
Woody: This is ludicrous.
For more on Clawe beyond the below readme, check out the clawe garden file on my blog.
It is named after the shape of your hand while trying to nail some of these key bindings.
It started as a CLojure-AWEsomewm experiement, but now cuts off any specific WM via a protocol, and can run on OSX (via yabai) as well.
Clawe is a clojure-based approach to managing your window manager’s configuration, and otherwise hacking scripts/automation together on your machine.
- Dev against your environment with a clojure repl!
- No more write-compile-restart-loop!
- Instead, debug by connecting to a running clojure repl and execing the code.
- Define your keybindings as clojure functions
- Configurable, toggle-able clients that can be repo-workspace aware
- Rofi (or via choose on osx) for listing available commands
- clawe.mx and ralphie.rofi namespaces
- Useful Babashka-based namespaces
- suggesting git clones based on the clipboard and current tabs
clawe.wm provides functions for working with your running clients and workspaces:
Ex:
clawe.wm/focus-client
clawe.wm/delete-workspace
These functions are implemented via a protocol, which means extending the same behavior to other window-managers is fairly reasonable. I’ve implemented it for AwesomeWM and Yabai so far, but am interested in pursuing i3 and bspwm as well.
Much gratitude to borkdude and the clojure community at large!
Clawe would not be possible without the boon that Babashka has brought to the clojure ecosystem. Simplicity + performance!
Clawe uses process everywhere, to shell out and do everything. It’s the
equivalent of $()
in bash.
Nearly all of clawe’s commands are executed almost exclusively as babashka cli commands:
# Toggle open/closed emacs in the current workspace's directory
bb ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle "emacs"
This is of course often better debugged in a clojure repl itself:
(comment (clawe.toggle/toggle "emacs"))
Clawe has been through a few different iterations and experiements - at one point I was using carve to produce ‘micro’-scripts in an effort to improve performance.
Later I had an uberjar flow, which required rebuilding after code changes were made.
Lately I’m in favor of using the babashka/cli style - just run the scripts in
place, call the functions directly with -x
. This has been great and nice to
debug both in the repl and via the terminal. It’s also simple, in that there are
no built artifacts to worry about. I expect this method to stick!
doctor
and most of the other top-level namespaces in clawe are used in a
full-on JVM or browser context. The above clawe features are all babashka-based,
but with doctor
, we get into support for topbars, dashboards, parsing org
files, reviewing chess games, publishing blog posts… all sorts of rabbit holes.
It may have been wise to cut clawe at the above feature set (and I did just that before one day throwing up my hands and combining several repos together).
Instead I’ve been hacking deeper features right on top of it. Keeping things in the same repo lowers the barrier for trying out new things, and at this point the clawe repo has several runtimes.
In particular, the ‘doctor’ backend is jvm based, and not all of the clojure dependencies are babashka compatible.
There are 4 runtimes to be aware of.
the clawe
and ralphie
namespaces are intended to be consumed by babashka
commands, and should be simple, fast, and (mostly) stateless. A clawe.edn
config file is read for most of them to work, but that should be it.
A backend server process running via the jvm - the typical clojure environment, providing a web api and sockets for connecting to the doctor frontend.
Worth noting - this server provides an nrepl for the clawe/ralphie namespaces to connect to, and is where most of clawe’s development happens.
A shadow-cljs process runs the typical frontend clojurescript environment.
Tauri is used, really just for it’s webview, to serve the topbar and a ‘native’ doctor web app (though I often work in a proper dev browser as well.)
Lately this is impled via `clove`, which wraps a Tauri app and exposes an api for launching transparent apps at arbitrary urls.
See the clove repo for install instructions.
With those runtime distinctions in mind…
Doctor is not quite as settled as clawe and ralphie, but it is centered around some core features:
- Topbar
- workspaces and their clients (current workspace, etc)
- queued tasks (todos are parsed from org files and opted into via the doctor’s components)
- Dashboard
- in various views
- org items (parsed and crud-able via russmatney/org-crud)
- commits from repos (parsed via
ralphie/git
) - recent screenshots
- recent games from lichess.org
- setting wallpapers
- in various views
- Sockets via teknql/plasma
- Database via tonsky/datascript
As more doctor features/interfaces settle down, I’ll update these docs with screenshots and usage details.
several local dirs are symlinked into public/assets/
# from clawe root dir
ln -s ~/Screenshots public/assets/screenshots
ln -s ~/gifs public/assets/clips
ln -s ~/Dropbox/wallpapers public/assets/wallpapers
l ~/russmatney/clawe/public/assets/ Name candy-icons -> /home/russ/EliverLara/candy-icons/apps/scalable/ screenshots -> /home/russ/Screenshots/ wallpapers -> /home/russ/Dropbox/wallpapers/
This is a quick hack to let the web apps reference images on the machine (avoids a local image host).
I manually copied the exported css and images into the project:
cp node_modules/chessground/assets/chessground.base.css node_modules/chessground/assets/chessground.brown.css node_modules/chessground/assets/chessground.cburnett.css public/css/.
clove
is a barebones tauri cli. It accepts a title and url, then launches a
tauri webview harness around that url. It sets the window to transparent by
default, so if you want a background, be sure to set one!
The goal is to support local web apps (like the doctor frontend) without requiring a full browser to use them. I.e. don’t let your dashboard get lost in your browser tabs.
See the clove repo for install instructions.
I feel like this is kind of a crazy hack/dev environment - to me, getting to do wm-things in clojure and against a repl is the dream!
I’ve been building it up for a few years now, and am happy to give a tour and share more context.
Feel free to create an issue/discussion in this repo, ping me @russmatney
on
the clojurians slack, or pop in on one of my Twitch streams - I’d love to share
more about it and show how it all fits together.
./test_runner.clj
Runs some babashka-based clawe unit tests.
./bin/kaocha unit
Bit of a wip for the moment, but hopefully there’s a one-line approach to running these soon.
These tests exercise the window manager in place - i.e. this will create and destory workspaces in your current environment.
./bin/kaocha integration
These don’t run in CI, but are a useful way to debug or ensure basic clawe usage isn’t borked.
Expects a running awesomewm and fennel setup, which unfortunately is not well documented or easily created at the moment.
./bin/kaocha awesomewm