1 files changed,
33 insertions(+),
53 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2025-09-15 23:30:41 +0300
Parent:
86d8e84
M
lua/scratch/tasks.lua
@@ -16,11 +16,7 @@ local f = io.open(config.tasks_file, "r")
if not f then error("cannot read " .. config.tasks_file) end - return vim.json.decode(f:read "*a")["files"] -end - -local function get_done_label() - return os.date(config.label) --[[@as string]] + return vim.json.decode(f:read "*a")["files"] or error "'files' is not found" end ---@param str string@@ -30,7 +26,7 @@ end
---@param str string local function is_task_labled(str) - return str:match "^%s*%- %[[x ]%] `%" ~= nil + return str:match "^%s*%- %[[x ]%] `" ~= nil end ---@param str string@@ -39,7 +35,7 @@ return str:match "%#next" ~= nil
end ---@param str string -local function check_task_status(str) +local function is_task_complete(str) return str:match "^(%s*%- )%[x%]" ~= nil end@@ -61,18 +57,17 @@ local res = str:gsub(" %#next", "")
return res end --- converts a like with markdown task to completed task, and removes `#next` in it, if there's one ---@param str string local function to_complete_task(str) - local label = get_done_label() - local task_prefix = str:match "^(%s*%- %[[x ]%])" if not task_prefix then return nil end + local label = os.date(config.label) --[[@as string]] str = task_prefix .. " `" .. label .. "`" .. str:sub(#task_prefix + 1) str = str:gsub("^(%s*%- )%[%s*%]", "%1[x]") + str = remove_note_link(str) str = remove_next_tag(str) str = str:gsub("%s+$", "") return str@@ -81,51 +76,38 @@
---@param lines string[] ---@return number? - Line of the heading, nil if not found local function find_archive_heading(lines) - local heading_line = nil - for i, line in ipairs(lines) do - if line:match("^%s*" .. config.archive_header) then - heading_line = i - break - end - end - return heading_line + return vim.iter(ipairs(lines)):find(function(lnum, line) + return line:match("^%s*" .. config.archive_header) ~= nil and lnum + end) end local tasks = {} function tasks.agenda() - -- parse all `task_files` for `#next` tag - ---@type table<string, {text: string, line: number}[]> - local agenda_tasks = {} - for _, fname in ipairs(get_tasks_files()) do - local lines = vim.fn.readfile(fname) - for i, line in ipairs(lines) do - if is_task(line) and has_next_tag(line) then - agenda_tasks[fname] = agenda_tasks[fname] or {} - table.insert(agenda_tasks[fname], { - text = line, - line = i, - }) - end - end - end - - -- build the output - local output = {} - for fname, ftasks in pairs(agenda_tasks) do - for _, ftask in pairs(ftasks) do - local task = remove_next_tag(ftask.text) - task = remove_task_prefix(task) - task = remove_note_link(task) + local qf_output = vim + .iter(get_tasks_files()) + :map(function(fname) + return vim + .iter(ipairs(vim.fn.readfile(fname))) + :filter(function(_, line) + return is_task(line) and has_next_tag(line) + end) + :map(function(lnum, line) + local task = remove_next_tag(line) + task = remove_task_prefix(task) + task = remove_note_link(task) - table.insert(output, { - lnum = ftask.line, - filename = fname, - text = task, - }--[[ @as vim.quickfix.entry ]]) - end - end + return { + lnum = lnum, + filename = fname, + text = task, + } --[[@as vim.quickfix.entry]] + end) + :totable() + end) + :flatten() + :totable() - vim.fn.setqflist(output, "r") + vim.fn.setqflist(qf_output, "r") vim.cmd.copen() end@@ -136,11 +118,11 @@ local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
local task = lines[task_idx] if not is_task(task) then - vim.notify("Not a task", vim.log.levels.WARN) + vim.notify("Not a task", vim.log.levels.ERROR) return end - if check_task_status(task) and is_task_labled(task) then + if is_task_complete(task) and is_task_labled(task) then vim.notify("Task already completed", vim.log.levels.ERROR) return end@@ -149,8 +131,6 @@ local archived_heading = find_archive_heading(lines)
if archived_heading == nil then table.insert(lines, "") table.insert(lines, config.archive_header) - vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, lines) - archived_heading = #lines end