101 lines
2.2 KiB
Lua
101 lines
2.2 KiB
Lua
--- @since 25.5.31
|
|
|
|
local update = ya.sync(function(st, tags)
|
|
for path, tag in pairs(tags) do
|
|
st.tags[path] = #tag > 0 and tag or nil
|
|
end
|
|
ya.render()
|
|
end)
|
|
|
|
local selected_or_hovered = ya.sync(function()
|
|
local tab, urls = cx.active, {}
|
|
for _, u in pairs(tab.selected) do
|
|
urls[#urls + 1] = u
|
|
end
|
|
if #urls == 0 and tab.current.hovered then
|
|
urls[1] = tab.current.hovered.url
|
|
end
|
|
return urls
|
|
end)
|
|
|
|
local function setup(st, opts)
|
|
st.tags = {}
|
|
st.keys = opts.keys
|
|
st.colors = opts.colors
|
|
|
|
Linemode:children_add(function(self)
|
|
local url = tostring(self._file.url)
|
|
local spans = {}
|
|
for _, tag in ipairs(st.tags[url] or {}) do
|
|
if self._file.is_hovered then
|
|
spans[#spans + 1] = ui.Span(" ●"):bg(st.colors[tag] or "reset")
|
|
else
|
|
spans[#spans + 1] = ui.Span(" ●"):fg(st.colors[tag] or "reset")
|
|
end
|
|
end
|
|
return ui.Line(spans)
|
|
end, 500)
|
|
end
|
|
|
|
local function fetch(_, job)
|
|
local paths = {}
|
|
for _, file in ipairs(job.files) do
|
|
paths[#paths + 1] = tostring(file.url)
|
|
end
|
|
|
|
local output, err = Command("tag"):arg(paths):stdout(Command.PIPED):output()
|
|
if not output then
|
|
return true, Err("Cannot spawn `tag` command, error: %s", err)
|
|
end
|
|
|
|
local i, tags = 1, {}
|
|
for line in output.stdout:gmatch("[^\r\n]+") do
|
|
if i > #paths then
|
|
break
|
|
end
|
|
tags[paths[i]] = tags[paths[i]] or {}
|
|
|
|
local joint = line:match("\t(.+)$") or ""
|
|
for s in joint:gmatch("[^,]+") do
|
|
table.insert(tags[paths[i]], s)
|
|
end
|
|
i = i + 1
|
|
end
|
|
|
|
update(tags)
|
|
return true
|
|
end
|
|
|
|
local cands = ya.sync(function(st)
|
|
local t = {}
|
|
for k, v in pairs(st.keys) do
|
|
t[#t + 1] = { on = k, desc = v }
|
|
end
|
|
return t
|
|
end)
|
|
|
|
local function entry(self, job)
|
|
assert(job.args[1] == "add" or job.args[1] == "remove", "Invalid action")
|
|
ya.emit("escape", { visual = true })
|
|
|
|
local cands = cands()
|
|
local choice = ya.which { cands = cands }
|
|
if not choice then
|
|
return
|
|
end
|
|
|
|
local t = { job.args[1] == "remove" and "-r" or "-a", cands[choice].desc }
|
|
local files = {}
|
|
for _, url in ipairs(selected_or_hovered()) do
|
|
t[#t + 1] = tostring(url)
|
|
files[#files + 1] = { url = url }
|
|
end
|
|
|
|
local status = Command("tag"):arg(t):status()
|
|
if status.success then
|
|
fetch(self, { files = files })
|
|
end
|
|
end
|
|
|
|
return { setup = setup, fetch = fetch, entry = entry }
|