-
-
Save confluencepoint/5fcc79cd870c487e537f635aaa4ab04d to your computer and use it in GitHub Desktop.
My Hammerspoon config
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
local math = require("hs.math") | |
currentSpeech = nil | |
mouseCircle = nil | |
mouseCircleTimer = nil | |
function mouseHighlight() | |
-- Delete an existing highlight if it exists | |
if mouseCircle then | |
mouseCircle:delete() | |
if mouseCircleTimer then | |
mouseCircleTimer:stop() | |
end | |
end | |
-- Get the current co-ordinates of the mouse pointer | |
mousepoint = hs.mouse.getAbsolutePosition() | |
-- Prepare a big red circle around the mouse pointer | |
mouseCircle = hs.drawing.circle(hs.geometry.rect(mousepoint.x-40, mousepoint.y-40, 80, 80)) | |
mouseCircle:setStrokeColor({["red"]=1,["blue"]=0,["green"]=0,["alpha"]=1}) | |
mouseCircle:setFill(false) | |
mouseCircle:setStrokeWidth(5) | |
mouseCircle:show() | |
-- Set a timer to delete the circle after 3 seconds | |
mouseCircleTimer = hs.timer.doAfter(3, function() | |
mouseCircle:delete() | |
mouseCircle = nil | |
end) | |
end | |
hs.hotkey.bind({"cmd","alt","shift"}, "4", mouseHighlight) | |
function compressImageCommand() | |
image = hs.pasteboard.readImage() | |
if image then | |
hs.alert.show("IMAGE") | |
tempDir = hs.fs.temporaryDirectory() | |
imagePath = tempDir .. hs.host.uuid() .. ".png" | |
hs.alert.show(imagePath) | |
image:saveToFile(imagePath) | |
byteSize = hs.fs.attributes(imagePath, "size") | |
hs.alert.show(byteSize .. " bytes") | |
-- Open ImageOptim | |
hs.urlevent.openURLWithBundle(hs.fs.urlFromPath(imagePath), "net.pornel.ImageOptim") | |
end | |
-- hs.notify.new(nil, { | |
-- contentImage=image | |
-- }):send() | |
end | |
function resizeImageCommand() | |
image = hs.pasteboard.readImage() | |
if image then | |
-- fullSize = image:size() | |
button, newSizeInput = hs.dialog.textPrompt("Enter size", "Resize to the specified size.", "", "OK", "Cancel") | |
if button == "Cancel" then | |
return | |
end | |
newSize = math.tointeger(tonumber(newSizeInput)) | |
if newSize > 0 then | |
hs.alert.show("New size: " .. newSize) | |
image = image:copy():size({ w = newSize, h = newSize }) | |
imageURLEncoded = image:encodeAsURLString() | |
image = hs.image.imageFromURL(imageURLEncoded) | |
hs.pasteboard.clearContents() | |
hs.pasteboard.writeObjects(image) | |
end | |
end | |
end | |
function copyImageAsURL() | |
image = hs.pasteboard.readImage() | |
if image then | |
imageURLEncoded = image:encodeAsURLString() | |
hs.pasteboard.clearContents() | |
hs.pasteboard.writeObjects(imageURLEncoded) | |
end | |
end | |
function copyEnteredText() | |
defaultText = hs.pasteboard.readString() | |
button, text = hs.dialog.textPrompt("Enter text", "Text will be copied to the clipboard.", defaultText, "Copy", "Cancel") | |
if button == "Copy" then | |
hs.pasteboard.writeObjects(text) | |
end | |
end | |
function copyEnteredJavaScript() | |
defaultSource = hs.pasteboard.readString() | |
button, source = hs.dialog.textPrompt("Enter JavaScript", "Code will be run and its result copied to the clipboard.", defaultSource, "Copy Result", "Cancel") | |
if button == "Copy Result" then | |
success, result, descriptor = hs.osascript.javascript(source) | |
if success then | |
hs.alert.show(hs.inspect(result)) | |
hs.alert.show(hs.inspect(descriptor)) | |
-- asJSON = hs.json.encode(result, true) | |
if type(result) == "number" then | |
hs.pasteboard.writeObjects("" .. result) | |
else | |
hs.pasteboard.writeObjects(descriptor) | |
end | |
else | |
hs.alert.show("ERROR") | |
hs.alert.show(hs.inspect(descriptor)) | |
end | |
end | |
end | |
function copyFormattedJSON() | |
text = hs.pasteboard.readString() | |
json = hs.json.decode(text) | |
if json then | |
hs.alert.show("Valid JSON") | |
encoded = hs.json.encode(json, true) | |
hs.pasteboard.writeObjects(encoded) | |
end | |
end | |
function copyUnformattedText() | |
text = hs.pasteboard.readString() | |
if text then | |
hs.pasteboard.clearContents() | |
hs.pasteboard.writeObjects(text) | |
end | |
end | |
function copyAlphanumericText() | |
text = hs.pasteboard.readString() | |
if text then | |
hs.pasteboard.clearContents() | |
text = text:gsub('[^0-9a-zA-Z]', "") | |
hs.pasteboard.writeObjects(text) | |
end | |
end | |
function copyUTF8Length() | |
text = hs.pasteboard.readString() | |
if text then | |
hs.pasteboard.clearContents() | |
hs.pasteboard.writeObjects(text:len()) | |
end | |
end | |
function copyBase64Encoded() | |
text = hs.pasteboard.readString() | |
if text then | |
hs.pasteboard.writeObjects(hs.base64.encode(text)) | |
end | |
end | |
function copyBase64Decoded() | |
text = hs.pasteboard.readString() | |
if text then | |
hs.pasteboard.writeObjects(hs.base64.decode(text)) | |
end | |
end | |
function copySHA256Digest() | |
text = hs.pasteboard.readString() | |
if text then | |
hs.pasteboard.writeObjects(hs.hash.SHA256(text)) | |
end | |
end | |
function stopSpeaking() | |
if currentSpeech then | |
currentSpeech:stop() | |
currentSpeech = nil | |
end | |
end | |
function speakText(text) | |
stopSpeaking() | |
currentSpeech = hs.speech.new() | |
currentSpeech:speak(text) | |
end | |
function showClipboardMenu() | |
stopSpeaking() | |
menubar = hs.menubar.new(false) | |
menubar:setMenu(function() | |
menuItems = {} | |
text = hs.pasteboard.readString() | |
if text then | |
table.insert(menuItems, { title = text, disabled = true }) | |
-- table.insert(menuItems, { title = "-" }) | |
table.insert(menuItems, { title = "Speak…", fn = function() speakText(text) end }) | |
table.insert(menuItems, { title = "Remove Formatting", fn = copyUnformattedText }) | |
table.insert(menuItems, { title = "Remove Non-Alphanumeric", fn = copyAlphanumericText }) | |
table.insert(menuItems, { title = "UTF-8 Length: " .. text:len(), fn = copyUTF8Length }) | |
table.insert(menuItems, { title = "SHA256: " .. hs.hash.SHA256(text), fn = copySHA256Digest }) | |
-- table.insert(menuItems, { title = "-" }) | |
--table.insert(menuItems, { title = "Format JSON", fn = copyFormattedJSON }) | |
table.insert(menuItems, { title = "Encode to Base64", fn = copyBase64Encoded }) | |
table.insert(menuItems, { title = "Decode from Base64", fn = copyBase64Decoded }) | |
-- table.insert(menuItems, { title = "Copy SHA256 Digest", fn = copySHA256Digest }) | |
table.insert(menuItems, { title = "-" }) | |
end | |
image = hs.pasteboard.readImage() | |
if image then | |
fullSize = image:size() | |
-- hs.alert.show("Image " .. math.tointeger(hs.inspect(fullSize["h"]))) | |
-- hs.alert.show(hs.inspect(fullSize["h"])) | |
resizedImage = image:copy():size({ w = 500, h = 500 }) | |
if resizedImage then | |
table.insert(menuItems, { title = "Image " .. fullSize["w"] .. " × " .. fullSize["h"], disabled = true }) | |
table.insert(menuItems, { title = "", image = resizedImage }) | |
table.insert(menuItems, { title = "Optimize Image…", fn = compressImageCommand }) | |
table.insert(menuItems, { title = "Resize Image…", fn = resizeImageCommand }) | |
table.insert(menuItems, { title = "Copy as data:image/png", fn = copyImageAsURL }) | |
table.insert(menuItems, { title = "-" }) | |
end | |
end | |
table.insert(menuItems, { title = "Copy Text…", fn = copyEnteredText }) | |
table.insert(menuItems, { title = "Copy Result of JavaScript…", fn = copyEnteredJavaScript }) | |
table.insert(menuItems, { title = "Copy Random UUID", fn = function() hs.pasteboard.writeObjects(hs.host.uuid()) end }) | |
table.insert(menuItems, { title = "-" }) | |
table.insert(menuItems, { title = hs.inspect(hs.pasteboard.typesAvailable()), disabled = true }) | |
return menuItems | |
end) | |
menubar:popupMenu(hs.mouse.absolutePosition()) | |
end | |
hs.hotkey.bind({"control"}, "escape", showClipboardMenu) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment