noctalia-plugin: captures as streams (no 5 s timeout), valw's error message in notifications, full state on every --set
This commit is contained in:
1 parent
9fa71fd399
commit
619eab9dc9
11 files changed
+234
-81
No files matched your search
+49
-15
@@ -11,38 +11,71 @@ local MODES = {
|
||||
{ id = "zoom", glyph = "zoom-in" },
|
||||
}
|
||||
local OPTIONS = { "cursor", "preview", "sound" }
|
||||
local KEYS = { "mode", "timer", "cursor", "preview", "sound" }
|
||||
|
||||
-- The decoded `--state` JSON; nil until it arrives.
|
||||
local state = nil
|
||||
local unavailable = false
|
||||
|
||||
local function lastLine(text)
|
||||
local last = ""
|
||||
for line in string.gmatch(text or "", "[^\n]+") do
|
||||
last = line
|
||||
-- valw's stderr on an error starts with "error: <message>", then cause,
|
||||
-- hint and log lines.
|
||||
local function errorMessage(lines)
|
||||
for _, line in ipairs(lines) do
|
||||
local message = string.match(line, "^error: (.+)$")
|
||||
if message then
|
||||
return message
|
||||
end
|
||||
end
|
||||
return last
|
||||
return noctalia.tr("error.failed")
|
||||
end
|
||||
|
||||
local function linesOf(text)
|
||||
local lines = {}
|
||||
for line in string.gmatch(text or "", "[^\n]+") do
|
||||
table.insert(lines, line)
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
-- Exit 3 is a cancel (Esc): not an error.
|
||||
local function report(result)
|
||||
if result.exitCode ~= 0 and result.exitCode ~= 3 then
|
||||
noctalia.notifyError("valw", lastLine(result.stderr))
|
||||
noctalia.notifyError("valw", errorMessage(linesOf(result.stderr)))
|
||||
end
|
||||
end
|
||||
|
||||
-- A capture lasts as long as the user takes (a region, a zoom, the timer),
|
||||
-- so it runs as a stream: runAsync with a callback kills its command after
|
||||
-- 5 s. stderr joins the stream and the exit status comes last.
|
||||
local function capture(command)
|
||||
local lines = {}
|
||||
local started = noctalia.runStream("(" .. command .. ") 2>&1; echo valw-exit:$?", function(line)
|
||||
local code = string.match(line, "^valw%-exit:(%d+)$")
|
||||
if code == nil then
|
||||
table.insert(lines, line)
|
||||
elseif code ~= "0" and code ~= "3" then
|
||||
noctalia.notifyError("valw", errorMessage(lines))
|
||||
end
|
||||
end)
|
||||
if not started then
|
||||
noctalia.notifyError("valw", noctalia.tr("error.failed"))
|
||||
end
|
||||
end
|
||||
|
||||
local render
|
||||
|
||||
local function capture(mode)
|
||||
panel.close()
|
||||
noctalia.runAsync("sleep 0.3 && valw toolbar --run " .. mode, report)
|
||||
end
|
||||
|
||||
-- `key` and `value` are always one of our own tokens, never user text.
|
||||
-- Every choice goes with every --set, not just the changed one: each
|
||||
-- --set loads, changes and saves the file, so two quick changes sending
|
||||
-- one key each could undo each other. The values are valw's own tokens
|
||||
-- (from --state or our lists), never user text.
|
||||
local function remember(key, value)
|
||||
state[key] = value
|
||||
render()
|
||||
noctalia.runAsync("valw toolbar --set " .. key .. "=" .. tostring(value), report)
|
||||
local sets = {}
|
||||
for _, k in ipairs(KEYS) do
|
||||
table.insert(sets, "--set " .. k .. "=" .. tostring(state[k]))
|
||||
end
|
||||
noctalia.runAsync("valw toolbar " .. table.concat(sets, " "), report)
|
||||
end
|
||||
|
||||
local function modeButton(m)
|
||||
@@ -51,7 +84,8 @@ local function modeButton(m)
|
||||
glyph = m.glyph,
|
||||
variant = if state.mode == m.id then "primary" else "outline",
|
||||
onClick = function()
|
||||
capture(m.id)
|
||||
panel.close()
|
||||
capture("sleep 0.3 && valw toolbar --run " .. m.id)
|
||||
end,
|
||||
})
|
||||
end
|
||||
@@ -123,7 +157,7 @@ function onOpen(_context)
|
||||
end
|
||||
noctalia.runAsync("valw toolbar --state", function(result)
|
||||
if result.exitCode ~= 0 then
|
||||
fail(lastLine(result.stderr))
|
||||
fail(errorMessage(linesOf(result.stderr)))
|
||||
return
|
||||
end
|
||||
local decoded = noctalia.json.decode(result.stdout)
|
||||
|
||||
Reference in new issue
Block a user