如何正确创建 Hammerspoon 的扩展脚本?

我编写了一个控制音量的扩展脚本,但 hotkeys.bind 方法无效,这是什么问题?

以下为扩展脚本 init.lua 的代码:

-- === 音量 ===

local obj={}
obj.__index = obj

-- 元数据
obj.name = "音量"
obj.version = "1.0"
obj.license = "MIT - https://opensource.org/licenses/MIT"

obj.logger = hs.logger.new('音量')

function obj:init()
end

function obj:changeVolume(diff)
   return function()
     local current = hs.audiodevice.defaultOutputDevice():volume()
     local new = math.min(100, math.max(0, math.floor(current + diff)))
     if new > 0 then
       hs.audiodevice.defaultOutputDevice():setMuted(false)
     end
     hs.alert.closeAll(0.0)
     hs.alert.show("音量 " .. new .. "%", {}, 0.5)
     hs.audiodevice.defaultOutputDevice():setVolume(new)
   end
 end

return obj

我在 ~/.hammerspoon/init.lua 中加载并使用了该扩展脚本:

hs.loadSpoon("音量")
hs.hotkey.bind({'cmd', 'alt'}, '[', function() spoon.Volume:changeVolume(-3) end)
hs.hotkey.bind({'cmd', 'alt'}, ']', function() spoon.Volume:changeVolume(3) end)
点赞
用户1252056
用户1252056

当调用changeVolume方法时,它会返回一个函数,但并不执行它。让它生效的唯一方法是将顶部和底部的第二行删除,这样当函数被调用时,它将被执行:

function obj:changeVolume(diff)
    local current = hs.audiodevice.defaultOutputDevice():volume()
    local new = math.min(100, math.max(0, math.floor(current + diff)))
    if new > 0 then
        hs.audiodevice.defaultOutputDevice():setMuted(false)
    end
    hs.alert.closeAll(0.0)
    hs.alert.show("Volume " .. new .. "%", {}, 0.5)
    hs.audiodevice.defaultOutputDevice():setVolume(new)
end

请注意,建议的方法是公开一个:bindHotKeys()方法。我建议将changeVolume函数定义为局部的(local function changeVolume),然后公开inc()dec()方法:

local function changeVolume(diff)
...
end

function obj:inc()
    changeVolume(3)
end

function obj:dec()
    changeVolume(-3)
end

function obj:bindHotkeys(mapping)
    local spec = {
        inc = hs.fnutils.partial(self.inc, self),
        dec = hs.fnutils.partial(self.dec, self),
    }
    hs.spoons.bindHotkeysToSpec(spec, mapping)
    return self
end
2021-05-06 00:53:10