Last active
May 24, 2022 14:42
-
-
Save pallove/125fd35a524064fbf95752455a739110 to your computer and use it in GitHub Desktop.
improve the spoon(HoldToQuit) of hammerspoon, the behaviour like Google Chrome`s
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
--- === HoldToQuit === | |
--- | |
--- Instead of pressing ⌘Q, hold ⌘Q to close applications. | |
local obj = {} | |
obj.__index = obj | |
-- Metadata | |
obj.name = "HoldToQuit" | |
obj.version = "1.1" | |
obj.author = "Matthias Strauss <[email protected]>" | |
obj.github = "@MattFromGer" | |
obj.homepage = "https://github.com/Hammerspoon/Spoons" | |
obj.license = "MIT - https://opensource.org/licenses/MIT" | |
obj.revisor = "DustinLL" | |
--- HoldToQuit.duration | |
--- Variable | |
--- Integer containing the duration (in seconds) how long to hold | |
--- the hotkey. Default 1. | |
obj.duration = 0.8 | |
--- HoldToQuit.defaultHotkey | |
--- Variable | |
--- Default hotkey mapping | |
obj.defaultHotkey = { | |
quit = { {"cmd"}, "Q" } | |
} | |
--- HoldToQuit.hotkeyQbj | |
--- Variable | |
--- Hotkey object | |
obj.hotkeyQbj = nil | |
--- HoldToQuit.timer | |
--- Variable | |
--- Timer for counting the holding time | |
obj.timer = nil | |
-- HoldToQuit.ignoreApp | |
obj.ignoreApp = { | |
{name = 'Finder', keep = true}, --- keep, avoid bell | |
{name = 'Google Chrome'}, --- use owner setting | |
{name = 'Hammerspoon', keep = true}, --- make it safe | |
} | |
local delayTimer | |
local timeStamp | |
local function gettime() | |
return math.floor(hs.timer.absoluteTime() / 1000000) | |
end | |
local function hasIgnore(app) | |
for _, obj in ipairs(obj.ignoreApp) do | |
if obj.name then | |
if string.find(app:path(), '/' .. obj.name) then | |
return true, obj | |
end | |
elseif obj.id then | |
if string.find(app:bundleID(), obj.id) then | |
return true, obj | |
end | |
end | |
end | |
return false, obj | |
end | |
--- HoldToQuit.killCurrentApp | |
--- Method | |
--- Kill the frontmost application | |
function obj:killCurrentApp() | |
hs.alert.closeAll(0) | |
delayTimer:stop() | |
local app = hs.application.frontmostApplication() | |
app:kill() | |
end | |
--- HoldToQuit:init() | |
--- Method | |
--- Initialize spoon | |
function obj:init() | |
delayTimer = hs.timer.delayed.new(0.5, function() | |
self.timer:stop() | |
end) | |
self.timer = hs.timer.delayed.new(self.duration, self.killCurrentApp) | |
end | |
--- HoldToQuit:onKeyDown() | |
--- Method | |
--- Start timer on keyDown | |
function obj:onKeyDown() | |
if self.timer:running() then | |
if delayTimer:running() then | |
self.timer:stop() | |
self:killCurrentApp() | |
end | |
else | |
hs.alert.closeAll(0) | |
local app = hs.application.frontmostApplication() | |
local flag, obj = hasIgnore(app) | |
if flag then | |
if obj.keep then return end | |
local hotkey = self.defaultHotkey.quit | |
hs.eventtap.event.newKeyEvent(hotkey[1], hotkey[2], true):post(app) | |
return | |
end | |
hs.alert.show(string.format("Hold %s to Quit [%s]", self.hotkeyQbj.idx, app:name())) | |
timeStamp = gettime() | |
self.timer:start() | |
end | |
end | |
--- HoldToQuit:onKeyUp() | |
--- Method | |
--- Stop Timer & show alert message | |
function obj:onKeyUp() | |
if self.timer:running() then | |
local endTime = gettime() | |
if (endTime - timeStamp < 200) then | |
delayTimer:start() | |
else | |
self.timer:stop() | |
end | |
else | |
local app = hs.application.frontmostApplication() | |
local flag, obj = hasIgnore(app) | |
if flag then | |
if obj.keep then return end | |
local hotkey = self.defaultHotkey.quit | |
hs.eventtap.event.newKeyEvent(hotkey[1], hotkey[2], false):post(app) | |
end | |
end | |
end | |
--- HoldToQuit:start() | |
--- Method | |
--- Start HoldToQuit with default hotkey | |
function obj:start() | |
if (self.hotkeyQbj) then | |
self.hotkeyQbj:enable() | |
else | |
local mod = self.defaultHotkey["quit"][1] | |
local key = self.defaultHotkey["quit"][2] | |
self.hotkeyQbj = hs.hotkey.bind(mod, key, function() obj:onKeyDown() end, function() obj:onKeyUp() end) | |
end | |
end | |
--- HoldToQuit:stop() | |
--- Method | |
--- Disable HoldToQuit hotkey | |
function obj:stop() | |
if (self.hotkeyQbj) then | |
self.hotkeyQbj:disable() | |
end | |
end | |
--- HoldToQuit:bindHotkeys(mapping) | |
--- Method | |
--- Binds hotkeys for HoldToQuit | |
--- | |
--- Parameters: | |
--- * mapping - A table containing hotkey modifier/key details for the following items: | |
--- * show - This will define the quit hotkey | |
function obj:bindHotkeys(mapping) | |
if (self.hotkeyQbj) then | |
self.hotkeyQbj:delete() | |
end | |
local mod = mapping["quit"][1] | |
local key = mapping["quit"][2] | |
self.hotkeyQbj = hs.hotkey.bind(mod, key, function() obj:onKeyDown() end, function() obj:onKeyUp() end) | |
return self | |
end | |
return obj |
Hello, i'm starting with Hammerspoon, do you have by any chance a snippet on how to use your spoon?
Thanks in advance :)
hi, sorry late for you, just follow the steps:
- enter your directory '~/.hammerspoon/Spoons/HoldToQuit.spoon'
- copy my snippet (HoldToQuit.spoon.lua)
- replace all content of your 'init.lua' file with clipboard
- now enter your directory '~/.hammerspoon'
- open 'init.lua'(if not exist, empty one.), append the content:
local obj = hs.loadSpoon("HoldToQuit")
obj:init()
obj:start()
- do 'reload config' on your Hammerspoon
Hi,
Thanks a lot for the help and for the great spoon ! Now it works as expected ! :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello, i'm starting with Hammerspoon, do you have by any chance a snippet on how to use your spoon?
Thanks in advance :)