二改模版笔记
自动重新加载HS
function reloadConfig(files) doReload = false for _,file in pairs(files) do if file:sub(-4) == ".lua" then doReload = true end end if doReload then hs.reload() end end myWatcher = hs.pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon/", reloadConfig):start() hs.alert.show("Config loaded")
调节音量
function 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("Volume " .. new .. "%", {}, 0.5) hs.audiodevice.defaultOutputDevice():setVolume(new) end end hs.hotkey.bind({"shift","ctrl",'command'}, 'Down', changeVolume(-3)) hs.hotkey.bind({"shift","ctrl",'command'}, 'Up', changeVolume(3))
显示七日天气
local urlApi = 'http://v1.yiketianqi.com/free/api' local menubar = hs.menubar.new() local menuData = {} local weaEmoji = { lei = '🌩️', qing = '☀️', shachen = '😷', wu = '🌫', xue = '❄️', yu = '🌧', yujiaxue = '🌨', yun = '☁️', zhenyu = '🌧', yin = '⛅️', default = '' } function updateMenubar() menubar:setTooltip("Weather Info") menubar:setMenu(menuData) end function getWeather() hs.http.doAsyncRequest(urlApi, "GET", nil,nil, function(code, body, htable) if code ~= 200 then print('get weather error:'..code) return end rawjson = hs.json.decode(body) city = rawjson.city menuData = {} for k, v in pairs(rawjson.data) do if k == 1 then menubar:setTitle(weaEmoji[v.wea_img]) if v.win_speed == "<3级" then titlestr = string.format("%s %s %s 🌡️%s-%s°C", city,weaEmoji[v.wea_img], v.wea, v.tem_night, v.tem_day) else titlestr = string.format("%s %s 🌡️%s-%s°C 💨%s %s %s", city,weaEmoji[v.wea_img],v.tem_night, v.tem_day, v.win_speed, v.win, v.wea) end item = { title = titlestr } table.insert(menuData, item) table.insert(menuData, {title = '-'}) else if v.win_speed == "<3级" then titlestr = string.format("%s %s 🌡️%s-%s°C %s", v.date, weaEmoji[v.wea_img], v.tem_night, v.tem_day, v.wea) else titlestr = string.format("%s %s 🌡️%s-%s°C 💨%s %s %s", v.date, weaEmoji[v.wea_img],v.tem_night, v.tem_day, v.win_speed, v.win, v.wea) end item = { title = titlestr } table.insert(menuData, item) end end updateMenubar() end) end menubar:setTitle('👀') getWeather() updateMenubar() hs.timer.doEvery(3000, getWeather)
剪贴板
其中设置这个为true的话,可以直接插入
local pasteOnSelect = false -- Auto-type on click
--[[ From https://github.com/victorso/.hammerspoon/blob/master/tools/clipboard.lua Modified by Diego Zamboni ]]-- -- Feel free to change those settings local frequency = 0.8 -- Speed in seconds to check for clipboard changes. If you check too frequently, you will loose performance, if you check sparsely you will loose copies local hist_size = 100 -- How many items to keep on history local label_length = 70 -- How wide (in characters) the dropdown menu should be. Copies larger than this will have their label truncated and end with "…" (unicode for elipsis ...) local honor_clearcontent = false --asmagill request. If any application clears the pasteboard, we also remove it from the history https://groups.google.com/d/msg/hammerspoon/skEeypZHOmM/Tg8QnEj_N68J local pasteOnSelect = false -- Auto-type on click -- Don't change anything bellow this line local jumpcut = hs.menubar.new() jumpcut:setTooltip("Clipboard history") local pasteboard = require("hs.pasteboard") -- http://www.hammerspoon.org/docs/hs.pasteboard.html local settings = require("hs.settings") -- http://www.hammerspoon.org/docs/hs.settings.html local last_change = pasteboard.changeCount() -- displays how many times the pasteboard owner has changed // Indicates a new copy has been made --Array to store the clipboard history local clipboard_history = settings.get("so.victor.hs.jumpcut") or {} --If no history is saved on the system, create an empty history function subStringUTF8(str, startIndex, endIndex) if startIndex < 0 then startIndex = subStringGetTotalIndex(str) + startIndex + 1 end if endIndex ~= nil and endIndex < 0 then endIndex = subStringGetTotalIndex(str) + endIndex + 1 end if endIndex == nil then return string.sub(str, subStringGetTrueIndex(str, startIndex)) else return string.sub(str, subStringGetTrueIndex(str, startIndex), subStringGetTrueIndex(str, endIndex + 1) - 1) end end --返回当前截取字符串正确下标 function subStringGetTrueIndex(str, index) local curIndex = 0 local i = 1 local lastCount = 1 repeat lastCount = subStringGetByteCount(str, i) i = i + lastCount curIndex = curIndex + 1 until(curIndex >= index) return i - lastCount end --返回当前字符实际占用的字符数 function subStringGetByteCount(str, index) local curByte = string.byte(str, index) local byteCount = 1 if curByte == nil then byteCount = 0 elseif curByte > 0 and curByte <= 127 then byteCount = 1 elseif curByte>=192 and curByte<=223 then byteCount = 2 elseif curByte>=224 and curByte<=239 then byteCount = 3 elseif curByte>=240 and curByte<=247 then byteCount = 4 end return byteCount end -- Append a history counter to the menu function setTitle() if (#clipboard_history == 0) then jumpcut:setTitle("✂") -- Unicode magic else jumpcut:setTitle("✂") -- Unicode magic -- jumpcut:setTitle("✂ ("..#clipboard_history..")") -- updates the menu counter end end function putOnPaste(string,key) if (pasteOnSelect) then hs.eventtap.keyStrokes(string) pasteboard.setContents(string) last_change = pasteboard.changeCount() else if (key.alt == true) then -- If the option/alt key is active when clicking on the menu, perform a "direct paste", without changing the clipboard hs.eventtap.keyStrokes(string) -- Defeating paste blocking http://www.hammerspoon.org/go/#pasteblock else pasteboard.setContents(string) last_change = pasteboard.changeCount() -- Updates last_change to prevent item duplication when putting on paste end end end -- Clears the clipboard and history function clearAll() pasteboard.clearContents() clipboard_history = {} settings.set("so.victor.hs.jumpcut",clipboard_history) now = pasteboard.changeCount() setTitle() end -- Clears the last added to the history function clearLastItem() table.remove(clipboard_history,#clipboard_history) settings.set("so.victor.hs.jumpcut",clipboard_history) now = pasteboard.changeCount() setTitle() end function pasteboardToClipboard(item) -- Loop to enforce limit on qty of elements in history. Removes the oldest items while (#clipboard_history >= hist_size) do table.remove(clipboard_history,1) end table.insert(clipboard_history, item) settings.set("so.victor.hs.jumpcut",clipboard_history) -- updates the saved history setTitle() -- updates the menu counter end -- Dynamic menu by cmsj https://github.com/Hammerspoon/hammerspoon/issues/61#issuecomment-64826257 populateMenu = function(key) setTitle() -- Update the counter every time the menu is refreshed menuData = {} if (#clipboard_history == 0) then table.insert(menuData, {title="None", disabled = true}) -- If the history is empty, display "None" else for k,v in pairs(clipboard_history) do if (string.len(v) > label_length) then table.insert(menuData,1, {title=subStringUTF8(v,0,label_length).."…", fn = function() putOnPaste(v,key) end }) -- Truncate long strings else table.insert(menuData,1, {title=v, fn = function() putOnPaste(v,key) end }) end -- end if else end-- end for end-- end if else -- footer table.insert(menuData, {title="-"}) table.insert(menuData, {title="Clear All", fn = function() clearAll() end }) if (key.alt == true or pasteOnSelect) then table.insert(menuData, {title="Direct Paste Mode ✍", disabled=true}) end return menuData end -- If the pasteboard owner has changed, we add the current item to our history and update the counter. function storeCopy() now = pasteboard.changeCount() if (now > last_change) then current_clipboard = pasteboard.getContents() -- asmagill requested this feature. It prevents the history from keeping items removed by password managers if (current_clipboard == nil and honor_clearcontent) then clearLastItem() else pasteboardToClipboard(current_clipboard) end last_change = now end end --Checks for changes on the pasteboard. Is it possible to replace with eventtap? timer = hs.timer.new(frequency, storeCopy) timer:start() setTitle() --Avoid wrong title if the user already has something on his saved history jumpcut:setMenu(populateMenu) hs.hotkey.bind({"cmd", "shift"}, "v", function() jumpcut:popupMenu(hs.mouse.getAbsolutePosition()) end)
系统信息显示
--- 显示系统信息 --- 可显示CPU\内存\硬盘\网络等实时信息 --- Created by sugood(https://github.com/sugood). --- DateTime: 2022/01/14 22:00 --- local menubaritem = hs.menubar.new() local menuData = {} -- ipv4Interface ipv6 Interface local interface = hs.network.primaryInterfaces() -- 该对象用于存储全局变量,避免每次获取速度都创建新的局部变量 local obj = {} function init() if interface then local interface_detail = hs.network.interfaceDetails(interface) if interface_detail.IPv4 then local ipv4 = interface_detail.IPv4.Addresses[1] table.insert(menuData, { title = "IPv4:" .. ipv4, tooltip = "Copy Ipv4 to clipboard", fn = function() hs.pasteboard.setContents(ipv4) end }) end local mac = hs.execute('ifconfig ' .. interface .. ' | grep ether | awk \'{print $2}\'') table.insert(menuData, { title = 'MAC:' .. mac, tooltip = 'Copy MAC to clipboard', fn = function() hs.pasteboard.setContents(mac) end }) obj.last_down = hs.execute('netstat -ibn | grep -e ' .. interface .. ' -m 1 | awk \'{print $7}\'') obj.last_up = hs.execute('netstat -ibn | grep -e ' .. interface .. ' -m 1 | awk \'{print $10}\'') else obj.last_down = 0 obj.last_down = 0 end local date=os.date("%Y-%m-%d %a"); table.insert(menuData, { title = 'Date: '..date, tooltip = 'Copy Now DateTime', fn = function() hs.pasteboard.setContents(os.date("%Y-%m-%d %H:%M:%S")) end }) table.insert(menuData, { title = '打开:监 视 器 (⇧⌃A)', tooltip = 'Show Activity Monitor', fn = function() bindActivityMonitorKey() end }) table.insert(menuData, { title = '打开:磁盘工具 (⇧⌃D)', tooltip = 'Show Disk Utility', fn = function() bindDiskKey() end }) table.insert(menuData, { title = '打开:系统日历 (⇧⌃C)', tooltip = 'Show calendar', fn = function() bindCalendarKey() end }) menubaritem:setMenu(menuData) end function scan() if interface then obj.current_down = hs.execute('netstat -ibn | grep -e ' .. interface .. ' -m 1 | awk \'{print $7}\'') obj.current_up = hs.execute('netstat -ibn | grep -e ' .. interface .. ' -m 1 | awk \'{print $10}\'') else obj.current_down = 0 obj.current_up = 0 end obj.cpu_used = getCpu() obj.disk_used = getRootVolumes() obj.mem_used = getVmStats() obj.down_bytes = obj.current_down - obj.last_down obj.up_bytes = obj.current_up - obj.last_up obj.down_speed = format_speed(obj.down_bytes) obj.up_speed = format_speed(obj.up_bytes) obj.display_text = hs.styledtext.new('▲ ' .. obj.up_speed .. '\n'..'▼ ' .. obj.down_speed , {font={size=9}, color={hex='#FFFFFF'}, paragraphStyle={alignment="left", maximumLineHeight=18}}) obj.display_disk_text = hs.styledtext.new(obj.disk_used ..'\n'.. 'SSD ' , {font={size=9}, color={hex='#FFFFFF'}, paragraphStyle={alignment="left", maximumLineHeight=18}}) obj.display_mem_text = hs.styledtext.new(obj.mem_used ..'\n'.. 'MEM ' , {font={size=9}, color={hex='#FFFFFF'}, paragraphStyle={alignment="left", maximumLineHeight=18}}) obj.display_cpu_text = hs.styledtext.new(obj.cpu_used ..'\n'.. 'CPU ' , {font={size=9}, color={hex='#FFFFFF'}, paragraphStyle={alignment="left", maximumLineHeight=18}}) obj.last_down = obj.current_down obj.last_up = obj.current_up local canvas = hs.canvas.new{x = 0, y = 0, h = 24, w = 30+30+30+60} -- canvas[1] = {type = 'text', text = obj.display_text} canvas:appendElements({ type = "text", text = obj.display_cpu_text, -- withShadow = true, trackMouseEnterExit = true, },{ type = "text", text = obj.display_disk_text, -- withShadow = true, trackMouseEnterExit = true, frame = { x = 30, y = "0", h = "1", w = "1", } },{ type = "text", text = obj.display_mem_text, -- withShadow = true, trackMouseEnterExit = true, frame = { x = 60, y = "0", h = "1", w = "1", } },{ type = "text", text = obj.display_text, -- withShadow = true, trackMouseEnterExit = true, frame = { x = 90, y = "0", h = "1", w = "1", } }) menubaritem:setIcon(canvas:imageFromCanvas()) canvas:delete() canvas = nil end function format_speed(bytes) -- 单位 Byte/s if bytes < 1024 then return string.format('%6.0f', bytes) .. ' B/s' else -- 单位 KB/s if bytes < 1048576 then -- 因为是每两秒刷新一次,所以要除以 (1024 * 2) return string.format('%6.1f', bytes / 2048) .. ' KB/s' -- 单位 MB/s else -- 除以 (1024 * 1024 * 2) return string.format('%6.1f', bytes / 2097152) .. ' MB/s' end end end function getCpu() local data = hs.host.cpuUsage() local cpu = (data["overall"]["active"]) return formatPercent(cpu) end function getVmStats() local vmStats = hs.host.vmStat() -- --1024^2 -- local megDiv = 1048576 -- local megMulti = vmStats.pageSize / megDiv -- local totalMegs = vmStats.memSize / megDiv --总内存 -- local megsCached = vmStats.fileBackedPages * megMulti --缓存内存 -- local freeMegs = vmStats.pagesFree * megMulti --空闲内存 -- --第一种方法使用 APP内存+联动内存+被压缩内存 = 已使用内存 -- --local megsUsed = vmStats.pagesWiredDown * megMulti -- 联动内存 -- --megsUsed = megsUsed + vmStats.pagesUsedByVMCompressor * megMulti -- 被压缩内存 -- --megsUsed = megsUsed + (vmStats.pagesActive +vmStats.pagesSpeculative)* megMulti -- APP内存 -- --第二种方法使用 总内存-缓存内存-空闲内存 = 已使用内存 -- local megsUsed = totalMegs - megsCached - freeMegs --第三种方法,由于部分设备pageSize获取不正确,所以只能通过已使用页数+缓存页数+空闲页数计算总页数 local megsUsed = vmStats.pagesWiredDown -- 联动内存 megsUsed = megsUsed + vmStats.pagesUsedByVMCompressor -- 被压缩内存 megsUsed = megsUsed + vmStats.pagesActive +vmStats.pagesSpeculative -- APP内存 local megsCached = vmStats.fileBackedPages --缓存内存 local freeMegs = vmStats.pagesFree --空闲内存 local totalMegs = megsUsed + megsCached + freeMegs local usedMem = megsUsed/totalMegs * 100 return formatPercent(usedMem) end function getRootVolumes() local vols = hs.fs.volume.allVolumes() for key, vol in pairs(vols) do local size = vol.NSURLVolumeTotalCapacityKey local free = vol.NSURLVolumeAvailableCapacityKey local usedSSD = (1-free/size) * 100 if ( string.find(vol.NSURLVolumeNameKey,'Macintosh') ~= nil) then return formatPercent(usedSSD) end end return ' 0%' end function formatPercent(percent) if ( percent <= 0 ) then return " 1%" elseif ( percent < 10 ) then return " " .. string.format("%.f", percent) .. "%" elseif (percent > 99 )then return "100%" else return string.format("%.f", percent) .. "%" end end local setSysInfo= function() -- if config ~=nil and config[1].showSysInfo ~= 'on' then if 1 then if(menuBarItem ~= nil and menuBarItem:isInMenuBar() == false) then return end if (menuBarItem == nil) then print("设置状态栏:系统信息") menuBarItem= hs.menubar.new() elseif (menuBarItem:isInMenuBar() == false) then menuBarItem:delete() menuBarItem= hs.menubar.new() end init() scan() if obj.timer then obj.timer:stop() obj.timer = nil end -- 三秒刷新一次 obj.timer = hs.timer.doEvery(3, scan):start() end end function initData() setSysInfo() --监听系统信息开关的状态,判断是否要重置 hs.timer.doEvery(1, setSysInfo) end -- 初始化 initData()
猜你喜欢
网友评论
- 搜索
- 最新文章
- 热门文章