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.
394 lines
12 KiB
394 lines
12 KiB
--- === 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
|
|
|