I refactored most of clawe last week (early august 2022).
It'd be good to capture what happened and why, and to share that as a post.
some raw:
clawe clients need def backing (persisted) so that i can:
just a name gets you pretty far, b/c you can sync across apps for workspaces
(emacs, tmux) to get re-openable state - useful when moving between contexts to
re-open a workspace just as you left it
bb-cli unlocks some strong apis that i can bake inputs of into the config, and
also easily test on the command line. it's already been a treat for
clawe.toggle/toggle-app
babashka/cli
's
-x
feature plus arg coercion lets you call
arbitrary
functions in your scripts with well formed inputs. It's an excellent
combination, and spurred a clawe refactor (re-achitecture) that I hope to write
up soon. (Though I do have a brief bb-cli note here.)
For today, just want to share a piece of the new
structure:
clawe.debug/ls
and
clawe.debug/ls-print
.
When debugging clawe, especially clawe's toggle feature, I often need to get a look at the workspaces and clients that are currently running - specifically the names, window titles, class names, etc, which are used to match with client/workspace definitions. When you invoke toggle for "spotify", clawe determines the current need. Are we already focusing spotify? Does the client exist in a different workspace? When this goes wrong, we need to figure out why.
The debug namespace is a quick way to list the
clients or workspaces that clawe knows about -
(clawe.debug/ls {:type
:clients})
in a repl is
simple and quite useful.
But sometimes you're not in a clojure repl, or you want to know what a fresh invokation of clawe would see. Maybe the repl state has some advantage or difference from the actual toggle invokation that your keybinding is sending.
> This is especially true for clawe, as I like to develop it against the > fully-featured jvm cider repl (against doctor 's backend server) rather than a > basic bb-repl. This supports extremely useful features like cider-inspect, > and makes clojure development a real joy.
Fortunately, bb-cli's
-x
lets us invoke the exact command on the
command line:
> alias clawebb='bb --config ~/russmatney/clawe/bb.edn'
> clawebb -x clawe.debug/ls-print --type :clients
| :client/window-title | :client/app-name |
|--------------------------------+------------------|
| clawe | alacritty |
| clawe | emacs |
| dino | emacs |
| dotfiles | emacs |
| tauri-doctor-topbar | clove |
| journal | emacs |
| slack | clojurians | slack |
| spotify | spotify |
| babashka/cli — mozilla firefox | firefox |
There we are! We can see that the spotify client is found and properly labelled.
Note that here we're calling
ls-print
instead, which is a simple wrapper that
passes the ls
results to
clojure.pprint/print-table
.
---
A few weeks after this implementation, I started toying with nextjournal/clerk,
and it was a delight to find that
clawe.debug/ls
can feed directly into
clerk/table
, which led to
this tiny tmux status notebook:
(ns notebooks.tmux
{:nextjournal.clerk/visibility {:code :hide :result :show}}
(:require
[clawe.debug :as debug]
[nextjournal.clerk :as clerk]))
;; ### tmux sessions
^::clerk/no-cache
(clerk/table (debug/ls {:type :tmux}))
;; ### tmux panes
^::clerk/no-cache
(clerk/table (debug/ls {:type :tmux-panes}))
---
Another piece of the
clawe
refactor: Clawe now invokes its
keybindings by default with
-x
.
;; from clawe/defs/bindings.clj
(defkbd toggle-terminal
[[:mod] "Return"]
(sxhkd-exec "bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle --key terminal"))
(defkbd toggle-emacs
[[:mod :shift] "Return"]
(sxhkd-exec "bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle --key emacs"))
(defkbd toggle-workspace-journal
[[:mod] "u"]
(sxhkd-exec "bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle --key journal"))
(defkbd toggle-workspace-web
[[:mod] "t"]
(sxhkd-exec "bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle --key web"))
Prior to this, I was using a defthing macro to register commands, and invoking them by passing the name into clawe's main function.
This change simplified the architecture by completely removing that registry,
and has the added benefit of making it very simple to reproduce an invokation -
you can just invoke it yourself:
bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle --key journal
This ends up being more performant as well -
there's no need to require every namespace in clawe to call
one command. When invoked via
-x
, only the
required namespaces are loaded, so we get to the good bits
right away.
---
For more on Clawe's features and design journey, check out the clawe workspace note.
Aha! moments - moments of insight that unlock the clarity and confidence while designing and implementing something.
The goal of a Hammock or Procrastination session.
Worth capturing!
babashka/cli
is a few input arg parsers/coercers
and babashka
features (
-x my-ns/my-func
) that make it dead simple to call a
clojure function with coerced args on the command
line.
I just refactored my clawe app-toggle on osx, and it's now just one function
called with a bunch of different args in my yabai keybindings:
# emacs, term toggling
shift + cmd - return : bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle-app --client emacs --app Emacs
cmd - return : bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle-app --client terminal --app Alacritty
cmd - u : bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle-app --wsp journal --title journal --app Emacs
cmd - t : bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle-app --wsp web --app Safari
cmd - b : bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle-app --wsp devweb --app "Firefox Developer Edition"
cmd - s : bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle-app --wsp spotify --app Spotify
cmd - e : bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle-app --wsp aseprite --app Aseprite
cmd - a : bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle-app --wsp slack --app Slack
cmd - m : bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle-app --wsp messages --app Messages
cmd - g : bb --config ~/russmatney/clawe/bb.edn -x clawe.toggle/toggle-app --wsp godot --app Godot