diff --git a/configs/hammerspoon/Spoons/Annotation/docs.json b/configs/hammerspoon/Spoons/Annotation/docs.json deleted file mode 100644 index 4620bdd..0000000 --- a/configs/hammerspoon/Spoons/Annotation/docs.json +++ /dev/null @@ -1,20 +0,0 @@ -[ - { - "Command": [], - "Constant": [], - "Constructor": [], - "Deprecated": [], - "Field": [], - "Function": [], - "Method": [], - "Variable": [], - "desc": "Thie plugin generates EmmyLua annotations for Hammerspoon and any installed Spoons", - "doc": "Thie plugin generates EmmyLua annotations for Hammerspoon and any installed Spoons\nunder ~/.hammerspoon/Spoons/EmmyLua.spoon/annotations.\nAnnotations will only be generated if they don't exist yet or are out of date.\n\nNote: Load this Spoon before any pathwatchers are defined to avoid unintended behaviour (for example multiple reloads when the annotions are created).\n\nIn order to get auto completion in your editor, you need to have one of the following LSP servers properly configured:\n* [lua-language-server](https://github.com/sumneko/lua-language-server) (recommended)\n* [EmmyLua-LanguageServer](https://github.com/EmmyLua/EmmyLua-LanguageServer)\n\nTo start using this annotations library, add the annotations folder to your workspace.\nfor lua-languag-server:\n\n```json\n{\n \"Lua.workspace.library\": [\"/Users/YOUR_USERNAME/.hammerspoon/Spoons/EmmyLua.spoon/annotations\"]\n}\n```\n\nDownload: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/EmmyLua.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/EmmyLua.spoon.zip)", - "items": [], - "name": "EmmyLua", - "stripped_doc": "under ~/.hammerspoon/Spoons/EmmyLua.spoon/annotations.\nAnnotations will only be generated if they don't exist yet or are out of date.\n\nNote: Load this Spoon before any pathwatchers are defined to avoid unintended behaviour (for example multiple reloads when the annotions are created).\n\nIn order to get auto completion in your editor, you need to have one of the following LSP servers properly configured:\n* [lua-language-server](https://github.com/sumneko/lua-language-server) (recommended)\n* [EmmyLua-LanguageServer](https://github.com/EmmyLua/EmmyLua-LanguageServer)\n\nTo start using this annotations library, add the annotations folder to your workspace.\nfor lua-languag-server:\n\n```json\n{\n \"Lua.workspace.library\": [\"/Users/YOUR_USERNAME/.hammerspoon/Spoons/EmmyLua.spoon/annotations\"]\n}\n```\n\nDownload: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/EmmyLua.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/EmmyLua.spoon.zip)", - "submodules": [], - "type": "Module" - } -] - diff --git a/configs/hammerspoon/Spoons/Annotation/init.lua b/configs/hammerspoon/Spoons/Annotation/init.lua deleted file mode 100644 index 716f8d2..0000000 --- a/configs/hammerspoon/Spoons/Annotation/init.lua +++ /dev/null @@ -1,255 +0,0 @@ ---- === EmmyLua === ---- ---- Thie plugin generates EmmyLua annotations for Hammerspoon and any installed Spoons ---- under ~/.hammerspoon/Spoons/EmmyLua.spoon/annotations. ---- Annotations will only be generated if they don't exist yet or are out of date. ---- ---- Note: Load this Spoon before any pathwatchers are defined to avoid unintended behaviour (for example multiple reloads when the annotions are created). ---- ---- In order to get auto completion in your editor, you need to have one of the following LSP servers properly configured: ---- * [lua-language-server](https://github.com/sumneko/lua-language-server) (recommended) ---- * [EmmyLua-LanguageServer](https://github.com/EmmyLua/EmmyLua-LanguageServer) ---- ---- To start using this annotations library, add the annotations folder to your workspace. ---- for lua-languag-server: ---- ---- ```json ---- { ---- "Lua.workspace.library": ["/Users/YOUR_USERNAME/.hammerspoon/Spoons/EmmyLua.spoon/annotations"] ---- } ---- ``` ---- ---- Download: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/EmmyLua.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/EmmyLua.spoon.zip) - -local M = {} - -M.name = "EmmyLua" -M.version = "1.0" -M.author = "http://github.com/folke" -M.license = "MIT - https://opensource.org/licenses/MIT" -M.logger = hs.logger.new("EmmyLua") - -local options = { - annotations = hs.spoons.resourcePath("annotations"), - timestampsFilename = hs.spoons.resourcePath("annotations") .. "/timestamps.json", - timestamps = {}, - timestampsChanged = false, - types = { - bool = "boolean", - boolean = "boolean", - ["false"] = "boolean", - ["true"] = "boolean", - string = "string", - number = "number", - float = "number", - integer = "number", - app = "hs.application", - hsminwebtable = "hs.httpserver.hsminweb", - notificationobject = "hs.notify", - point = "hs.geometry", - rect = "hs.geometry", - ["hs.geometry rect"] = "hs.geometry", - size = "hs.geometry", - }, -} - -M.spoonPath = hs.spoons.scriptPath() - -function M.comment(str, commentStr) - commentStr = commentStr or "--" - return commentStr .. " " .. str:gsub("[\n]", "\n" .. commentStr .. " "):gsub("%s+\n", "\n") .. "\n" -end - -function M.parseType(module, str) - if not str then - return - end - - str = str:lower() - - if options.types[str] then - return options.types[str] - end - - local type = str:match("^(hs%.%S*)%s*object") - if type then - return type - end - - type = str:match("^list of (hs%.%S*)%s*object") - if type then - return type .. "[]" - end - - if module.name:find(str, 1, true) or str == "self" then - return module.name - end -end - -function M.trim(str) - str = str:gsub("^%s*", "") - str = str:gsub("%s*$", "") - return str -end - -function M.parseArgs(str) - local name, args = str:match("^(.*)%((.*)%)$") - if name then - args = args:gsub("%s*|%s*", "_or_") - args = args:gsub("%s+or%s+", "_or_") - args = args:gsub("[%[%]{}%(%)]", "") - if args:find("...") then - args = args:gsub(",?%s*%.%.%.", "") - args = M.trim(args) - if #args > 0 then - args = args .. ", " - end - args = args .. "..." - end - args = hs.fnutils.split(args, "%s*,%s*") - for a, arg in ipairs(args) do - if arg == "false" then - args[a] = "_false" - elseif arg == "function" then - args[a] = "fn" - elseif arg == "end" then - args[a] = "_end" - end - end - return name, args - end - return str -end - -function M.parseDef(module, el) - el.def = el.def or "" - el.def = module.prefix .. el.def - local parts = hs.fnutils.split(el.def, "%s*%-+>%s*") - local name, args = M.parseArgs(parts[1]) - local ret = { name = name, args = args, type = M.parseType(module, parts[2]) } - if name:match("%[.*%]$") then - if not ret.type then - ret.type = "table" - end - ret.name = ret.name:sub(1, ret.name:find("%[") - 1) - end - return ret -end - -function M.processModule(module) - io.write("--# selene: allow(unused_variable)\n") - io.write("---@diagnostic disable: unused-local\n\n") - - if module.name == "hs" then - io.write("--- global variable containing loaded spoons\n") - io.write("spoon = {}\n\n") - end - - io.write(M.comment(module.doc)) - io.write("---@class " .. module.name .. "\n") - io.write("local M = {}\n") - io.write(module.name .. " = M\n\n") - - for _, item in ipairs(module.items) do - local def = M.parseDef(module, item) - -- io.write("-- " .. item.def) - io.write(M.comment(item.doc)) - local name = def.name - if def.name:find(module.name, 1, true) == 1 then - name = "M" .. def.name:sub(#module.name + 1) - end - if def.args then - if def.type then - io.write("---@return " .. def.type .. "\n") - end - io.write("function " .. name .. "(" .. table.concat(def.args, ", ") .. ") end\n") - else - if def.type then - io.write("---@type " .. def.type .. "\n") - end - if def.type and (def.type:find("table") or def.type:find("%[%]")) then - io.write(name .. " = {}\n") - else - io.write(name .. " = nil\n") - end - end - io.write("\n") - end -end - -function M.create(jsonDocs, prefix) - local mtime = hs.fs.attributes(jsonDocs, "modification") - prefix = prefix or "" - local data = hs.json.read(jsonDocs) - for _, module in ipairs(data) do - if module.type ~= "Module" then - error("Expected a module, but found type=" .. module.type) - end - module.prefix = prefix - module.name = prefix .. module.name - local fname = options.annotations .. "/" .. module.name .. ".lua" - local fmtime = hs.fs.attributes(fname, "modification") - - if fmtime == nil or mtime > fmtime then - M.logger.i("creating " .. fname) - local fd = io.open(fname, "w+") - io.output(fd) - M.processModule(module) - io.close(fd) - else - M.logger.i("skipping " .. fname) - end - end -end - -function M.createWhenChanged(jsonDocs, prefix) - local mtime = hs.fs.attributes(jsonDocs, "modification") - local timestamp = options.timestamps[jsonDocs] - - if timestamp == nil or mtime ~= timestamp then - M.logger.i("reading " .. jsonDocs) - M.create(jsonDocs, prefix) - options.timestamps[jsonDocs] = mtime - options.timestampsChanged = true - else - M.logger.i("skipping " .. jsonDocs) - end -end - -function M.readTimestamps() - timestamps = hs.json.read(options.timestampsFilename) - - if timestamps then - options.timestamps = timestamps - end - - M.logger.d(hs.inspect(options.timestamps)) -end - -function M.writeTimestamps() - M.logger.d(hs.inspect(options.timestamps)) - if options.timestampsChanged then - hs.json.write(options.timestamps, options.timestampsFilename, true, true) - end -end - -function M:init() - hs.fs.mkdir(options.annotations) - - M.readTimestamps() - - -- Load hammerspoon docs - M.createWhenChanged(hs.docstrings_json_file) - - -- Load Spoons - for _, spoon in ipairs(hs.spoons.list()) do - local doc = hs.configdir .. "/Spoons/" .. spoon.name .. ".spoon/docs.json" - if hs.fs.attributes(doc, "modification") then - M.createWhenChanged(doc, "spoon.") - end - end - - M.writeTimestamps() -end - -return M diff --git a/configs/hammerspoon/Spoons/hotkey-window.lua b/configs/hammerspoon/Spoons/hotkey-window.lua index 855d257..cb93b1e 100644 --- a/configs/hammerspoon/Spoons/hotkey-window.lua +++ b/configs/hammerspoon/Spoons/hotkey-window.lua @@ -11,18 +11,14 @@ local function create_hot_key_window(app_name, command_key, key) else local win = app:mainWindow() - local activeSpaces = spaces.activeSpaces() - spaces.moveWindowToSpace(win:id(), spaces.activeSpaceOnScreen()) win:focus() end end) end --- create_hot_key_window("net.ankiweb.dtop", { "cmd", "shift" }, "m") create_hot_key_window("md.obsidian", { "cmd", "shift" }, "z") create_hot_key_window("net.kovidgoyal.kitty", { "cmd", "shift" }, "s") create_hot_key_window("com.hnc.Discord", { "cmd", "shift" }, "d") --- create_hot_key_window("com.mitchellh.ghostty", { "cmd", "shift" }, "g") create_hot_key_window("com.google.Chrome", { "cmd", "shift" }, "a") create_hot_key_window("abnerworks.Typora", { "cmd", "shift" }, "m") diff --git a/configs/hammerspoon/Spoons/tiling.lua b/configs/hammerspoon/Spoons/tiling.lua index 6c4f982..cb0ab5a 100644 --- a/configs/hammerspoon/Spoons/tiling.lua +++ b/configs/hammerspoon/Spoons/tiling.lua @@ -12,10 +12,13 @@ local windowChooser = function(active_win_id, callback) end) -- format for chooser win_list = hs.fnutils.map(win_list, function(win) + local app = win:application() + local app_name = app and app:name() or "" + local bundle_id = app and app:bundleID() or "" return { - text = win:title() .. " - " .. win:application():name() .. " - " .. win:application():bundleID(), - subText = win:application():name(), - image = hs.image.imageFromAppBundle(win:application():bundleID()), + text = (win:title() or "") .. " - " .. app_name .. " - " .. bundle_id, + subText = app_name, + image = bundle_id ~= "" and hs.image.imageFromAppBundle(bundle_id) or nil, value = win:id(), } end) @@ -45,6 +48,10 @@ hs.hotkey.bind({ "cmd", "shift" }, "h", function() active_win:setFrame(active_frame) windowChooser(active_win:id(), function(choice) + if choice == nil then + return + end + local other_frame = {} other_frame.x = active_frame.x + active_frame.w other_frame.y = active_frame.y @@ -97,6 +104,10 @@ hs.hotkey.bind({ "cmd", "shift" }, "l", function() active_win:setFrame(active_frame) windowChooser(active_win:id(), function(choice) + if choice == nil then + return + end + local other_frame = {} other_frame.x = active_frame.x - active_frame.w other_frame.y = active_frame.y @@ -116,7 +127,16 @@ end) -- find & focus hs.hotkey.bind({ "cmd", "shift" }, "f", function() local activeWindow = hs.window.focusedWindow() - windowChooser(activeWindow:id(), function(choice) - hs.window(choice.value):focus() + local active_win_id = activeWindow and activeWindow:id() + windowChooser(active_win_id, function(choice) + if choice == nil then + return + end + + local win = hs.window(choice.value) + if win == nil then + return + end + win:focus() end) end) diff --git a/configs/hammerspoon/init.lua b/configs/hammerspoon/init.lua index 4a5905c..45af64c 100644 --- a/configs/hammerspoon/init.lua +++ b/configs/hammerspoon/init.lua @@ -2,7 +2,6 @@ require("hs.ipc") -- reload config hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "R", function() - require("Spoons.Annotation").init() hs.reload() end) diff --git a/configs/hammerspoon/sketchybar/init.lua b/configs/hammerspoon/sketchybar/init.lua index 8f1b4f0..f8e2e46 100644 --- a/configs/hammerspoon/sketchybar/init.lua +++ b/configs/hammerspoon/sketchybar/init.lua @@ -1,7 +1,4 @@ local manager = require("sketchybar.manager") manager.add_widget(require("sketchybar.widgets.active-app"), { only_init = true }) --- manager.add_widget(require("sketchybar.widgets.battery"), { time = 120 }) --- manager.add_widget(require("sketchybar.widgets.memory"), { time = 120 }) --- manager.add_widget(require("sketchybar.widgets.storage"), { time = 120 }) manager.add_widget(require("sketchybar.widgets.wifi"), { only_init = true }) diff --git a/configs/hammerspoon/sketchybar/manager/init.lua b/configs/hammerspoon/sketchybar/manager/init.lua index 35407b3..5a623a0 100644 --- a/configs/hammerspoon/sketchybar/manager/init.lua +++ b/configs/hammerspoon/sketchybar/manager/init.lua @@ -29,7 +29,7 @@ M.add_widget = function(widget, opts) end M.remove_widget = function(widget_id) - if not _widgets[widget_id].timer then + if _widgets[widget_id].timer then _widgets[widget_id].timer:stop() end _widgets[widget_id] = nil diff --git a/configs/hammerspoon/sketchybar/widgets/active-app.lua b/configs/hammerspoon/sketchybar/widgets/active-app.lua index 98eea0a..fb423e2 100644 --- a/configs/hammerspoon/sketchybar/widgets/active-app.lua +++ b/configs/hammerspoon/sketchybar/widgets/active-app.lua @@ -7,11 +7,13 @@ local function update(window, appName, watcher) -- update app_icon item if watcher == "windowFocused" then - hs.execute( - "sketchybar --set app_icon background.drawing=on background.image=app." - .. activeWindow:application():bundleID(), - true - ) + local app = window and window:application() + local bundle_id = app and app:bundleID() + if bundle_id == nil then + return + end + + hs.execute("sketchybar --set app_icon background.drawing=on background.image=app." .. bundle_id, true) elseif watcher == "windowUnfocused" then if activeWindow == nil then hs.execute("sketchybar --set app_icon background.drawing=off", true) @@ -28,9 +30,4 @@ M.init = function() }) end -M.update = function() - -- DO NOT WRITE CODE - -- update by hammerspoon builtin watcher -end - return M diff --git a/configs/hammerspoon/sketchybar/widgets/battery.lua b/configs/hammerspoon/sketchybar/widgets/battery.lua deleted file mode 100644 index cfca186..0000000 --- a/configs/hammerspoon/sketchybar/widgets/battery.lua +++ /dev/null @@ -1,62 +0,0 @@ -local icon = { - [100] = "󱈏", - [90] = "󰂂", - [80] = "󰂁", - [70] = "󰂀", - [60] = "󰁿", - [50] = "󰁾", - [40] = "󰁽", - [30] = "󰁼", - [20] = "󰁻", - [10] = "󰁺", - [0] = "󰂃", - charging = "󰂄", -} - --- return number --- ex) 0, 40, 80, 100 -local function get_percentage() - local battery = hs.battery.getAll() - local percentage = math.floor(battery.percentage) - - return percentage -end - --- return boolean string --- ex) true, false -local function get_is_charging() - local battery = hs.battery.getAll() - local isCharging = battery.powerSource == "AC Power" - - return isCharging -end - -local update = function() - local percentage = get_percentage() - local isCharging = get_is_charging() - - if isCharging then - hs.execute("sketchybar --set battery label='" .. percentage .. "%' icon='" .. icon["charging"] .. "'", true) - return - end - - for i = 100, 0, -10 do - if percentage >= i then - hs.execute("sketchybar --set battery label='" .. percentage .. "%' icon='" .. icon[i] .. "'", true) - return - end - end - - hs.execute("sketchybar --set battery label='" .. percentage .. "%' icon='" .. icon[0] .. "'", true) -end - -battery_watcher = hs.battery.watcher.new(update) -local M = {} - -M.init = function() - -- start Watcher - battery_watcher:start() -end - -M.update = update -return M diff --git a/configs/hammerspoon/sketchybar/widgets/memory.lua b/configs/hammerspoon/sketchybar/widgets/memory.lua deleted file mode 100644 index 0aff2c3..0000000 --- a/configs/hammerspoon/sketchybar/widgets/memory.lua +++ /dev/null @@ -1,54 +0,0 @@ -local function get_vmstat_in_gb() - local vmStats = hs.host.vmStat() - local pageSize = vmStats["pageSize"] - - for partition, size in pairs(vmStats) do - if partition ~= "pageSize" then - print(math.floor((size * pageSize) / 1023 / 1024 / 1024 * 100) / 100) - end - end -end - -local function get_available_memory_in_gb() - -- local GB = 1024 * 1024 * 1024 - local vmStats = hs.host.vmStat() - - -- local totalMemory = vmStats["memSize"] / GB - - -- File Cache: -> File-backed pages - -- Wired Memory: -> Pages wired down - -- Compressed: -> Pages occupied by compressor - -- App Memory: -> Pages Active + Pages Speculative - - -- local pageSize = vmStats["pageSize"] / GB - -- - -- -- Calculate total memory used by adding up relevant page counts - -- local appMemory = vmStats["pagesActive"] + vmStats["pagesSpeculative"] + vmStats["pagesUsedByVMCompressor"] - -- local wiredMemory = vmStats["pagesWiredDown"] - -- - -- local totalPagesUsed = appMemory + wiredMemory - -- local totalMemoryUsage = totalPagesUsed * pageSize - - -- local available = (totalMemory - totalMemoryUsage) / 1024 / 1024 / 1024 - -- local available = totalMemory - totalMemoryUsage - - -- https://www.reddit.com/r/MacOS/comments/1dg8vgb/tracking_historical_ram_usage_on_a_mac/ - local pageSizeKB = 16 - local freeMemoryKB = (vmStats["pagesFree"] + vmStats["pagesInactive"] + vmStats["pagesSpeculative"]) * pageSizeKB - - local availableGB = freeMemoryKB / 1024 / 1024 - - return math.floor(availableGB * 10) / 10 -end - -local M = {} - -M.init = function() end - -M.update = function() - local avaialbeMemory = get_available_memory_in_gb() - - hs.execute("sketchybar --set memory label='" .. avaialbeMemory .. "GB'", true) -end - -return M diff --git a/configs/hammerspoon/sketchybar/widgets/storage.lua b/configs/hammerspoon/sketchybar/widgets/storage.lua deleted file mode 100644 index 04a9874..0000000 --- a/configs/hammerspoon/sketchybar/widgets/storage.lua +++ /dev/null @@ -1,24 +0,0 @@ -function get_available_storage() - local volumeInformation = hs.host.volumeInformation() - local availableSpace = volumeInformation["/"].NSURLVolumeAvailableCapacityKey / 1024 / 1024 / 1024 - availableSpace = math.floor(availableSpace * 10) / 10 - - return availableSpace -end - -local M = {} - -M.init = function() end - -M.update = function() - local availableSpace = get_available_storage() - - if availableSpace >= 100 then - hs.execute("sketchybar --set storage label='≥100GB'", true) - return - end - - hs.execute("sketchybar --set storage label='" .. availableSpace .. "GB'", true) -end - -return M diff --git a/configs/hammerspoon/sketchybar/widgets/wifi.lua b/configs/hammerspoon/sketchybar/widgets/wifi.lua index 98cc69a..d2e7465 100644 --- a/configs/hammerspoon/sketchybar/widgets/wifi.lua +++ b/configs/hammerspoon/sketchybar/widgets/wifi.lua @@ -1,7 +1,6 @@ local icon = { on = "󰖩", off = "󰖪", - nosignal = "󱚵", } local function update(watcher, message) @@ -19,7 +18,6 @@ local function update(watcher, message) end WifiWatcher = hs.wifi.watcher.new(update) --- Watcher:watchingFor({ "SSIDChange", "BSSIDChange", "linkChange", "powerChange", "modeChange" }) local M = {} @@ -27,9 +25,4 @@ M.init = function() WifiWatcher:start() end -M.update = function() - -- DO NOT WRITE CODE - -- update by hammerspoon builtin watcher -end - return M diff --git a/configs/hammerspoon/utils/init.lua b/configs/hammerspoon/utils/init.lua deleted file mode 100644 index aabd2ea..0000000 --- a/configs/hammerspoon/utils/init.lua +++ /dev/null @@ -1,14 +0,0 @@ -function dump(o) - if type(o) == "table" then - local s = "{ " - for k, v in pairs(o) do - if type(k) ~= "number" then - k = '"' .. k .. '"' - end - s = s .. "[" .. k .. "] = " .. dump(v) .. "," - end - return s .. "} " - else - return tostring(o) - end -end