hammerspoon: hs.configdir resolution change in 0.9.79 breaks module loading for symlinked configs
Thanks @asmagill, @cmsj, @latenitefilms — and to everyone else who contributed to this new release! 🚀
I’ve been keeping my configs in sync between multiple Macs by symlinking init.lua (and other modules) into ~/.hammerspoon from a central config dir (~/Sync/Settings/Hammerpoon) using Resilio Sync.
My config failed to load when upgrading from 0.9.78. In the console, the following errors were logged:
...app/Contents/Resources/extensions/hs/_coresetup/init.lua:651: module 'keybinds' not found:
no field package.preload['keybinds']
no file '/Users/luke/Sync/Settings/Hammerspoon/keybinds.lua'
no file '/Users/luke/Sync/Settings/Hammerspoon/keybinds/init.lua'
no file '/Users/luke/Sync/Settings/Hammerspoon/Spoons/keybinds.spoon/init.lua'
< ...snip... >
stack traceback:
[C]: in function 'rawrequire'
...app/Contents/Resources/extensions/hs/_coresetup/init.lua:651: in function 'require'
(...tail calls...)
[C]: in function 'xpcall'
...app/Contents/Resources/extensions/hs/_coresetup/init.lua:514: in function <...app/Contents/Resources/extensions/hs/_coresetup/init.lua:494>
I eventually figured out that this was due to a change in the way hs.configdir is resolved. Previously, it seems like it would resolve to ~/.hammerspoon but now, if init.lua is itself a symlink, then hs.configdir is set to the parent directory of the absolute path of the real file. This is probably fine for 99.9% of users— but in my case, it broke my configuration.
I have the following symlinks:
~/.hammerspoon/init.lua → ~/Sync/Settings/Hammerspoon/init-XXX-YYY.lua
~/.hammerspoon/keybinds.lua → ~/Sync/Settings/Hammerspoon/keybinds-XXX-YYY.lua
(where XXX=hostname and YYY=machine serial number)
The reason I do this is so I can share chunks of configuration in init.lua between multiple Macs, but have the keybinds/module settings be specific to the machine that’s loading them. I symlink a custom file for each machine but they are all named e.g. “keybinds.lua”.
I “fixed” it by adding a function to my init.lua:
function require_safe(m)
local rs_abspath = hs.fs.pathToAbsolute(os.getenv('HOME') .. '/.hammerspoon/' .. m .. '.lua')
if not rs_abspath then return end
local rs_basename = string.gsub(rs_abspath, "(.*/)(.*)", "%2")
local rs_modname = rs_basename:sub(1, -5)
return require(rs_modname)
end
-- instead of require('keybinds')
require_safe('keybinds')
This has gotten things working again for me. But I’m guessing there’s a cleaner way to handle this…?
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 3
- Comments: 16 (15 by maintainers)
I had the same problem since I use homeshick to manage my dotfiles in a git repo, and all of my dotfiles are symlinks.
If you want Spoons to load, you’ll need those in package.path as well:
Automatically closed when pull merged; reopen if you still have an issue after trying a build off of master branch.