From aa93b1b524ee810117b2bb9f4fd38070ecc75443 Mon Sep 17 00:00:00 2001 From: qq Date: Mon, 2 Jan 2023 21:45:24 +0800 Subject: [PATCH] init --- .gitignore | 4 + README.md | 0 init.lua | 6 + modules/commons.lua | 290 ++++++++++++++++++++++++++++++++++++++++++++ modules/snippet.lua | 171 ++++++++++++++++++++++++++ 5 files changed, 471 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 init.lua create mode 100644 modules/commons.lua create mode 100644 modules/snippet.lua diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..59ece68 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/.idea/ +/*.zip +.idea/ +build/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..b23fcc4 --- /dev/null +++ b/init.lua @@ -0,0 +1,6 @@ +hs.configdir = os.getenv('HOME') .. '/.hammerspoon' +package.path = hs.configdir .. '/?.lua;' .. hs.configdir .. '/?/init.lua;' .. hs.configdir .. '/Spoons/?.spoon/init.lua;' .. package.path +~/.gitconfig~/.gitconfig + + +require "modules/snippet" \ No newline at end of file diff --git a/modules/commons.lua b/modules/commons.lua new file mode 100644 index 0000000..dd20e13 --- /dev/null +++ b/modules/commons.lua @@ -0,0 +1,290 @@ +--- +--- 公共函数 +--- Created by sugood(https://github.com/sugood). +--- DateTime: 2020/10/24 14:13 +--- +local console = require("hs.console") +version = "v0.2.0" +configPath= "~/.hammerspoon/data/config.json" +initConfigPath= "~/.hammerspoon/data/initConfig.json" +config = {} +colorDialog = hs.dialog.color + +--检查文件是否存在 +function checkFileExist(path) + local file = hs.fs.pathToAbsolute(path) + return file ~= nil +end + +--复制文件 +function copyFile(source,destination) + print(destination) + local sourcefile = io.open(source, "r") + local destinationfile = io.open(destination, "w") + destinationfile:write(sourcefile:read("*all")) + sourcefile:close() + destinationfile:close() +end + +function switchDict() + if config[1].dictEngine == '百度' then + config[1].dictEngine = '有道' + else + config[1].dictEngine = '百度' + end + hs.json.write(config,configPath, true, true) + hs.reload() +end + +function switchTime() + if config[1].isSyncTime == 'on' then + config[1].isSyncTime = 'off' + else + if(stringIsEmpty(config[1].rootPassword)) then + local result,subText = hs.dialog.textPrompt("输入开机密码", "时间同步操作需要开机密码", '', "确定", "取消", true) + if result == "确定" and stringIsEmpty(subText) == false then + config[1].rootPassword = subText + config[1].isSyncTime = 'on' + end + else + config[1].isSyncTime = 'on' + end + end + hs.json.write(config,configPath, true, true) + hs.reload() +end + +function switchCaffeine() + if config[1].caffeine == 'on' then + config[1].caffeine = 'off' + else + config[1].caffeine = 'on' + end + hs.json.write(config,configPath, true, true) + hs.reload() +end + +function switchSysInfo() + if config[1].showSysInfo == 'on' then + config[1].showSysInfo = 'off' + else + config[1].showSysInfo = 'on' + end + hs.json.write(config,configPath, true, true) + hs.reload() +end + +--设置全局菜单栏 +function initMenu() + macMenubar = hs.menubar.new() + macMenubar:setTitle("") + macMenubar:setIcon() + macMenubar:setMenu( { + { title = "Reload config", fn = function() + hs.reload() + end }, + { title = "Open console", fn = function() hs.openConsole() end }, + { title = "Relaunch", fn = function() hs.relaunch() end }, + { title = "-" }, + { title = "翻译平台:" .. config[1].dictEngine, fn = function() + if (hs.dialog.blockAlert("支持百度和有道翻译,确认切换?","有道翻译需先申请有道云API","确定","取消","informational") == "确定") then + switchDict() + end + end }, + { title = "输入appID", fn = function() + if(config[1].dictEngine == '有道') then + local result,subText = hs.dialog.textPrompt("输入appID", "请通过有道云API获取appkey", config[1].youdaoAppid, "确定", "取消", false) + if result == "确定" then + config[1].youdaoAppid = subText + hs.json.write(config,configPath, true, true) + end + elseif(config[1].dictEngine == '百度') then + local result,subText = hs.dialog.textPrompt("输入appID", "百度翻译可不修改", config[1].baiduAppid, "确定", "取消", true) + if result == "确定" then + config[1].baiduAppid = subText + hs.json.write(config,configPath, true, true) + end + end + end }, + { title = "输入appSecret", fn = function() + if(config[1].dictEngine == '有道') then + local result,subText = hs.dialog.textPrompt("输入appSecret", "请通过有道云API获取appSecret", config[1].youdaoAppSecret, "确定", "取消", false) + if result == "确定" then + config[1].youdaoAppSecret = subText + hs.json.write(config,configPath, true, true) + end + elseif(config[1].dictEngine == '百度') then + local result,subText = hs.dialog.textPrompt("输入appSecret", "百度翻译可不修改", config[1].baiduAppSecret, "确定", "取消", true) + if result == "确定" then + config[1].baiduAppSecret = subText + hs.json.write(config,configPath, true, true) + end + end + end }, + { title = "-" }, + { title = "时间同步:" .. config[1].isSyncTime, fn = function() + switchTime() + end }, + { title = "输入开机密码", fn = function() + local result,subText = hs.dialog.textPrompt("输入开机密码", "时间同步操作需要开机密码", config[1].rootPassword, "确定", "取消", true) + if result == "确定" then + config[1].rootPassword = subText + hs.json.write(config,configPath, true, true) + end + end }, + { title = "-" }, + { title = "屏幕取色", fn = function() + openColorDialog() + end }, + { title = "-" }, + { title = "咖啡因:" .. config[1].caffeine, fn = function() + switchCaffeine() + end }, + { title = "-" }, + { title = "系统状态:" .. config[1].showSysInfo, fn = function() + switchSysInfo() + end }, + { title = "-" }, + { title = "打开键盘偏好设置", fn = function() hs.osascript.applescript([[ + tell application "System Preferences" + reveal anchor "InputSources" of pane "com.apple.preference.keyboard" + activate + end tell ]] + ) end }, + { title = "-" }, + { title = "关于", fn = function() + if (hs.dialog.blockAlert("当前版本:"..version,"整理了一些能够提高效率的脚本,打开主页查看详细说明。","确定","取消","informational") == "确定") then + hs.urlevent.openURL("https://github.com/sugood/hammerspoon") + end + end }, + }) +end + +function initData() + --第一次安装需要复制一个配置文件。以后更新则不会修改用户配置文件,防止被覆盖 + if(checkFileExist(configPath) == false) then + print("初始化配置文件") + --获取绝对路径,io.open只支持绝对路径 + local source = hs.fs.pathToAbsolute(initConfigPath) + local destination = string.gsub(source, "initConfig.json$", "config.json") + copyFile(source,destination) + end + + if hs.json.read(configPath) ~= nil then + config = hs.json.read(configPath) + end + initMenu() + -- 修改全局alert样式 + hs.alert.defaultStyle.strokeColor = {white = 1, alpha = 0} + hs.alert.defaultStyle.fillColor = {white = 0.05, alpha = 0.50} + hs.alert.defaultStyle.radius = 10 + --清空打印信息 + console.clearConsole() + -- + colorDialog.mode("RGB") +end + +initData() + +-- 字符串判空 +function stringIsEmpty(str) + return str == nil or str == '' +end + +--生成url编码 +function decodeURI(s) + s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end) + return string.gsub(s, " ", "+") +end + +--截取UTF8字符 +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 + +--获取中英混合UTF8字符串的真实字符数量 +function SubStringGetTotalIndex(str) + local curIndex = 0; + local i = 1; + local lastCount = 1; + repeat + lastCount = SubStringGetByteCount(str, i) + i = i + lastCount; + curIndex = curIndex + 1; + until(lastCount == 0); + return curIndex - 1; +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 + +--判断是否复制成功 +function isCopySuccess() + local num = hs.pasteboard.changeCount() + print("复制前数量:"..num) + hs.eventtap.keyStroke({ "cmd" }, "C") + local numAfter = hs.pasteboard.changeCount() + print("复制后数量:"..numAfter) + return numAfter > num +end + +function openColorDialog() + hs.openConsole(true) + colorDialog.show() + colorDialog.mode("RGB") + colorDialog.callback(function(a,b) + if b then + hs.closeConsole() + end + end) + hs.closeConsole() +end + +--设置颜色拾取快键键 +hs.hotkey.bind(hyperCmd, "P", function () + openColorDialog() +end) + +--设置咖啡因开关 +hs.hotkey.bind(hyperCmd, "S", function () + switchCaffeine() +end) \ No newline at end of file diff --git a/modules/snippet.lua b/modules/snippet.lua new file mode 100644 index 0000000..59def20 --- /dev/null +++ b/modules/snippet.lua @@ -0,0 +1,171 @@ +local chooser = require("hs.chooser") + +local historyPath= "~/.hammerspoon/data/history.json" +local maxLength = 1000 +local history = {} +local mChooser + +function initData() + if hs.json.read(historyPath) ~= nil then + history = hs.json.read(historyPath) + end + isSearck = false +end +-- 初始化,读取本地数据 +initData() +-- 查重 +function duplicate(table,keys) + for k,v in ipairs(table) do + if v.text == keys then + return true + end + end + return false +end + +-- 查询text是否存在并返回索引index +-- 等于0为没有查询到,大于0为查询到 +function searchByText(table,text) + for k,v in ipairs(table) do + if v.text == text then + print("结果:"..k) + return k + end + end + return 0 +end +-- 清除收尾空格 +function trim(input) + return (string.gsub(input, "^%s*(.-)%s*$", "%1")) +end +-- 字符串分割 +string.split = function(s, p) + local rt= {} + string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end ) + return rt +end +-- 添加片段到记录列表中 +function addToHistory() + local item = {} + local str = hs.pasteboard.getContents() + if str == nil then + hs.alert.show("文本为空,请重新选择文本!") + end + local list = string.split(str, "|") + if #list >1 then + item.subText = trim(string.sub(str,#list[1]+2,string.len(str))) + item.text = trim(list[1]) + else + item.subText = trim(list[1]) + item.text = trim(list[1]) + end + + if duplicate(history, item.text) then + hs.alert.show("片段已经存在") + return + end + if #history >= maxLength then + hs.alert.show("片段已超过:"..maxLength.."个") + return + end + table.insert(history, 1, item) + -- 排序 + table.sort(history,function(a,b) return a.subText 0 then + local selectResult = mChooser:selectedRowContents(index) + if selectResult == nil or stringIsEmpty(selectResult.text) then + return + end + index = searchByText(history,selectResult.text) + if index == 0 then + hs.alert.show("找不到片段") + return + end + menubar = hs.menubar.new(false) + menubar:setTitle("Hidden Menu") + menubar:setMenu( { + { title = "菜单", fn = function() print("you clicked my menu item!") end }, + { title = "-" }, + { title = "修改片段内容", fn = function() + result,text = hs.dialog.textPrompt("修改片段内容", "请输入新的内容", history[index].text, "确定", "取消") + if result == "确定" then + modifyHistory(text,history[index].subText,true,index) + end + end }, + { title = "修改片段说明", fn = function() + result,subText = hs.dialog.textPrompt("修改片段说明", "请输入新的说明", history[index].subText, "确定", "取消") + if result == "确定" then + modifyHistory(history[index].text,subText,false,index) + end + end }, + { title = "-" }, + { title = "删除当前片段", fn = function() + if hs.dialog.blockAlert("确定删除以下片段?",history[index].text,"确定","取消","informational") == "确定" then + table.remove(history,index) + hs.json.write(history,historyPath, true, true) + hs.alert.show("成功删除片段") + end + end }, + }) + menubar:popupMenu(hs.mouse.getAbsolutePosition(), true) + else + hs.alert.show("错误") + end +end +-- 选取片段内容(按下快捷键时显示片段列表,点击选中的快捷键将自动粘贴) +hs.hotkey.bind(hyperCmd, "V", function () + mChooser = chooser.new(completionFn) + :choices(history) + :rightClickCallback(rightClickCallbackFn) + :searchSubText(true) + :show() +end) +-- 添加片段(按下快捷键时做一个复制操作,并记录复制的内容到片段列表中) +hs.hotkey.bind(hyperCmd, "X", function () + bindCopyKey() + if hs.dialog.blockAlert("添加片段:‘|’为分隔符,建议按如下格式","内容|keyword|示例|说明","确定","取消","informational") == "确定" then + addToHistory() + end +end)