Hammerspoon + macOS Fix for perfectly consistent keyboard layout switching.
This setup combines:
- Hammerspoon — dynamically switches keyboard layout when specific apps become active
- macOS system override — disables Apple's per-app keyboard memory to avoid conflicts
- A small Bash utility — applies the required macOS preference fix
This eliminates layout flickering, unexpected switches, and the fight between macOS and Hammerspoon.
- Automatically switches to U.S. English when opening coding/terminal apps
- Automatically switches to Icelandic when opening communication apps
- Configurable lists for both languages
- On-screen alerts showing the active layout
- Reload config hotkey:
Cmd + Alt + Ctrl + R - macOS keyboard memory disabled to prevent interference
Download from: https://www.hammerspoon.org
Then allow permissions under:
System Settings → Privacy & Security → Accessibility / Automation
Place the following file at ~/.hammerspoon/init.lua:
-- ⌨️ Automatic Keyboard Switching for Applications
-- CONFIGURATION
local englishApps = {
"Ghostty",
"Code",
"Terminal",
"iTerm2",
"Visual Studio Code",
}
local icelandicApps = {
"Slack",
"Mail",
"Messages",
"Discord",
}
-- Helper function
local function isInArray(array, value)
local lowerValue = string.lower(value)
for _, item in ipairs(array) do
if string.lower(item) == lowerValue then
return true
end
end
return false
end
-- Stop existing watcher if reloading
if appWatcher then
appWatcher:stop()
appWatcher = nil
end
-- Create watcher (GLOBAL to prevent garbage collection)
appWatcher = hs.application.watcher.new(function(appName, eventType, appObject)
if eventType == hs.application.watcher.activated and appName then
if isInArray(englishApps, appName) then
hs.keycodes.setLayout("U.S.")
hs.alert.show("🇺🇸 English", 0.5)
elseif isInArray(icelandicApps, appName) then
hs.keycodes.setLayout("Icelandic")
hs.alert.show("🇮🇸 Íslenska", 0.5)
end
end
end)
appWatcher:start()
-- Reload config: Cmd+Alt+Ctrl+R
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "R", function()
hs.reload()
end)
hs.alert.show(string.format("⌨️ Auto-Keyboard: %d EN, %d IS apps", #englishApps, #icelandicApps), 1.5)macOS tries to remember the keyboard layout per application, which conflicts with Hammerspoon trying to enforce a layout.
Disable it with the following script:
#!/bin/bash
###############################################
# Disable macOS's built-in per-app keyboard #
# memory. Without it, you'd have two systems #
# fighting each other: #
# 1. macOS trying to restore the last #
# keyboard layout you used in each app #
# 2. Hammerspoon trying to set the layout #
# based on your config #
# #
# This conflict can cause flickering or #
# unexpected behavior. #
###############################################
defaults write ~/Library/Preferences/com.apple.HIToolbox.plist AppleGlobalTextInputProperties -dict TextInputGlobalPropertyPerContextInput -int 0
killall cfprefsdRun it:
chmod +x disable-macos-keyboard-memory.sh
./disable-macos-keyboard-memory.shThis takes effect instantly.
Modify the app arrays in init.lua:
local englishApps = { ... }
local icelandicApps = { ... }Use the exact application name as macOS reports it (case-insensitive).
Update the layout names:
hs.keycodes.setLayout("U.S.")
hs.keycodes.setLayout("Icelandic")List available layouts in the Hammerspoon console:
hs.keycodes.layouts()- Reload config:
Cmd + Alt + Ctrl + R - Switch between apps listed in the config
- You should see:
- An alert (
🇺🇸 Englishor🇮🇸 Íslenska) - The keyboard input menu switching instantly
- An alert (
If layouts flicker, re-run the macOS memory script.
You now have:
- Automatic layout switching based on app focus
- No macOS interference
- Clean and fast UX for Icelandic + English workflows