diff --git a/flork/_macos.fnl b/flork/_macos.fnl
deleted file mode 100644
index 1c2d72c5..00000000
--- a/flork/_macos.fnl
+++ /dev/null
@@ -1,45 +0,0 @@
-(local {: ok :utils {: assert-bin : dirname : expand-env-vars : sh*}}
- (require :flork))
-
-(local lfs (require :lfs))
-
-(require :_defaults)
-
-(let [src (expand-env-vars :$HOME/.dotfiles/macos/DefaultKeyBinding.dict)
- dest (expand-env-vars :$HOME/Library/KeyBindings/DefaultKeyBinding.dict)]
- (ok :directory (expand-env-vars :$HOME/Library/KeyBindings))
- (ok :symlink dest src))
-
-(let [src (expand-env-vars :$HOME/.dotfiles/macos/colors)
- dest (expand-env-vars :$HOME/Library/Colors)
- (iter dir-obj) (lfs.dir src)
- colors (icollect [entry #(iter dir-obj)]
- (if (entry:match "%.clr$") entry))]
- (ok :directory dest)
- (each [_ color (ipairs colors)]
- (ok :symlink (.. dest "/" color) (.. src "/" color))))
-
-;; TODO tridactyl: https://librewolf.net/docs/faq/#how-can-i-get-tridactyls-native-messaging-to-work-when-i-install-librewolf-with-flatpak
-(let [src (expand-env-vars "$HOME/Library/Application Support/Mozilla/NativeMessagingHosts")
- dest (src:gsub :Mozilla :LibreWolf)]
- (ok :symlink dest src))
-
-(let [mailmate-keybindings (expand-env-vars "$HOME/Library/Application Support/MailMate/Resources/KeyBindings/Alpha.plist")]
- (ok :directory (dirname mailmate-keybindings))
- (ok :symlink mailmate-keybindings
- (expand-env-vars :$HOME/.dotfiles/macos/MailMate.plist)))
-
-(assert-bin :dockutil)
-(let [out (sh* :dockutil :--list)
- items (icollect [line (out:gmatch "[^\n]+")]
- ;; ignore recent apps
- (if (not (line:match "%srecentApps%s")) (line:match "%S+")))]
- (case items
- (where [item] (not= item :Downloads)) (do
- (sh* :dockutil :--remove :all)
- (sh* :dockutil :--add
- (expand-env-vars :$HOME/Downloads)
- :--view :auto :--display :stack
- :--sort :datemodified)
- (sh* :killall :Dock))
- _ (print "ok: dockutil")))
diff --git a/flork/main.fnl b/flork/main.fnl
deleted file mode 100644
index cf051246..00000000
--- a/flork/main.fnl
+++ /dev/null
@@ -1,35 +0,0 @@
-;; TODO Figure out how I want to bootstrap this from a blank slate
-
-(local {: ok
- :utils {: assert-bin : assert-platform : chomp : expand-env-vars : sh*}}
- (require :flork))
-
-(ok :directory (expand-env-vars :$HOME/src))
-
-(ok :git (expand-env-vars :$HOME/.dotfiles)
- "https://git.kejadlen.dev/alpha/dotfiles.git")
-
-(require :_dotfiles)
-
-(if (pcall assert-platform :Darwin) (require :_macos))
-
-(ok :brew)
-;; this is slow...
-; (ok :brew-bundle (expand-env-vars :$HOME/.dotfiles/Brewfile))
-
-;; TODO figure out when this actually needs to be run (or maybe run it always?)
-; (utils.sh* :bat :cache :--build)
-
-;; https://tratt.net/laurie/blog/2024/faster_shell_startup_with_shell_switching.html
-(do
- (assert-bin :dscl) ; TODO Linux
- (let [desired-shell :/bin/sh
- out (sh* :dscl "." :-read (expand-env-vars :$HOME/) :UserShell)
- actual-shell (chomp (out:match "UserShell: (.+)"))]
- (if (not= actual-shell desired-shell) (sh* :chsh :-s desired-shell))))
-
-;; TODO
-;; - brew bundle
-;; - start sketchybar
-;; - install neovim plugins
-;; - install tmux plugins
diff --git a/flork/_defaults.fnl b/frork/_defaults.fnl
similarity index 99%
rename from flork/_defaults.fnl
rename to frork/_defaults.fnl
index 26c3e6cc..7f6a53ad 100644
--- a/flork/_defaults.fnl
+++ b/frork/_defaults.fnl
@@ -1,4 +1,4 @@
-(local {: ok} (require :flork))
+(local {: ok} (require :frork))
;; # TODO restart Dock, Finder, and SystemUIServer on changes
diff --git a/flork/_dotfiles.fnl b/frork/_dotfiles.fnl
similarity index 61%
rename from flork/_dotfiles.fnl
rename to frork/_dotfiles.fnl
index 4adfe601..d5dbe7f8 100644
--- a/flork/_dotfiles.fnl
+++ b/frork/_dotfiles.fnl
@@ -1,4 +1,4 @@
-(local {: ok :utils {: dirname : expand-env-vars}} (require :flork))
+(local {: ok :utils {: dirname}} (require :flork))
(let [dotfiles [:.config
:.digrc
@@ -16,9 +16,12 @@
:.bundle/config
:.cargo/config.toml]]
(each [_ v (ipairs dotfiles)]
- (let [src (expand-env-vars (.. :$HOME/.dotfiles/ v))
- dest (expand-env-vars (.. :$HOME/ v))]
- (if (v:match "/") (ok :directory (dirname dest)))
+ (let [src (.. :$HOME/.dotfiles/ v)
+ dest (.. :$HOME/ v)]
+ (when (v:match "/")
+ (-?> dest dirname (partial #(ok :directory))))
(ok :symlink dest src))))
-(ok :directory (expand-env-vars :$HOME/.config/jj/conf.d))
+(ok :directory :$HOME/.config/jj/conf.d)
+
+(ok :symlink :$HOME/CLAUDE.md :$HOME/.dotfiles/ai/CLAUDE.md)
diff --git a/frork/_firefox.fnl b/frork/_firefox.fnl
new file mode 100644
index 00000000..0b2bb0a7
--- /dev/null
+++ b/frork/_firefox.fnl
@@ -0,0 +1,16 @@
+;; manual steps:
+;; 1. Enable toolkit.legacyUserProfileCustomizations.stylesheets in about:config
+
+(local {: view} (require :fennel))
+(local lfs (require :lfs))
+(local {: ok :utils {: assert-platform : expand-env-vars}} (require :flork))
+
+(assert-platform :Darwin)
+
+(let [profiles-dir (expand-env-vars "$HOME/Library/Application Support/Firefox/Profiles")
+ (iter dir-obj) (lfs.dir profiles-dir)
+ default-dirs (icollect [entry #(iter dir-obj)]
+ (if (entry:match :.default$) entry))
+ src (expand-env-vars :$HOME/.dotfiles/firefox/chrome)]
+ (each [_ dir (ipairs default-dirs)]
+ (ok :symlink (table.concat [profiles-dir dir :chrome] "/") src)))
diff --git a/flork/_local.fnl b/frork/_local.fnl
similarity index 58%
rename from flork/_local.fnl
rename to frork/_local.fnl
index 55ab4610..543672b6 100644
--- a/flork/_local.fnl
+++ b/frork/_local.fnl
@@ -1,8 +1,8 @@
-(local {: ok :utils {: expand-env-vars}} (require :flork))
+(local {: ok} (require :flork))
(let [ComputerName "Perfect Cherry Blossom"
LocalHostName (ComputerName:gsub " " "-")]
(each [pref val (pairs {: ComputerName : LocalHostName})]
(ok :scutil pref val)))
-; (ok :brew-bundle (expand-env-vars :$HOME/.dotfiles/Brewfile.personal))
+(ok :brew-bundle "~/.dotfiles/Brewfile.personal")
diff --git a/frork/_macos.fnl b/frork/_macos.fnl
new file mode 100644
index 00000000..cbb26cd1
--- /dev/null
+++ b/frork/_macos.fnl
@@ -0,0 +1,35 @@
+(local {: ok : register :utils {: assert-bin : dirname : expand-path : sh!}}
+ (require :frork))
+
+(ok :brew)
+
+(require :_defaults)
+
+(let [src "~/.dotfiles/macos/DefaultKeyBinding.dict"
+ dest "~/Library/KeyBindings/DefaultKeyBinding.dict"]
+ (ok :directory "~/Library/KeyBindings")
+ (ok :symlink dest src))
+
+(let [mailmate-keybindings "~/Library/Application Support/MailMate/Resources/KeyBindings/Alpha.plist"]
+ (ok :directory (dirname mailmate-keybindings))
+ (ok :symlink mailmate-keybindings "~/.dotfiles/macos/MailMate.plist"))
+
+(register :dock {:status (fn []
+ (assert-bin :dockutil)
+ (let [out (sh! :dockutil :--list)
+ items (icollect [line (out:gmatch "[^\n]+")]
+ ;; ignore recent apps
+ (if (not (line:match "%srecentApps%s"))
+ (line:match "%S+")))]
+ (case items
+ [:Downloads] :ok
+ _ :conflict-upgrade)))
+ :install #(error "dock install not supported")
+ :upgrade (fn []
+ (sh! :dockutil :--remove :all)
+ (sh! :dockutil :--add (expand-path "~/Downloads")
+ :--view :auto :--display :stack :--sort
+ :datemodified)
+ ;; TODO if we add handlers, do this there instead
+ (sh! :killall :Dock))})
+(ok :dock)
diff --git a/frork/main.fnl b/frork/main.fnl
new file mode 100644
index 00000000..9cfe1d8a
--- /dev/null
+++ b/frork/main.fnl
@@ -0,0 +1,31 @@
+(local {: ok :utils {: assert-bin : chomp : expand-path : platform : sh!}}
+ (require :frork))
+
+(require :types)
+
+(ok :directory "~/src")
+
+(ok :git "~/.dotfiles" "https://git.kejadlen.dev/alpha/dotfiles.git")
+
+(require :_dotfiles)
+
+(if (= platform :darwin) (require :_macos))
+
+;; this is slow...
+(ok :brew-bundle "~/.dotfiles/Brewfile")
+
+;; https://tratt.net/laurie/blog/2024/faster_shell_startup_with_shell_switching.html
+(do
+ (assert-bin :dscl) ; TODO Linux
+ (let [desired-shell :/bin/sh
+ out (sh! :dscl "." :-read (expand-path :$HOME/) :UserShell)
+ actual-shell (chomp (out:match "UserShell: (.+)"))]
+ (if (not= actual-shell desired-shell) (sh! :chsh :-s desired-shell))))
+
+;; TODO figure out when these actually need to be run instead of always doing these
+(sh! :bat :cache :--build)
+(sh! :brew :services :restart :felixkratz/formulae/sketchybar)
+
+;; TODO
+;; - install neovim plugins
+;; - install tmux plugins
diff --git a/frork/types.fnl b/frork/types.fnl
new file mode 100644
index 00000000..fb16e00a
--- /dev/null
+++ b/frork/types.fnl
@@ -0,0 +1,44 @@
+(local {: register :utils {: chomp : sh}} (require :frork))
+
+(register :defaults (let [defaults #(let [(output rc) (sh :defaults $...)]
+ (values (chomp output) rc))]
+ {:status (fn [domain key typ val]
+ ;; (assert-bin :defaults)
+ (if (or (= typ :dictionary) (= typ :array))
+ ;; I don't need this (yet), so defer implementation
+ (error :todo))
+ (let [normalize-value (fn [typ val]
+ (case [typ val]
+ [:boolean :1] :true
+ [:boolean :0] :false
+ _ (val:gsub "\\\\"
+ "\\")))
+ normalize-type #(or (. {:bool :boolean
+ :int :integer}
+ $1)
+ $1)
+ (current-value rc) (defaults :read
+ domain
+ key)
+ ;; extract the type from the "Type is {type}" output
+ current-type (accumulate [t nil m (: (defaults :read-type
+ domain
+ key)
+ :gmatch
+ "%S+")]
+ m)]
+ (if (not= rc 0)
+ :missing
+ (or (not= current-type
+ (normalize-type typ))
+ (not= (normalize-value current-type
+ current-value)
+ (tostring val)))
+ (values :conflict-upgrade
+ {:expected (tostring val)
+ :actual (normalize-value current-type
+ current-value)})
+ :ok)))
+ :install #(defaults :write $1 $2 (.. "-" $3) $4)
+ :upgrade #(defaults :write $1 $2 (.. "-" $3) $4)
+ :remove #(defaults :delete $1 $2)}))