Skip to content

Commit 70f5587

Browse files
committed
[cliphist] Add cliphist extension
1 parent 53c4bdd commit 70f5587

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

cliphist/__init__.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import albert as al
2+
import subprocess as sp
3+
import time
4+
5+
md_iid = "3.0"
6+
md_version = "1.0"
7+
md_name = "ClipHist"
8+
md_description = "Access cliphist clipboard"
9+
md_license = "MIT"
10+
md_url = "https://github.com/albertlauncher/python/tree/main/cliphist"
11+
md_authors = ["@ivomac"]
12+
md_bin_dependencies = ["cliphist"]
13+
14+
15+
def delete(entry: str):
16+
"""Delete an entry from the cliphist history."""
17+
18+
sp.run(
19+
["cliphist", "delete"],
20+
input=entry,
21+
stdout=sp.PIPE,
22+
text=True,
23+
).stdout
24+
25+
return
26+
27+
28+
def copy(entry: str):
29+
"""Copy an entry from the cliphist history to the clipboard."""
30+
31+
clip_entry = sp.run(
32+
["cliphist", "decode"],
33+
input=entry,
34+
stdout=sp.PIPE,
35+
text=True,
36+
).stdout
37+
38+
al.setClipboardText(clip_entry)
39+
40+
return
41+
42+
43+
class Plugin(al.PluginInstance, al.TriggerQueryHandler):
44+
iconUrls = ["xdg:clipboard"]
45+
46+
def __init__(self):
47+
al.PluginInstance.__init__(self)
48+
al.TriggerQueryHandler.__init__(self)
49+
50+
def defaultTrigger(self):
51+
return "cl "
52+
53+
def handleTriggerQuery(self, query):
54+
for _ in range(5):
55+
time.sleep(0.02)
56+
if not query.isValid:
57+
return
58+
59+
plug_id = self.id()
60+
61+
matcher = al.Matcher(query.string)
62+
63+
# Get the list of cliphist entries
64+
clip_history = (
65+
sp.run(
66+
["cliphist", "list"],
67+
stdout=sp.PIPE,
68+
text=True,
69+
)
70+
.stdout.strip()
71+
.splitlines()
72+
)
73+
74+
# cliphist items are in the format:
75+
# <id>\t<approximate text>
76+
splits = [(item, *item.split("\t", 1)) for item in clip_history]
77+
78+
query.add(
79+
[
80+
al.StandardItem(
81+
id=plug_id,
82+
iconUrls=self.iconUrls,
83+
text=text,
84+
subtext=idx,
85+
actions=[
86+
al.Action("copy", "Copy", lambda u=item: copy(u)),
87+
al.Action("delete", "Delete", lambda u=item: delete(u)),
88+
],
89+
)
90+
for item, idx, text in splits
91+
if matcher.match(item)
92+
]
93+
)
94+
95+
return

0 commit comments

Comments
 (0)