117 lines
2.5 KiB
Nim
117 lines
2.5 KiB
Nim
|
import base
|
||
|
import std/[strutils,os,db_sqlite,osproc]
|
||
|
|
||
|
const CLIP_DB = WM_TOOLS_DIR & ".clipboard_cache.sqlite"
|
||
|
const KEEP_ITEMS = 20
|
||
|
|
||
|
proc openDBConn(): DBConn =
|
||
|
let db: DBconn = open(CLIP_DB,"","","")
|
||
|
try:
|
||
|
db.exec(sql"""create table if not exists
|
||
|
clip_items (
|
||
|
timestamp DATETIME NOT NULL,
|
||
|
clip NVARCHAR(500) NOT NULL
|
||
|
)
|
||
|
""")
|
||
|
except:
|
||
|
echo getCurrentExceptionMsg()
|
||
|
return db
|
||
|
|
||
|
proc clearHistory() =
|
||
|
let db = openDBConn()
|
||
|
defer: db.close()
|
||
|
try:
|
||
|
db.exec(sql"drop table if exists clip_items")
|
||
|
except:
|
||
|
echo getCurrentExceptionMsg()
|
||
|
|
||
|
proc getCurrentClipboardContent(): string =
|
||
|
var str = ""
|
||
|
if wayland:
|
||
|
let cur = execCmdEx("wl-paste")
|
||
|
if cur.exitcode == 0:
|
||
|
str = cur[0]
|
||
|
else:
|
||
|
echo cur
|
||
|
return str
|
||
|
|
||
|
proc maintainDB() =
|
||
|
let db = openDBConn()
|
||
|
try:
|
||
|
db.exec(sql"""BEGIN""")
|
||
|
db.exec(sql"delete from clip_items order by timestamp desc offset ?", KEEP_ITEMS)
|
||
|
db.exec(sql"""COMMIT""")
|
||
|
except:
|
||
|
echo getCurrentExceptionMsg()
|
||
|
|
||
|
proc escapeClip(str: string): string =
|
||
|
var clip = str
|
||
|
clip = clip.replace("`","\\`")
|
||
|
clip = escape(clip)
|
||
|
return clip
|
||
|
|
||
|
proc unescapeClip(str: string): string =
|
||
|
var clip = str
|
||
|
try:
|
||
|
clip = unescape(clip)
|
||
|
except:
|
||
|
echo getCurrentExceptionMsg()
|
||
|
|
||
|
return clip
|
||
|
|
||
|
proc readClipFile(): seq[string] =
|
||
|
var clips: seq[string] = @[]
|
||
|
let db = openDBConn()
|
||
|
defer: db.close()
|
||
|
try:
|
||
|
for row in db.fastRows(sql"select clip from clip_items order by timestamp desc"):
|
||
|
var str = unescapeClip(row[0])
|
||
|
clips.add(str)
|
||
|
except:
|
||
|
echo getCurrentExceptionMsg()
|
||
|
return clips
|
||
|
|
||
|
proc addClip(str: string) =
|
||
|
if str == "":
|
||
|
return
|
||
|
let db = openDBConn()
|
||
|
defer: db.close()
|
||
|
try:
|
||
|
db.exec(sql"""BEGIN""")
|
||
|
db.exec(sql"""insert into clip_items (timestamp, clip)
|
||
|
values (CURRENT_TIMESTAMP, ?)
|
||
|
""", escapeClip(str))
|
||
|
db.exec(sql"""COMMIT""")
|
||
|
except:
|
||
|
echo getCurrentExceptionMsg()
|
||
|
return
|
||
|
|
||
|
proc showClips() =
|
||
|
let clips = readClipFile()
|
||
|
let info = newInfo("Clips")
|
||
|
let option = outputData(info, clips)
|
||
|
if option != "":
|
||
|
copyToClipboard(option)
|
||
|
return
|
||
|
|
||
|
proc main() =
|
||
|
for idx, arg in args:
|
||
|
if arg == "set":
|
||
|
addClip(getCurrentClipboardContent())
|
||
|
return
|
||
|
if arg == "clear":
|
||
|
clearHistory()
|
||
|
return
|
||
|
showClips()
|
||
|
return
|
||
|
|
||
|
block start:
|
||
|
if isMainModule:
|
||
|
if not wayland:
|
||
|
echo "Not a wayland session, exiting..."
|
||
|
break start
|
||
|
else:
|
||
|
main()
|
||
|
|
||
|
maintainDB()
|