Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,29 @@ This is where I tweak config files till 4am like a goblin. It's pretty cozy in h
- **[wezterm](https://wezterm.org/index.html)**
- **[stow](https://www.gnu.org/software/stow/)**
- **[SwiftBar](https://github.com/swiftbar/SwiftBar)**
- **[Tinycast](https://github.com/abue-ammar/tinycast)**
- **[yazi](https://yazi-rs.github.io/)**

## Setup

```bash
bash scripts/bootstrap.sh
```

Tinycast's native [settings.json](tinycast/.config/tinycast/settings.json) is linked
to `~/.config/tinycast/settings.json` with Stow. On a new Mac, enable
**Settings → Backup → Settings File** and choose **Import**. Tinycast reads file
edits and saves UI preference changes back through the link.

Tinycast 0.11.12 excludes app and launcher shortcuts from its native file, so
[shortcuts.json](tinycast/.config/tinycast/shortcuts.json) stores those separately:
Command+Space for the launcher (key code 49, modifier 256), Option+W for WezTerm
(key code 13), Option+L for Linear (key code 37), and Option+H for Helium
(key code 4). All Option shortcuts use modifier 2048.
This is a dotfiles helper config, read by bootstrap.
Add app entries by bundle ID under `apps`; copy UI shortcut changes here before
rerunning setup. It manages the app shortcut list and preserves other preferences.

Full setup links the files and applies shortcuts, or run `just bootstrap tinycast`
on macOS. The recipe quits Tinycast before writing shortcuts and reopens it if it
was running.
44 changes: 41 additions & 3 deletions scripts/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ link_configs() {
ok "Configs already linked ($*)"
fi
}
bootstrap_stow() { section 'Dotfiles'; link_configs fish gh-dash nvim pi wezterm yazi; }
bootstrap_stow() { section 'Dotfiles'; link_configs fish gh-dash nvim pi tinycast wezterm yazi; }
bootstrap_gh() {
section 'GitHub extensions'
require_tool gh gh
Expand Down Expand Up @@ -216,6 +216,43 @@ bootstrap_insomnia() {
ok 'SwiftBar already running'
fi
}
bootstrap_tinycast() {
section 'Tinycast'
if [[ "$(uname -s)" != Darwin ]]; then warn 'Tinycast skipped: macOS only'; return; fi
local restart=0 shortcuts bundle_id
local app_ids=()
need defaults 'Run this recipe on macOS.'
require_tool jq jq
link_configs tinycast
shortcuts="$ROOT/tinycast/.config/tinycast/shortcuts.json"
jq -e '.launcher | type == "object"' "$shortcuts" >/dev/null
jq -e '.apps | type == "object"' "$shortcuts" >/dev/null
while IFS= read -r bundle_id; do app_ids+=("$bundle_id"); done < <(jq -r '.apps | keys[]' "$shortcuts")
if pgrep -x Tinycast >/dev/null 2>&1; then
run 'Quit Tinycast to apply settings' osascript -e 'tell application "Tinycast" to quit'
restart=1
# Wait for shutdown so a final preference save cannot overwrite the config.
local attempt
for ((attempt = 0; attempt < 50; attempt++)); do
if ! pgrep -x Tinycast >/dev/null 2>&1; then break; fi
sleep 0.1
done
if pgrep -x Tinycast >/dev/null 2>&1; then
fail 'Tinycast is still running. Quit it, then rerun just bootstrap tinycast.'
fi
fi
run 'Apply Tinycast launcher shortcut' defaults write com.tinycast.app hotkey.togglePalette -string "$(jq -c .launcher "$shortcuts")"
# Bash 3.2 treats empty arrays as unset under nounset; expand only populated arrays.
run 'Apply Tinycast app shortcut index' defaults write com.tinycast.app boundAppBundleIDs -array ${app_ids[@]+"${app_ids[@]}"}
for bundle_id in ${app_ids[@]+"${app_ids[@]}"}; do
run "Apply $bundle_id shortcut" defaults write com.tinycast.app "hotkey.app.$bundle_id" -string \
"$(jq -c --arg id "$bundle_id" '.apps[$id]' "$shortcuts")"
done
if [[ "$(defaults read com.tinycast.app settingsFileEnabled 2>/dev/null || true)" != 1 ]]; then
warn 'Enable Settings → Backup → Settings File in Tinycast and choose Import to load the linked settings.json'
fi
if [[ "$restart" == 1 ]]; then run 'Restart Tinycast' open -a Tinycast; fi
}
bootstrap_obscura() {
section 'Obscura'
local version=0.1.8 os arch asset tmp
Expand Down Expand Up @@ -255,10 +292,11 @@ bootstrap_tailscale() {
require_tool just just

case "${1:-all}" in
all) bootstrap_brew; bootstrap_stow; bootstrap_gh; bootstrap_pi; bootstrap_fish; bootstrap_insomnia ;;
all) bootstrap_brew; bootstrap_stow; bootstrap_gh; bootstrap_pi; bootstrap_fish; bootstrap_insomnia; bootstrap_tinycast ;;
brew) bootstrap_brew ;; stow) bootstrap_stow ;; gh) bootstrap_gh ;; pi) bootstrap_pi ;;
fish) bootstrap_fish ;; insomnia) bootstrap_insomnia ;; obscura) bootstrap_obscura ;; tailscale) bootstrap_tailscale ;;
*) fail "Unknown setup target: $1. Use all, brew, stow, gh, pi, fish, insomnia, obscura, or tailscale." ;;
tinycast) bootstrap_tinycast ;;
*) fail "Unknown setup target: $1. Use all, brew, stow, gh, pi, fish, insomnia, tinycast, obscura, or tailscale." ;;
esac
printf '\n'
if [[ "$skipped" -gt 0 ]]; then
Expand Down
6 changes: 4 additions & 2 deletions tests/integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def main():
repo = base / 'repo with spaces'
home = base / 'home'
home.mkdir()
for directory in ('scripts', 'homebrew', 'fish', 'gh-dash', 'nvim', 'pi', 'wezterm', 'yazi', 'swiftbar'):
for directory in ('scripts', 'homebrew', 'fish', 'gh-dash', 'nvim', 'pi', 'wezterm', 'yazi', 'swiftbar', 'tinycast'):
shutil.copytree(ROOT / directory, repo / directory,
ignore=shutil.ignore_patterns('node_modules', '__pycache__'))
shutil.copy2(ROOT / 'justfile', repo / 'justfile')
Expand Down Expand Up @@ -102,7 +102,9 @@ def run(*args, success=True, show_output=True):
'const require = createRequire(process.argv[1]); '
'await import(require.resolve("typebox")); console.log("Pi dependency import passed")',
str(pi / 'package.json'))
for source in (repo / 'fish/.config/fish/config.fish', pi / 'package.json',
for source in (repo / 'fish/.config/fish/config.fish',
repo / 'tinycast/.config/tinycast/settings.json',
repo / 'tinycast/.config/tinycast/shortcuts.json', pi / 'package.json',
pi / 'node_modules/typebox/package.json'):
package = source.relative_to(repo).parts[0]
target = home / source.relative_to(repo / package)
Expand Down
167 changes: 167 additions & 0 deletions tinycast/.config/tinycast/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
{
"general": {
"showInMenuBar": true,
"popToRootSeconds": 0,
"escapeKeyBehavior": "navigateBackOrClose",
"autoSwitchInputSource": null,
"supportReminders": true
},
"appearance": {
"theme": "system",
"interfaceSize": "standard",
"compactMode": false,
"showFavoritesInCompactMode": true,
"followCursorAcrossDisplays": true,
"dragToReposition": false
},
"hyperKey": {
"key": "none",
"includesShift": true,
"quickPress": "none"
},
"calculator": {
"numberStyle": "system"
},
"search": {
"showsSuggestions": true,
"sensitivity": "medium"
},
"applications": {
"searchScopes": [
"/Applications",
"/Applications/Utilities",
"/System/Applications",
"/System/Applications/Utilities",
"/System/Library/CoreServices/Applications",
"/System/Volumes/Preboot/Cryptexes/App/System/Applications",
"/System/Library/CoreServices/Finder.app",
"~/Applications"
]
},
"commands": {
"enabled": false,
"showInLauncher": true
},
"quicklinks": {
"enabled": false,
"showInLauncher": true,
"opensNewWindow": false,
"selectionFallback": "ask",
"confirmsBeforeDelete": true
},
"appleShortcuts": {
"enabled": false
},
"ai": {
"enabled": false,
"webSearch": false,
"systemPrompt": "",
"systemPromptEnabled": true,
"retentionDays": "forever",
"opensTo": "recent",
"newChatAfterMinutes": 5,
"toolRounds": 25
},
"quickActions": {
"targetLanguage": ""
},
"fileSearch": {
"enabled": false,
"scopes": [
"~"
],
"ignorePatterns": []
},
"notes": {
"enabled": false,
"rendersMarkdown": true,
"showsFormattingBar": true,
"folder": null
},
"snippets": {
"showInLauncher": true,
"folder": null
},
"navigation": {
"enabled": false,
"menuSearchShowsAppleMenu": false,
"menuSearchDisabledApps": []
},
"windowManagement": {
"enabled": false,
"showInLauncher": true,
"gap": 0,
"cycle": "off",
"layoutsShowInLauncher": true,
"roomsShowInLauncher": true,
"shortcuts": {
"left-half": null,
"right-half": null,
"top-half": null,
"bottom-half": null,
"top-left-quarter": null,
"top-right-quarter": null,
"bottom-left-quarter": null,
"bottom-right-quarter": null,
"first-three-fourths": null,
"last-three-fourths": null,
"first-third": null,
"center-third": null,
"last-third": null,
"first-two-thirds": null,
"last-two-thirds": null,
"maximize": null,
"almost-maximize": null,
"reasonable-size": null,
"maximize-height": null,
"maximize-width": null,
"center": null,
"center-half": null,
"center-two-thirds": null,
"make-larger": null,
"make-smaller": null,
"restore": null,
"move-left": null,
"move-right": null,
"move-up": null,
"move-down": null,
"next-display": null,
"previous-display": null,
"toggle-fullscreen": null,
"previous-space": null,
"next-space": null
},
"customSizes": [],
"layouts": [],
"rooms": []
},
"clipboard": {
"enabled": true,
"retentionDays": 90,
"defaultAction": "paste",
"disabledApps": [
"com.apple.keychainaccess",
"com.apple.Passwords"
]
},
"emoji": {
"skinTone": "none",
"gridColumns": 8
},
"calendar": {
"showInLauncher": true,
"launcherLimit": 5,
"span": "todayAndTomorrow",
"joinWindowMinutes": 5,
"autoJoinConfirms": true,
"meetingBrowser": null,
"menuBar": "disabled",
"menuBarUpcomingEvents": "today",
"menuBarLinkedEventsOnly": true,
"menuBarHidesWhenEmpty": false,
"hideCurrentEventAfterMinutes": "never"
},
"extensions": {
"showInLauncher": true
}
}
24 changes: 24 additions & 0 deletions tinycast/.config/tinycast/shortcuts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"launcher": {
"combo": {
"_0": { "carbonKeyCode": 49, "carbonModifiers": 256 }
}
},
"apps": {
"com.github.wez.wezterm": {
"combo": {
"_0": { "carbonKeyCode": 13, "carbonModifiers": 2048 }
}
},
"com.linear": {
"combo": {
"_0": { "carbonKeyCode": 37, "carbonModifiers": 2048 }
}
},
"net.imput.helium": {
"combo": {
"_0": { "carbonKeyCode": 4, "carbonModifiers": 2048 }
}
}
}
}
Loading