Last active
July 17, 2025 13:18
-
-
Save chutch3/e1c2e9bdde360c30a71274376b326aaf to your computer and use it in GitHub Desktop.
Complete Hammerspoon ShiftIt setup script for macOS - Automates installation and configuration of keyboard-driven window management
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Hammerspoon ShiftIt Setup Script for macOS | |
# This script automates the installation and configuration of Hammerspoon with ShiftIt | |
set -e # Exit on any error | |
echo "๐จ Hammerspoon ShiftIt Setup Script" | |
echo "====================================" | |
echo "" | |
# Function to check if command exists | |
command_exists() { | |
command -v "$1" >/dev/null 2>&1 | |
} | |
# Function to check if Homebrew is installed | |
check_homebrew() { | |
if ! command_exists brew; then | |
echo "โ Homebrew is not installed." | |
echo "๐ฅ Installing Homebrew..." | |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" | |
else | |
echo "โ Homebrew is already installed" | |
fi | |
} | |
# Function to install Hammerspoon | |
install_hammerspoon() { | |
if brew list --cask hammerspoon >/dev/null 2>&1; then | |
echo "โ Hammerspoon is already installed" | |
else | |
echo "๐ฅ Installing Hammerspoon..." | |
brew install --cask hammerspoon | |
echo "โ Hammerspoon installed successfully" | |
fi | |
} | |
# Function to create Hammerspoon directory | |
create_hammerspoon_dir() { | |
HAMMERSPOON_DIR="$HOME/.hammerspoon" | |
SPOONS_DIR="$HAMMERSPOON_DIR/Spoons" | |
if [ ! -d "$HAMMERSPOON_DIR" ]; then | |
echo "๐ Creating Hammerspoon directory..." | |
mkdir -p "$HAMMERSPOON_DIR" | |
fi | |
if [ ! -d "$SPOONS_DIR" ]; then | |
echo "๐ Creating Spoons directory..." | |
mkdir -p "$SPOONS_DIR" | |
fi | |
echo "โ Hammerspoon directories are ready" | |
} | |
# Function to download ShiftIt spoon | |
download_shiftit_spoon() { | |
SPOONS_DIR="$HOME/.hammerspoon/Spoons" | |
SHIFTIT_DIR="$SPOONS_DIR/ShiftIt.spoon" | |
if [ -d "$SHIFTIT_DIR" ]; then | |
echo "โ ShiftIt spoon already exists" | |
read -p "๐ Do you want to update it? (y/N): " -n 1 -r | |
echo | |
if [[ $REPLY =~ ^[Yy]$ ]]; then | |
rm -rf "$SHIFTIT_DIR" | |
else | |
return 0 | |
fi | |
fi | |
echo "๐ฅ Downloading ShiftIt spoon..." | |
# Create temporary directory | |
TEMP_DIR=$(mktemp -d) | |
cd "$TEMP_DIR" | |
# Download the latest release | |
curl -L "https://github.com/peterklijn/hammerspoon-shiftit/raw/master/Spoons/ShiftIt.spoon.zip" -o shiftit.zip | |
# Add after curl command: | |
if [ ! -f "shiftit.zip" ]; then | |
echo "โ Download failed" | |
exit 1 | |
fi | |
# Extract and move to Spoons directory | |
unzip -q shiftit.zip | |
mv "ShiftIt.spoon" "$SHIFTIT_DIR" | |
# Cleanup | |
cd - >/dev/null | |
rm -rf "$TEMP_DIR" | |
echo "โ ShiftIt spoon downloaded successfully" | |
} | |
# Function to create init.lua configuration | |
create_init_lua() { | |
INIT_LUA="$HOME/.hammerspoon/init.lua" | |
if [ -f "$INIT_LUA" ]; then | |
echo "โ ๏ธ init.lua already exists" | |
read -p "๐ Do you want to backup and replace it? (y/N): " -n 1 -r | |
echo | |
if [[ $REPLY =~ ^[Yy]$ ]]; then | |
cp "$INIT_LUA" "$INIT_LUA.backup.$(date +%Y%m%d_%H%M%S)" | |
echo "๐พ Backed up existing init.lua" | |
else | |
echo "โญ๏ธ Skipping init.lua creation" | |
return 0 | |
fi | |
fi | |
echo "๐ Creating init.lua configuration..." | |
cat > "$INIT_LUA" << 'EOF' | |
-- Install hammerspoon (https://formulae.brew.sh/cask/hammerspoon) and setup this script as | |
-- the init.lua to replicate ShiftIt key binding for | |
-- shifting windows in Mac | |
hs.loadSpoon("ShiftIt") | |
spoon.ShiftIt:bindHotkeys({}) | |
-- Optional: Configure window cycling sizes | |
-- spoon.ShiftIt:setWindowCyclingSizes({ 50, 33, 67 }, { 50 }) | |
-- Optional: Custom key mappings (example using Vim keys) | |
-- spoon.ShiftIt:bindHotkeys({ | |
-- left = { { 'ctrl', 'alt', 'cmd' }, 'h' }, | |
-- down = { { 'ctrl', 'alt', 'cmd' }, 'j' }, | |
-- up = { { 'ctrl', 'alt', 'cmd' }, 'k' }, | |
-- right = { { 'ctrl', 'alt', 'cmd' }, 'l' }, | |
-- }) | |
print("ShiftIt configuration loaded!") | |
EOF | |
echo "โ init.lua created successfully" | |
} | |
# Function to show manual steps | |
show_manual_steps() { | |
echo "" | |
echo "๐ง MANUAL STEPS REQUIRED:" | |
echo "========================" | |
echo "" | |
echo "1. ๐ Start Hammerspoon:" | |
echo " - Open Launchpad and click on Hammerspoon" | |
echo " - Or press Cmd+Space and type 'Hammerspoon'" | |
echo "" | |
echo "2. ๐ Grant Accessibility Permissions:" | |
echo " - Go to System Preferences (or System Settings)" | |
echo " - Navigate to Security & Privacy > Privacy > Accessibility" | |
echo " - Click the lock icon and enter your password" | |
echo " - Check the box next to 'Hammerspoon'" | |
echo " - If Hammerspoon is already checked, uncheck and recheck it" | |
echo "" | |
echo "3. ๐ฑ Reload Hammerspoon after granting permissions" | |
echo "" | |
echo "๐ฎ DEFAULT KEY BINDINGS:" | |
echo "========================" | |
echo "โข Snap to sides: Ctrl+Alt+Cmd + Arrow Keys" | |
echo "โข Snap to corners: Ctrl+Alt+Cmd + 1,2,3,4" | |
echo "โข Maximize: Ctrl+Alt+Cmd + M" | |
echo "โข Center: Ctrl+Alt+Cmd + C" | |
echo "โข Resize: Ctrl+Alt+Cmd + =/-" | |
echo "โข Full screen: Ctrl+Alt+Cmd + F" | |
echo "โข Next/Previous screen: Ctrl+Alt+Cmd + N/P" | |
echo "" | |
} | |
# Main execution | |
main() { | |
echo "Starting Hammerspoon ShiftIt setup..." | |
echo "" | |
check_homebrew | |
install_hammerspoon | |
create_hammerspoon_dir | |
download_shiftit_spoon | |
create_init_lua | |
show_manual_steps | |
echo "๐ Setup completed successfully!" | |
echo "" | |
echo "๐ก Pro tip: You can run this script again to update ShiftIt or restore your configuration." | |
} | |
# Run the main function | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment