From 90b678a617523f528e21ad5a944f63885cac0814 Mon Sep 17 00:00:00 2001 From: Chris Pecunies Date: Wed, 4 Dec 2024 15:32:17 -0800 Subject: [PATCH] updating todos, updating data todo, removing base todo mod --- TODO.md | 1 + lua/word/mod/data/init.lua | 6 +- lua/word/mod/data/metadata/init.lua | 14 +- lua/word/mod/data/todo/init.lua | 75 +++------ lua/word/mod/edit/todo/README.md | 1 + lua/word/mod/todo/init.lua | 251 ---------------------------- 6 files changed, 40 insertions(+), 308 deletions(-) delete mode 100644 lua/word/mod/todo/init.lua diff --git a/TODO.md b/TODO.md index 0b3442d..ef19911 100644 --- a/TODO.md +++ b/TODO.md @@ -22,6 +22,7 @@ - [ ] (easy) Remove all lingering instances of `[module].data.data` and merge into `[module].data` - [ ] (easy) Consider another separation of tables and functions of a module - [ ] (easy) Fix `ui.calendar` for `note` module +- [ ] (easy) Fix mod popup window buffer close error ## Low priority diff --git a/lua/word/mod/data/init.lua b/lua/word/mod/data/init.lua index 06daa4b..ce89f82 100644 --- a/lua/word/mod/data/init.lua +++ b/lua/word/mod/data/init.lua @@ -1,3 +1,7 @@ +---brief TODO: refactor mod/schema of modules so submodules can +--- load on `data` load also require the data module +--- for generic function, maybe implement in separate +--- util.lua file that is required for submodules local M = require("word.mod").create("data", { "log", "mod", @@ -8,6 +12,7 @@ local M = require("word.mod").create("data", { "media", "template", "metadata", + "todo", "save", -- "code", }) @@ -23,7 +28,6 @@ M.setup = function() end M.config.public = { - -- Full path to store data (saved in mpack data format) path = vim.fn.stdpath("data") .. "/word.mpack", } diff --git a/lua/word/mod/data/metadata/init.lua b/lua/word/mod/data/metadata/init.lua index afe8a72..e0f6334 100644 --- a/lua/word/mod/data/metadata/init.lua +++ b/lua/word/mod/data/metadata/init.lua @@ -1,4 +1,6 @@ -local M = Mod.create("data.metadata") +local mod = require("word.mod") + +local M = mod.create("data.metadata") M.setup = function() return { @@ -10,12 +12,13 @@ M.setup = function() } end +---@class word.data.metadata.Config M.config.public = { fields = {}, } M.load = function() - Mod.await("cmd", function(cmd) + mod.await("cmd", function(cmd) cmd.add_commands_from_table({ meta = { subcommands = { @@ -38,10 +41,7 @@ M.load = function() end) end -M.config.public = {} - -M.data.data = {} - +---@class word.data.metadata.Data M.data = { buf_inject_frontmatter = function() local id = "" @@ -68,6 +68,6 @@ M.events.subscribed = { }, } -M.on_event = function(e) end +M.on_event = function() end return M diff --git a/lua/word/mod/data/todo/init.lua b/lua/word/mod/data/todo/init.lua index eb5b252..2feb952 100644 --- a/lua/word/mod/data/todo/init.lua +++ b/lua/word/mod/data/todo/init.lua @@ -1,29 +1,23 @@ -local word = require("word") +local mod, map = require("word.mod"), require("word.util.maps") -local M = Mod.create("data.todo") +local M = mod.create("data.todo") M.maps = function() - Map.nmap(",wt", "Telescope word todo") + map.nmap(",wt", "Telescope word todo") end +---@class word.data.todo.Data M.data = { - data = { - namespace = vim.api.nvim_create_namespace("word/todo"), + namespace = vim.api.nvim_create_namespace("word.data.todo"), - --- List of active buffers - buffers = {}, - }, + --- List of active buffers + buffers = {}, } ----@class base.todo +---@class word.data.todo.Config M.config.public = { - -- Highlight group to display introspector in. - -- - -- base to "Normal". highlight_group = "Normal", - -- - -- base to the following: `done`, `pending`, `undone`, `urgent`. counted_statuses = { "done", "pending", @@ -31,29 +25,17 @@ M.config.public = { "urgent", }, - -- Which status should count towards the completed count (should be a subset of counted_statuses). - -- - -- base to the following: `done`. completed_statuses = { "done", }, - -- Callback to format introspector. Takes in two parameters: - -- * `completed`: number of completed tasks - -- * `total`: number of total counted tasks - -- - -- Should return a string with the format you want to display the introspector in. - -- - -- base to "[completed/total] (progress%)" format = function(completed, total) - -- stylua: ignore start return string.format( "[%d/%d] (%d%%)", completed, total, (total ~= 0 and math.floor((completed / total) * 100) or 0) ) - -- stylua: ignore end end, } @@ -71,11 +53,11 @@ M.load = function() callback = function(ev) local buf = ev.buf - if M.data.data.buffers[buf] then + if M.data.buffers[buf] then return end - M.data.data.buffers[buf] = true + M.data.buffers[buf] = true -- M.public.attach_introspector(buf) -- TODO end, }) @@ -86,8 +68,8 @@ end ---@param buffer number #The buffer ID to attach to. function M.data.attach_introspector(buffer) if - not vim.api.nvim_buf_is_valid(buffer) - or vim.bo[buffer].filetype ~= "markdown" + not vim.api.nvim_buf_is_valid(buffer) + or vim.bo[buffer].filetype ~= "markdown" then error( string.format( @@ -122,7 +104,7 @@ function M.data.attach_introspector(buffer) ---@type TSNode? local node = - M.required["integration.treesitter"].get_first_node_on_line(buf, first) + M.required["integration.treesitter"].get_first_node_on_line(buf, first) if not node then return @@ -130,7 +112,7 @@ function M.data.attach_introspector(buffer) vim.api.nvim_buf_clear_namespace( buffer, - M.data.data.namespace, + M.data.namespace, first + 1, first + 1 ) @@ -153,16 +135,16 @@ function M.data.attach_introspector(buffer) introspect(node) local node_above = - M.required["integration.treesitter"].get_first_node_on_line( - buf, - first - 1 - ) + M.required["integration.treesitter"].get_first_node_on_line( + buf, + first - 1 + ) do local todo_status = node_above:named_child(1) if - todo_status and todo_status:type() == "detached_modifier_extension" + todo_status and todo_status:type() == "detached_modifier_extension" then introspect(node_above) end @@ -170,8 +152,8 @@ function M.data.attach_introspector(buffer) end), on_detach = function() - vim.api.nvim_buf_clear_namespace(buffer, M.data.data.namespace, 0, -1) - M.data.data.buffers[buffer] = nil + vim.api.nvim_buf_clear_namespace(buffer, M.data.namespace, 0, -1) + M.data.buffers[buffer] = nil end, }) end @@ -191,8 +173,8 @@ function M.data.calculate_items(node) -- Go through all the children of the current todo item node and count the amount of "done" children for child in node:iter_children() do if - child:named_child(1) - and child:named_child(1):type() == "detached_modifier_extension" + child:named_child(1) + and child:named_child(1):type() == "detached_modifier_extension" then for status in child:named_child(1):iter_children() do if status:type():match("^todo_item_") then @@ -227,18 +209,13 @@ function M.data.perform_introspection(buffer, node) local line, col = node:start() - vim.api.nvim_buf_clear_namespace( - buffer, - M.data.data.namespace, - line, - line + 1 - ) + vim.api.nvim_buf_clear_namespace(buffer, M.data.namespace, line, line + 1) if total == 0 then return end - vim.api.nvim_buf_set_extmark(buffer, M.data.data.namespace, line, col, { + vim.api.nvim_buf_set_extmark(buffer, M.data.namespace, line, col, { virt_text = { { M.config.public.format(completed, total), @@ -249,4 +226,4 @@ function M.data.perform_introspection(buffer, node) }) end -return init +return M diff --git a/lua/word/mod/edit/todo/README.md b/lua/word/mod/edit/todo/README.md index e69de29..d68b491 100644 --- a/lua/word/mod/edit/todo/README.md +++ b/lua/word/mod/edit/todo/README.md @@ -0,0 +1 @@ +# `edit.todo` diff --git a/lua/word/mod/todo/init.lua b/lua/word/mod/todo/init.lua deleted file mode 100644 index 74c11ee..0000000 --- a/lua/word/mod/todo/init.lua +++ /dev/null @@ -1,251 +0,0 @@ -local word = require("word") - -local M = Mod.create("todo") - -M.maps = function() - Map.nmap(",wt", "Telescope word todo") -end - -M.data = { - data = { - namespace = vim.api.nvim_create_namespace("word/todo"), - - --- List of active buffers - buffers = {}, - }, -} ----@class base.todo -M.config.public = { - - -- Highlight group to display introspector in. - -- - -- base to "Normal". - highlight_group = "Normal", - - -- - -- base to the following: `done`, `pending`, `undone`, `urgent`. - counted_statuses = { - "done", - "pending", - "undone", - "urgent", - }, - - -- Which status should count towards the completed count (should be a subset of counted_statuses). - -- - -- base to the following: `done`. - completed_statuses = { - "done", - }, - - -- Callback to format introspector. Takes in two parameters: - -- * `completed`: number of completed tasks - -- * `total`: number of total counted tasks - -- - -- Should return a string with the format you want to display the introspector in. - -- - -- base to "[completed/total] (progress%)" - format = function(completed, total) - -- stylua: ignore start - return string.format( - "[%d/%d] (%d%%)", - completed, - total, - (total ~= 0 and math.floor((completed / total) * 100) or 0) - ) - -- stylua: ignore end - end, -} -M.setup = function() - return { - loaded = true, - requires = { "integration.treesitter" }, - } -end - -M.load = function() - vim.api.nvim_create_autocmd("Filetype", { - pattern = "markdown", - desc = "Attaches the TODO introspector to any word buffer.", - callback = function(ev) - local buf = ev.buf - - if M.data.data.buffers[buf] then - return - end - - M.data.data.buffers[buf] = true - -- M.public.attach_introspector(buf) -- TODO - end, - }) -end - ---- Attaches the introspector to a given word buffer. ---- Errors if the target buffer is not a word buffer. ----@param buffer number #The buffer ID to attach to. -function M.data.attach_introspector(buffer) - if - not vim.api.nvim_buf_is_valid(buffer) - or vim.bo[buffer].filetype ~= "markdown" - then - error( - string.format( - "Could not attach to buffer %d, buffer is not a word file!", - buffer - ) - ) - end - - M.required["integration.treesitter"].execute_query( - [[ - (_ - state: (detached_modifier_extension)) @item - ]], - function(query, id, node) - if query.captures[id] == "item" then - M.data.perform_introspection(buffer, node) - end - end, - buffer - ) - - vim.api.nvim_buf_attach(buffer, false, { - on_lines = vim.schedule_wrap(function(_, buf, _, first) - if not vim.api.nvim_buf_is_valid(buf) then - return - end - -- If we delete the last line of a file `first` will point to a nonexistent line - -- For this reason we fall back to the line count (accounting for 0-based indexing) - -- whenever a change to the document is made. - first = math.min(first, vim.api.nvim_buf_line_count(buf) - 1) - - ---@type TSNode? - local node = - M.required["integration.treesitter"].get_first_node_on_line(buf, first) - - if not node then - return - end - - vim.api.nvim_buf_clear_namespace( - buffer, - M.data.data.namespace, - first + 1, - first + 1 - ) - - local function introspect(start_node) - local parent = start_node - - while parent do - local child = parent:named_child(1) - - if child and child:type() == "detached_modifier_extension" then - M.data.perform_introspection(buffer, parent) - -- NOTE: do not break here as we want the introspection to propagate all the way up the syntax tree - end - - parent = parent:parent() - end - end - - introspect(node) - - local node_above = - M.required["integration.treesitter"].get_first_node_on_line( - buf, - first - 1 - ) - - do - local todo_status = node_above:named_child(1) - - if - todo_status and todo_status:type() == "detached_modifier_extension" - then - introspect(node_above) - end - end - end), - - on_detach = function() - vim.api.nvim_buf_clear_namespace(buffer, M.data.data.namespace, 0, -1) - M.data.data.buffers[buffer] = nil - end, - }) -end - ---- Aggregates TODO item counts from children. ----@param node TSNode ----@return number completed Total number of completed tasks ----@return number total Total number of counted tasks -function M.data.calculate_items(node) - local counts = {} - for _, status in ipairs(M.config.public.counted_statuses) do - counts[status] = 0 - end - - local total = 0 - - -- Go through all the children of the current todo item node and count the amount of "done" children - for child in node:iter_children() do - if - child:named_child(1) - and child:named_child(1):type() == "detached_modifier_extension" - then - for status in child:named_child(1):iter_children() do - if status:type():match("^todo_item_") then - local type = status:type():match("^todo_item_(.+)$") - - if not counts[type] then - break - end - - counts[type] = counts[type] + 1 - total = total + 1 - end - end - end - end - - local completed = 0 - for _, status in ipairs(M.config.public.completed_statuses) do - if counts[status] then - completed = completed + counts[status] - end - end - - return completed, total -end - ---- Displays the amount of done items in the form of an extmark. ----@param buffer number ----@param node TSNode -function M.data.perform_introspection(buffer, node) - local completed, total = M.data.calculate_items(node) - - local line, col = node:start() - - vim.api.nvim_buf_clear_namespace( - buffer, - M.data.data.namespace, - line, - line + 1 - ) - - if total == 0 then - return - end - - vim.api.nvim_buf_set_extmark(buffer, M.data.data.namespace, line, col, { - virt_text = { - { - M.config.public.format(completed, total), - M.config.public.highlight_group, - }, - }, - invalidate = true, - }) -end - -return init