I am running on v2 and am wondering if there is some possibility to update attributes via Lua commands?
My current use case is the concept of scheduled tasks, including recurring tasks. As soon as But as soon as I have understood the concept, I am sure that more use cases will pop up
Not the fancy version with emojis and stuff like the one I linked, but I found a solution that is good enough for me.
The main script does the following:
Check if the task was actually finished/ticked; otherwise stop immediately
Get the task text
Check if the finished attribute exists. The main stuff happens only if this returns positive.
Ignore what is set in the finished attribute, and replace it with today’s string.
Interestingly, the text I received seems to be the text before the change. So I repaired it and set the task to “finished” again.
Finally, call editor.replaceRange to replace the task object with the new task object.
Note: Not sure if this is a bug or a feature, but the event does not get triggered if I tick a task from a live query, so in this case, the script does not run.
function attribute_exists(text, attr)
-- Assume that attr == "finished", then
-- the expression searches for:
-- [finished:{anything}]. This "anything" is a
-- bit weird, because it disallows the matching of "]".
local a, b = string.find(text, "%[" .. attr .. ":[^%]]*%]")
return a, b
end
event.listen {
name = "task:stateChange",
run = function(e)
-- Check if the new state indicates "done"
if e.data.newState != "x" then
return
end
-- print("start")
local today = os.date("%Y-%m-%d")
local task_text = e.data.text
-------------------------------------------
-- Set finished attribute
-------------------------------------------
-- Find out if a finished attribute already
-- exists. If so, get it's start and end index
-- in the task text.
local finished_start, finished_end = attribute_exists(
task_text, "finished"
)
if finished_start != nil then
-- finished attribute already exists.
-- Get it's contents.
-- print(finished_start, finished_end)
-- Replace the task text as follows:
-- * Take everything before the (first) `finished` attribute
-- * Replace the `finished` attribute: Set the value to be
-- today's date
-- * Leave everything after the `finished` attribute unchanged
task_text =
string.sub(task_text, 1, finished_start - 1) ..
"[finished: " .. today .. "]" ..
string.sub(task_text, finished_end + 1)
end
-------------------------------------------
-- Cleanup and write data to file
-------------------------------------------
-- The task string is now un-finished. Have to fix that.
task_text = "[x" .. string.sub(task_text, 3)
-- print(task_text)
-- Finally, edit the Silverbullet file.
editor.replaceRange(
e.data.from,
e.data.to,
task_text
)
-- print("end")
end
}