diff --git a/bork/Brewfile b/Brewfile
similarity index 96%
rename from bork/Brewfile
rename to Brewfile
index 4916e20b..f5c4d9c7 100644
--- a/bork/Brewfile
+++ b/Brewfile
@@ -12,6 +12,7 @@ brew "curl"
brew "difftastic"
brew "direnv"
brew "docker"
+brew "dockutil"
brew "entr"
brew "eza"
brew "fd"
@@ -84,7 +85,7 @@ cask "ghostty"
cask "hammerspoon"
cask "keyboardcleantool"
cask "kicad"
-cask "librewolf", args: %w[ no-quarantine ]
+cask "librewolf", args: { "no-quarantine" => true }
cask "mailmate"
cask "neovide"
cask "obsidian"
diff --git a/personal/Brewfile b/Brewfile.personal
similarity index 100%
rename from personal/Brewfile
rename to Brewfile.personal
diff --git a/bork/_defaults.sh b/bork/_defaults.sh
deleted file mode 100644
index 2088dc20..00000000
--- a/bork/_defaults.sh
+++ /dev/null
@@ -1,75 +0,0 @@
-### defaults
-
-# TODO restart Dock, Finder, and SystemUIServer on changes
-
-### global defaults
-
-ok defaults -globalDomain NSDisableAutomaticTermination bool true # don't quit idle applications
-ok defaults -globalDomain AppleFontSmoothing int 0 # disable font smoothing
-ok defaults -globalDomain AppleKeyboardUIMode int 3 # full keyboard access
-ok defaults -globalDomain AppleShowAllExtensions bool true # show all extensions by default
-ok defaults -globalDomain KeyRepeat int 2 # keyboard repeat rate
-ok defaults -globalDomain InitialKeyRepeat int 25 # delay before keyboard repeat
-ok defaults -globalDomain NSTableViewDefaultSizeMode int 1 # set sidebar item size to small
-ok defaults -globalDomain NSQuitAlwaysKeepsWindows bool false # disable resume
-ok defaults -globalDomain WebKitDeveloperExtras bool true # add debug menu in web views
-ok defaults -globalDomain com.apple.mouse.tapBehavior bool true # tap to click
-ok defaults -globalDomain AppleShowScrollBars string WhenScrolling # only show scrollbars when scrolling
-ok defaults -globalDomain NSWindowShouldDragOnGesture bool true # move windows by holding ctrl+cmd and dragging any part of the window
-
-ok defaults com.apple.dashboard mcx-disabled bool true # disable dashboard
-ok defaults com.apple.desktopservices DSDontWriteNetworkStores bool true # don't write .DS_Store to network volumes
-
-ok defaults com.apple.dock autohide bool true # automatically hide and show the dock
-ok defaults com.apple.dock mineffect string scale # minimize windows using the scale effect
-ok defaults com.apple.dock mru-spaces bool false # don't rearrange spaces
-ok defaults com.apple.dock orientation string left
-ok defaults com.apple.dock wvous-bl-corner int 10 # the bottom left hot corner to sleep the display
-ok defaults com.apple.dock tilesize int 36 # set the icon size to 36 pixels
-ok defaults com.apple.dock autohide-delay float 0 # no dock delay
-ok defaults com.apple.dock showhidden bool true # show hidden apps
-
-# https://nikitabobko.github.io/AeroSpace/guide#a-note-on-displays-have-separate-spaces
-ok defaults com.apple.spaces spans-displays bool true disable
-
-ok defaults com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking int 1
-ok defaults com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadFourFingerVertSwipeGesture int 0
-ok defaults com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadThreeFingerDrag bool true
-ok defaults com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadThreeFingerHorizSwipeGesture int 0
-ok defaults com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadThreeFingerVertSwipeGesture int 0
-
-# # Finder defaults
-ok defaults com.apple.finder FXEnableExtensionChangeWarning bool false # don't ask when changing file extension
-ok defaults com.apple.finder FXPreferredViewStyle string Nlsv # default to list view
-ok defaults com.apple.finder QLEnableTextSelection bool true # enable text selection in QuickLook
-ok defaults com.apple.finder _FXShowPosixPathInTitle bool true # show full path in Finder
-ok defaults com.apple.Finder NSToolbarTitleViewRolloverDelay float 0 # remove the proxy icon hover delay
-# https://twitter.com/chucker/status/1395843084383043584
-ok defaults com.apple.Finder NSWindowSupportsAutomaticInlineTitle bool false # show the proxy icon and older titlebar
-
-ok defaults com.apple.universalaccess showWindowTitlebarIcons bool true # show the proxy icon always
-
-ok defaults com.apple.Safari IncludeInternalDebugMenu bool true # enable Debug menu in Safari
-
-ok defaults com.apple.screencapture disable-shadow bool true # no window shadows when capturing windows
-ok defaults com.apple.screencapture location string "$HOME/Downloads"
-
-ok defaults com.apple.screensaver askForPassword int 1
-
-ok defaults com.apple.Terminal ShowLineMarks bool false
-
-ok defaults com.google.Chrome AppleEnableSwipeNavigateWithScrolls bool false
-
-# TODO com.freron.MailMate MmAllowedImageURLRegexp
-# ok defaults com.freron.MailMate MmAllowedImageURLRegexp string "https://({{ mailmate.allowed_image_regexps | join('|') }})"
- # - (i|images|d)\.gr-assets\.com
- # - www\.goodreads\.com
- # - massdrop-s3\.imgix\.net
- # - .*\.cloudfront\.net
- # - s3\.amazonaws\.com
- # - files\.convertkitcdn\.com/assets/pictures
- # - wizardzines\.com
-
-ok defaults com.freron.MailMate MmSendMessageDelayEnabled bool true
-ok defaults com.freron.MailMate MmSendMessageDelay int 60
-
diff --git a/bork/bootstrap.sh b/bork/bootstrap.sh
deleted file mode 100644
index 406dabdb..00000000
--- a/bork/bootstrap.sh
+++ /dev/null
@@ -1,61 +0,0 @@
-# TODO use scutil to set the machine name
-
-ok directory ~/src
-
-# ok git ~/src/dotfiles https://git.kejadlen.dev/alpha/dotfiles.git
-
-register brew-bundle.sh
-
-# symlink dotfiles directly in $HOME
-declare -a dotfiles=(
- ".config"
- ".digrc"
- ".gemrc"
- ".gitconfig"
- ".hammerspoon"
- ".inputrc"
- ".local"
- ".p10k.zsh"
- ".profile"
- ".ruby-version"
- ".tmux.conf"
- ".zsh"
- ".zshenv"
- ".zshrc"
-
- ".bundle/config"
- ".cargo/config.toml"
- ".docker/config.json"
-)
-for file in "${dotfiles[@]}"; do
- ok directory "$(dirname $file)"
- ok symlink "$HOME/$file" "$HOME/.dotfiles/$file"
-done
-
-### macos
-
-ok brew
-ok brew-bundle "$HOME/.dotfiles/bork/Brewfile"
-
-ok symlink "$HOME/Library/Application\ Support/LibreWolf/NativeMessagingHosts" "$HOME/Library/Application\ Support/Mozilla/NativeMessagingHosts"
-
-### jujutsu
-
-jj_config=$(jj config path --user)
-ok directory "$(dirname "$jj_config")"
-ok symlink "$jj_config" "$HOME/.config/jj/config.toml"
-
-include _defaults.sh
-
-# TODO set the default shell to /bin/sh
-# dscl . -read ~/ UserShell
-# https://tratt.net/laurie/blog/2024/faster_shell_startup_with_shell_switching.html
-# - name: Set default shell to sh
-# ansible.builtin.user:
-# name: alpha
-# shell: /bin/sh --login
-
-# TODO
-# luarocks install fennel
-
-# TODO tridactyl: https://librewolf.net/docs/faq/#how-can-i-get-tridactyls-native-messaging-to-work-when-i-install-librewolf-with-flatpak
diff --git a/bork/brew-bundle.sh b/bork/brew-bundle.sh
deleted file mode 100644
index af74b7fd..00000000
--- a/bork/brew-bundle.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-action=$1
-file=$2
-shift 2
-
-export HOMEBREW_BUNDLE_FILE=$file
-
-case $action in
- status)
- baking_platform_is "Darwin" || return $STATUS_UNSUPPORTED_PLATFORM
- needs_exec "brew" || return $STATUS_FAILED_PRECONDITION
- bake [ -e $file ] || return $STATUS_FAILED_PRECONDITION
- HOMEBREW_NO_AUTO_UPDATE=true bake brew bundle check --no-upgrade > /dev/null || return $STATUS_MISSING
- HOMEBREW_NO_AUTO_UPDATE=true bake brew bundle check > /dev/null || return $STATUS_OUTDATED
- return $STATUS_OK ;;
- install)
- HOMEBREW_NO_AUTO_UPDATE=true bake brew bundle install
- ;;
- upgrade)
- HOMEBREW_NO_AUTO_UPDATE=true bake brew bundle upgrade
- ;;
- remove)
- return $STATUS_CONFLICT_HALT
- ;;
- *) return 1 ;;
-esac
diff --git a/flork/_defaults.fnl b/flork/_defaults.fnl
new file mode 100644
index 00000000..258dc90e
--- /dev/null
+++ b/flork/_defaults.fnl
@@ -0,0 +1,98 @@
+(local {: ok} (require :flork))
+
+;; # TODO restart Dock, Finder, and SystemUIServer on changes
+
+(local domain-defaults
+ {:-globalDomain [; don't quit idle applications
+ [:NSDisableAutomaticTermination :bool true]
+ ; disable font smoothing
+ [:AppleFontSmoothing :int 0]
+ ; full keyboard access
+ [:AppleKeyboardUIMode :int 3]
+ ; show all extensions by default
+ [:AppleShowAllExtensions :bool true]
+ ; keyboard repeat rate
+ [:KeyRepeat :int 2]
+ ; delay before keyboard repeat
+ [:InitialKeyRepeat :int 25]
+ ; set sidebar item size to small
+ [:NSTableViewDefaultSizeMode :int 1]
+ ; disable resume
+ [:NSQuitAlwaysKeepsWindows :bool false]
+ ; add debug menu in web views
+ [:WebKitDeveloperExtras :bool true]
+ ; tap to click
+ [:com.apple.mouse.tapBehavior :bool true]
+ ; only show scrollbars when scrolling
+ [:AppleShowScrollBars :string :WhenScrolling]
+ ; move windows by holding ctrl+cmd and dragging any part of the window
+ [:NSWindowShouldDragOnGesture :bool true]]
+ :com.apple.dock [; automatically hide and show the dock
+ [:autohide :bool true]
+ ; minimize windows using the scale effect
+ [:mineffect :string :scale]
+ ; don't rearrange spaces
+ [:mru-spaces :bool false]
+ [:orientation :string :left]
+ ; the bottom left hot corner to sleep the display
+ [:wvous-bl-corner :int 10]
+ ; set the icon size to 36 pixels
+ [:tilesize :int 36]
+ ; no dock delay
+ [:autohide-delay :float 0]
+ ; show hidden apps
+ [:showhidden :bool true]]
+ ; https://nikitabobko.github.io/AeroSpace/guide#a-note-on-displays-have-separate-spaces
+ :com.apple.spaces [[:spans-displays :bool true]]
+ :com.apple.driver.AppleBluetoothMultitouch.trackpad [[:Clicking :int 1]
+ [:TrackpadFourFingerVertSwipeGesture
+ :int
+ 0]
+ [:TrackpadThreeFingerDrag
+ :bool
+ true]
+ [:TrackpadThreeFingerHorizSwipeGesture
+ :int
+ 0]
+ [:TrackpadThreeFingerVertSwipeGesture
+ :int
+ 0]]
+ ; don't write .DS_Store to network volumes
+ :com.apple.desktopservices [[:DSDontWriteNetworkStores :bool true]]
+ :com.apple.finder [; don't ask when changing file extension
+ [:FXEnableExtensionChangeWarning :bool false]
+ ; default to list view
+ [:FXPreferredViewStyle :string :Nlsv]
+ ; enable text selection in QuickLook
+ [:QLEnableTextSelection :bool true]
+ ; show full path in Finder
+ [:_FXShowPosixPathInTitle :bool true]
+ ; remove the proxy icon hover delay
+ [:NSToolbarTitleViewRolloverDelay :float 0]
+ ; https://twitter.com/chucker/status/1395843084383043584
+ ; show the proxy icon and older titlebar
+ [:NSWindowSupportsAutomaticInlineTitle :bool false]]
+ ; show the proxy icon always
+ :com.apple.universalaccess [[:showWindowTitlebarIcons :bool true]]
+ ; enable Debug menu in Safari
+ :com.apple.Safari [[:IncludeInternalDebugMenu :bool true]]
+ :com.apple.screensaver [[:askForPassword :int 1]]
+ :com.freron.MailMate [[:MmSendMessageDelayEnabled :bool true]
+ [:MmSendMessageDelay :int 60]
+ [:MmAllowedImageURLRegexp
+ :string
+ (.. "https://("
+ (table.concat ["(i|images|d)\\.gr-assets\\.com"
+ "www\\.goodreads\\.com"
+ "massdrop-s3\\.imgix\\.net"
+ ".*\\.cloudfront\\.net"
+ "s3\\.amazonaws\\.com"
+ "files\\.convertkitcdn\\.com/assets/pictures"
+ "wizardzines\\.com"
+ "www\\.redfin\\.com/stingray/do/api-get-listing-hero-shot"]
+ "|")
+ ")")]]})
+
+(each [domain defaults (pairs domain-defaults)]
+ (each [_ [key typ val] (ipairs defaults)]
+ (ok :defaults domain key typ val)))
diff --git a/flork/_dotfiles.fnl b/flork/_dotfiles.fnl
new file mode 100644
index 00000000..8256e357
--- /dev/null
+++ b/flork/_dotfiles.fnl
@@ -0,0 +1,30 @@
+(local {: ok :utils {: chomp : dirname : expand-env-vars : sh*}}
+ (require :flork))
+
+(let [dotfiles [:.config
+ :.digrc
+ :.gemrc
+ :.gitconfig
+ :.hammerspoon
+ :.inputrc
+ :.local
+ :.p10k.zsh
+ :.profile
+ :.ruby-version
+ :.tmux.conf
+ :.zsh
+ :.zshenv
+ :.zshrc
+ :.bundle/config
+ :.cargo/config.toml
+ :.docker/config.json]]
+ (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)))
+ (ok :symlink dest src))))
+
+(let [jj-config (chomp (sh* :jj :config :path :--user))]
+ (ok :directory (dirname jj-config))
+ (ok :symlink jj-config (expand-env-vars :$HOME/.config/jj/config.toml)))
+
diff --git a/flork/_local.fnl b/flork/_local.fnl
new file mode 100644
index 00000000..55ab4610
--- /dev/null
+++ b/flork/_local.fnl
@@ -0,0 +1,8 @@
+(local {: ok :utils {: expand-env-vars}} (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))
diff --git a/flork/_macos.fnl b/flork/_macos.fnl
new file mode 100644
index 00000000..5eba0e45
--- /dev/null
+++ b/flork/_macos.fnl
@@ -0,0 +1,43 @@
+(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 :list :--display
+ :stack :--sort :datemodified))))
diff --git a/flork/bootstrap.fnl b/flork/bootstrap.fnl
new file mode 100644
index 00000000..df471312
--- /dev/null
+++ b/flork/bootstrap.fnl
@@ -0,0 +1,29 @@
+;; 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))))
diff --git a/personal/main.yml b/personal/main.yml
deleted file mode 100644
index 1ee5e5ec..00000000
--- a/personal/main.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-- hosts: local
- tasks:
- - name: Run brew bundle
- ansible.builtin.command: brew bunfle --file=~/.dotfiles/personal/Brewfile
-
-- hosts: local
- tags: library
- tasks:
-
- - name: Create KeyBindings dir
- ansible.builtin.file:
- path: ~/Library/Application Support/MailMate/Resources/KeyBindings
- state: directory
- mode: "0755"
-
- - name: Symlink key bindings
- ansible.builtin.file:
- src: ~/.dotfiles/macos/MailMate.plist
- dest: ~/Library/Application Support/MailMate/Resources/KeyBindings/Alpha.plist
- state: link
-
-# vim: ft=yaml.ansible