mirror of https://github.com/einverne/dotfiles.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
395 lines
12 KiB
395 lines
12 KiB
4 years ago
|
--- === ClipShow ===
|
||
|
---
|
||
|
--- Show the content of system clipboard
|
||
|
---
|
||
|
--- Download: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/ClipShow.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/ClipShow.spoon.zip)
|
||
|
|
||
|
local obj={}
|
||
|
obj.__index = obj
|
||
|
|
||
|
-- Metadata
|
||
|
obj.name = "ClipShow"
|
||
|
obj.version = "1.0"
|
||
|
obj.author = "ashfinal <[email protected]>"
|
||
|
obj.homepage = "https://github.com/Hammerspoon/Spoons"
|
||
|
obj.license = "MIT - https://opensource.org/licenses/MIT"
|
||
|
|
||
|
obj.canvas = nil
|
||
|
obj.ccount = nil
|
||
|
obj.lastsession = nil
|
||
|
|
||
|
|
||
|
function obj:init()
|
||
|
obj.canvas = hs.canvas.new({x=0, y=0, w=0, h=0})
|
||
|
obj.canvas[1] = {
|
||
|
type = "rectangle",
|
||
|
action = "fill",
|
||
|
fillColor = {hex="#000000", alpha=0.75}
|
||
|
}
|
||
|
obj.canvas[2] = {
|
||
|
type = "segments",
|
||
|
strokeColor = {hex = "#FFFFFF", alpha = 0.1},
|
||
|
coordinates = {
|
||
|
{x="1%", y="72%"},
|
||
|
{x="72%", y="72%"}
|
||
|
}
|
||
|
}
|
||
|
obj.canvas[3] = {
|
||
|
type = "segments",
|
||
|
strokeColor = {hex = "#FFFFFF", alpha = 0.1},
|
||
|
coordinates = {
|
||
|
{x="72%", y="1%"},
|
||
|
{x="72%", y="99%"}
|
||
|
}
|
||
|
}
|
||
|
obj.canvas[4] = {type = "text", text = ""}
|
||
|
obj.canvas[5] = {type = "text"}
|
||
|
obj.canvas:level(hs.canvas.windowLevels.tornOffMenu)
|
||
|
end
|
||
|
|
||
|
local function isFileKinds(val, tbl)
|
||
|
for _, v in ipairs(tbl) do
|
||
|
if val == v then
|
||
|
return true
|
||
|
end
|
||
|
end
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
-- Resize the ClipShow canvas
|
||
|
function obj:adjustCanvas()
|
||
|
local cscreen = hs.screen.mainScreen()
|
||
|
local cres = cscreen:fullFrame()
|
||
|
obj.canvas:frame({
|
||
|
x = cres.x+cres.w*0.15/2,
|
||
|
y = cres.y+cres.h*0.25/2,
|
||
|
w = cres.w*0.85,
|
||
|
h = cres.h*0.75
|
||
|
})
|
||
|
end
|
||
|
|
||
|
-- Fill clipshowM's keybindings in sidebar
|
||
|
function obj:fillModalKeys()
|
||
|
if #obj.canvas < 6 then
|
||
|
local modal = spoon.ModalMgr.modal_list["clipshowM"]
|
||
|
if modal then
|
||
|
local keys_pool = {}
|
||
|
for _, v in ipairs(modal.keys) do
|
||
|
table.insert(keys_pool, v.msg)
|
||
|
end
|
||
|
for idx, val in ipairs(keys_pool) do
|
||
|
obj.canvas[idx + 5] = {
|
||
|
type = "text",
|
||
|
text = val,
|
||
|
textFont = "Courier-Bold",
|
||
|
textSize = 16,
|
||
|
textColor = {hex = "#2390FF", alpha = 1},
|
||
|
frame = {
|
||
|
x = "74%",
|
||
|
y = tostring(idx * 30 / (obj.canvas:frame().h - 60)),
|
||
|
w = "24%",
|
||
|
h = tostring(30 / (obj.canvas:frame().h - 60))
|
||
|
}
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--- ClipShow:toggleShow()
|
||
|
--- Method
|
||
|
--- Process the content of system clipboard and show/hide the canvas
|
||
|
---
|
||
|
|
||
|
function obj:processClipboard()
|
||
|
local clip_type = hs.pasteboard.typesAvailable()
|
||
|
if clip_type.image then
|
||
|
if clip_type.URL then
|
||
|
local urltbl = hs.pasteboard.readURL()
|
||
|
if urltbl.filePath then
|
||
|
-- local file
|
||
|
local fex = urltbl.filePath:match(".*%.(%w+)$") or ""
|
||
|
local image_ex = {"jpeg", "jpg", "gif", "png", "bmp", "tiff", "icns"}
|
||
|
local text_ex = {"", "txt", "md", "markdown", "mkd", "rst", "org", "sh", "zsh", "json", "yml", "mk", "config", "conf", "pub", "gitignore"}
|
||
|
if isFileKinds(fex:lower(), image_ex) then
|
||
|
local imagedata = hs.image.imageFromPath(urltbl.filePath)
|
||
|
obj.canvas[4] = {
|
||
|
type = "image",
|
||
|
image = imagedata,
|
||
|
frame = {
|
||
|
x = "1%",
|
||
|
y = "1%",
|
||
|
w = "70%",
|
||
|
h = "70%"
|
||
|
}
|
||
|
}
|
||
|
elseif isFileKinds(fex:lower(), text_ex) then
|
||
|
-- text file format
|
||
|
local file_handler = io.open(urltbl.filePath)
|
||
|
if file_handler then
|
||
|
local file_content = file_handler:read(1000)
|
||
|
if file_content then
|
||
|
obj.canvas[4] = {
|
||
|
type = "text",
|
||
|
text = file_content,
|
||
|
textSize = 20,
|
||
|
frame = {
|
||
|
x = "1%",
|
||
|
y = "1%",
|
||
|
w = "70%",
|
||
|
h = "70%"
|
||
|
}
|
||
|
}
|
||
|
file_handler:close()
|
||
|
else
|
||
|
-- Maybe directory
|
||
|
local dir_name = urltbl.filePath
|
||
|
obj.canvas[4] = {
|
||
|
type = "text",
|
||
|
text = dir_name,
|
||
|
frame = {
|
||
|
x = "1%",
|
||
|
y = "1%",
|
||
|
w = "70%",
|
||
|
h = "70%"
|
||
|
}
|
||
|
}
|
||
|
end
|
||
|
else
|
||
|
print("-- ClipShow: No access to this file!")
|
||
|
end
|
||
|
else
|
||
|
local stringdata = table.concat(hs.pasteboard.readString(nil, true))
|
||
|
obj.canvas[4] = {
|
||
|
type = "text",
|
||
|
text = stringdata,
|
||
|
frame = {
|
||
|
x = "1%",
|
||
|
y = "1%",
|
||
|
w = "70%",
|
||
|
h = "70%"
|
||
|
}
|
||
|
}
|
||
|
end
|
||
|
else
|
||
|
-- Remote image
|
||
|
local imagedata = hs.pasteboard.readImage()
|
||
|
obj.canvas[4] = {
|
||
|
type = "image",
|
||
|
image = imagedata,
|
||
|
frame = {
|
||
|
x = "1%",
|
||
|
y = "1%",
|
||
|
w = "70%",
|
||
|
h = "70%"
|
||
|
}
|
||
|
}
|
||
|
end
|
||
|
else
|
||
|
-- Image fragement
|
||
|
local imagedata = hs.pasteboard.readImage()
|
||
|
obj.canvas[4] = {
|
||
|
type = "image",
|
||
|
image = imagedata,
|
||
|
frame = {
|
||
|
x = "1%",
|
||
|
y = "1%",
|
||
|
w = "70%",
|
||
|
h = "70%"
|
||
|
}
|
||
|
}
|
||
|
end
|
||
|
obj:adjustCanvas()
|
||
|
obj:fillModalKeys()
|
||
|
obj.canvas:show()
|
||
|
elseif clip_type.URL then
|
||
|
local urltbl = hs.pasteboard.readURL(nil, true)
|
||
|
if urltbl then
|
||
|
if #urltbl > 1 then
|
||
|
local stringdata = table.concat(hs.pasteboard.readString(nil, true))
|
||
|
obj.canvas[4] = {
|
||
|
type = "text",
|
||
|
text = stringdata,
|
||
|
frame = {
|
||
|
x = "1%",
|
||
|
y = "1%",
|
||
|
w = "70%",
|
||
|
h = "70%"
|
||
|
}
|
||
|
}
|
||
|
obj:adjustCanvas()
|
||
|
obj:fillModalKeys()
|
||
|
obj.canvas:show()
|
||
|
else
|
||
|
local browser = hs.urlevent.getDefaultHandler("http")
|
||
|
hs.urlevent.openURLWithBundle(urltbl[1].url, browser)
|
||
|
end
|
||
|
else
|
||
|
local browser = hs.urlevent.getDefaultHandler("http")
|
||
|
hs.urlevent.openURLWithBundle(urltbl[1].url, browser)
|
||
|
end
|
||
|
elseif clip_type.string then
|
||
|
local stringdata = table.concat(hs.pasteboard.readString(nil, true))
|
||
|
obj.canvas[4] = {
|
||
|
type = "text",
|
||
|
text = stringdata,
|
||
|
frame = {
|
||
|
x = "1%",
|
||
|
y = "1%",
|
||
|
w = "70%",
|
||
|
h = "70%"
|
||
|
}
|
||
|
}
|
||
|
obj:adjustCanvas()
|
||
|
obj:fillModalKeys()
|
||
|
obj.canvas:show()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function obj:toggleShow()
|
||
|
if obj.canvas:isShowing() then
|
||
|
obj.canvas:hide()
|
||
|
else
|
||
|
local change_count = hs.pasteboard.changeCount()
|
||
|
-- Only if content of the clipboard changed then we redraw the canvas
|
||
|
if change_count ~= obj.ccount then
|
||
|
obj:processClipboard()
|
||
|
obj.ccount = change_count
|
||
|
else
|
||
|
obj:adjustCanvas()
|
||
|
obj.canvas:show()
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--- ClipShow:openInBrowserWithRef(refstr)
|
||
|
--- Method
|
||
|
--- Open content of the clipboard in default browser with specific refstr.
|
||
|
---
|
||
|
--- Parameters:
|
||
|
--- * refstr - A optional string specifying which refstr to use. If nil, then open this content in browser directly. The "refstr" could be something like this: `https://www.bing.com/search?q=`.
|
||
|
|
||
|
local function acquireText()
|
||
|
if obj.canvas:isShowing() then
|
||
|
if obj.canvas[4].type == "text" then
|
||
|
return obj.canvas[4].text
|
||
|
else
|
||
|
return hs.pasteboard.readString() or ""
|
||
|
end
|
||
|
else
|
||
|
return hs.pasteboard.readString() or ""
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function obj:openInBrowserWithRef(refstr)
|
||
|
local querystr = acquireText()
|
||
|
if refstr then
|
||
|
local encoded_query = hs.http.encodeForQuery(refstr .. querystr)
|
||
|
local defaultbrowser = hs.urlevent.getDefaultHandler("http")
|
||
|
hs.urlevent.openURLWithBundle(encoded_query, defaultbrowser)
|
||
|
else
|
||
|
local defaultbrowser = hs.urlevent.getDefaultHandler("http")
|
||
|
hs.urlevent.openURLWithBundle(querystr, defaultbrowser)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--- ClipShow:saveToSession()
|
||
|
--- Method
|
||
|
--- Save clipboard session so we can restore it later
|
||
|
---
|
||
|
|
||
|
function obj:saveToSession()
|
||
|
obj.lastsession = hs.pasteboard.readAllData()
|
||
|
if obj.canvas:isShowing() then
|
||
|
if obj.canvas[4].type == "text" then
|
||
|
local cdraw = obj.canvas[4].text
|
||
|
hs.pasteboard.writeObjects(cdraw)
|
||
|
obj.canvas[5] = {
|
||
|
type = "text",
|
||
|
text = cdraw,
|
||
|
textSize = 16,
|
||
|
textAlignment = "center",
|
||
|
frame = {
|
||
|
x = "1%",
|
||
|
y = "73%",
|
||
|
w = "70%",
|
||
|
h = "26%"
|
||
|
}
|
||
|
}
|
||
|
elseif obj.canvas[4].type == "image" then
|
||
|
local cdraw = obj.canvas[4].image
|
||
|
hs.pasteboard.writeObjects(cdraw)
|
||
|
obj.canvas[5] = {
|
||
|
type = "image",
|
||
|
image = cdraw,
|
||
|
frame = {
|
||
|
x = "1%",
|
||
|
y = "73%",
|
||
|
w = "70%",
|
||
|
h = "26%"
|
||
|
}
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--- ClipShow:restoreLastSession()
|
||
|
--- Method
|
||
|
--- Restore the lastsession of system clipboard
|
||
|
---
|
||
|
|
||
|
function obj:restoreLastSession()
|
||
|
if obj.lastsession then
|
||
|
hs.pasteboard.writeAllData(obj.lastsession)
|
||
|
obj:processClipboard()
|
||
|
obj.ccount = change_count
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--- ClipShow:saveToFile()
|
||
|
--- Method
|
||
|
--- Save content of current canvas to a file, the default location is `~/Desktop/`.
|
||
|
---
|
||
|
|
||
|
function obj:saveToFile()
|
||
|
if obj.canvas:isShowing() then
|
||
|
if obj.canvas[4].type == "image" then
|
||
|
local cdraw = obj.canvas[4].image
|
||
|
local file_name = os.date("%Y-%m-%d %H:%M:%S")
|
||
|
cdraw:saveToFile("~/Desktop/" .. file_name .. ".png", true)
|
||
|
elseif obj.canvas[4].type == "text" then
|
||
|
local ctext = obj.canvas[4].text
|
||
|
local file_name = os.date("%Y-%m-%d %H:%M:%S")
|
||
|
local full_path = os.getenv("HOME") .. "/Desktop/" .. file_name .. ".txt"
|
||
|
local file_handler = io.open(full_path, "w")
|
||
|
file_handler:write(ctext)
|
||
|
file_handler:close()
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--- ClipShow:openWithCommand(command)
|
||
|
--- Method
|
||
|
--- Open local file with specific command.
|
||
|
---
|
||
|
--- Parameters:
|
||
|
--- * command - A string specifying which command to use. The "command" is something like this: `/usr/local/bin/mvim`.
|
||
|
|
||
|
function obj:openWithCommand(command)
|
||
|
if obj.canvas:isShowing() then
|
||
|
if obj.canvas[4].type == "text" then
|
||
|
local urltbl = hs.pasteboard.readURL()
|
||
|
if urltbl then
|
||
|
if urltbl.filePath then
|
||
|
os.execute(command .. " " .. urltbl.filePath)
|
||
|
else
|
||
|
os.execute(command)
|
||
|
end
|
||
|
else
|
||
|
os.execute(command)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
return obj
|