Skip to content

babashka/obb

Repository files navigation

obb

project chat Stability: Experimental

Ad-hoc ClojureScript scripting of Mac applications via Apple's Open Scripting Architecture.

Status

Experimental.

Installation

Homebrew

$ brew install babashka/brew/obb

Manual

Download from Github releases.

Usage

Evaluate an expression:

$ obb -e '(-> (js/Application "Safari") (.-documents) (aget 0) (.url))'
"https://clojure.org/"
$ obb -e '(-> (js/Application "Google Chrome") (.-windows) (aget 0) (.activeTab) (.title))'
#js ["GitHub - babashka/obb: Ad-hoc ClojureScript scripting of Mac applications"]

Or evaluate a file:

$ obb examples/choice.cljs

Or make an executable script by using obb in a shebang:

#!/usr/bin/env obb
(-> (js/Application "Safari")
    (.quit))

How does this tool work?

ClojureScript code is evaluated through SCI, the same interpreter that powers babashka. SCI is compiled to JavaScript which is then by executed by osascript.

Macros

SCI supports macros as first class citizens so you can write a few macros to deal with interop boilerplate:

(defmacro ->clj [obj & interops]
  (let [names (map #(clojure.string/replace (str %) #"[.-]" "") interops)
        ks (mapv keyword names)
        exprs (mapv #(list % obj) interops)]
    `(zipmap ~ks [~@exprs])))

(-> (js/Application "Spotify") (.-currentTrack) (->clj .artist .album .name))
;;=>
{:artist "The Gathering", :album "How to Measure a Planet? (Deluxe Edition)", :name "Travel"}

References

Tips and tricks

Explore app specific APIs

Open Script Editor.app, go to File > Open Dictionary and select the application you would like to explore, e.g. Spotify.app. After selection, select JavaScript instead of AppleScript.

Application bundle

Read here how to create an application bundle from an obb script.

Sister projects

  • babashka: Native, fast starting Clojure interpreter for scripting.
  • nbb: Ad-hoc CLJS scripting on Node.js using SCI.
  • scittle: The Small Clojure Interpreter exposed for usage in browser script tags.

Build

Install Babashka. Then build with:

$ bb build

Then place out/obb anywhere on your path.

Dev

To develop obb you can use the bb dev task which starts a shadow-cljs server and a file watcher.