Skip to content

Instantly share code, notes, and snippets.

@chutch3
Last active July 17, 2025 13:18
Show Gist options
  • Save chutch3/e1c2e9bdde360c30a71274376b326aaf to your computer and use it in GitHub Desktop.
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
#!/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