Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(summary) - replace existing summary, use a ranged tag #976

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 78 additions & 20 deletions lua/neorg/modules/core/summary/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,19 @@ module.load = function()
end
end)
local result = {}
local prefix = string.rep("*", heading_level)
local prefix = string.rep(" ", heading_level)

for category, data in vim.spairs(categories) do
table.insert(result, prefix .. " " .. category)

table.insert(result, prefix .. "#category " .. category)
for _, datapoint in ipairs(data) do
table.insert(
result,
-- TODO each line _SHOULD BE_ a list item,
-- but due to an apparent bug, treesitter currently barfs on list items (or headings) inside a ranged tag.
-- :InspectTree shows an "ERROR" instead of the ranged_tag node.
table.concat({
" - {:$",
prefix,
"_ {:$",
datapoint.norgname,
":}[",
neorg.lib.title(datapoint.title),
Expand Down Expand Up @@ -163,21 +166,69 @@ module.events.subscribed = {
},
}

module.private = {
find_existing_summary = function(buffer, root)
local query_str = neorg.lib.match("all")({
_ = [[
(ranged_tag
name: (tag_name) @_tag_name
(#eq? @_tag_name "group")
)
]],
})

local query = neorg.utils.ts_parse_query("norg", query_str)
for _, node in query:iter_captures(root, buffer, 0, -1) do
-- node is the tag_name. we need its parent node
local ranged_tag = node:parent()
for child in ranged_tag:iter_children() do
if child:type() == "tag_parameters" then
local param = child:child(0)
if param ~= nil then
--for param in child:iter_children() do
local text = module.required["core.integrations.treesitter"].get_node_text(param)
if text == "summary" then
return ranged_tag
end
end
end
end
end
return nil
end,
}

module.on_event = function(event)
if event.type == "core.neorgcmd.events.summary.summarize" then
local ts = module.required["core.integrations.treesitter"]
local buffer = event.buffer

local node_at_cursor = ts.get_first_node_on_line(buffer, event.cursor_position[1] - 1)

if not node_at_cursor or not node_at_cursor:type():match("^heading%d$") then
neorg.utils.notify(
"No heading under cursor! Please move your cursor under the heading you'd like to generate the summary under."
)
return
local start_line = event.cursor_position[1]
local end_line = start_line
local existing = module.private.find_existing_summary(buffer, ts.get_document_root(buffer))
local heading_level = 0
if existing ~= nil then
start_line, _ = existing:start()
end_line, _ = existing:end_()
end_line = end_line + 1
local level = tonumber(string.sub(existing:type(), -1))
if level ~= nil then
heading_level = level
end
else
local node_at_cursor = ts.get_first_node_on_line(buffer, event.cursor_position[1] - 1)
if not node_at_cursor or not node_at_cursor:type():match("^heading%d$") then
neorg.utils.notify(
"No heading under cursor! Please move your cursor under the heading you'd like to generate the summary under."
)
return
end
-- heading level of 'node_at_cursor' (summary headings should be one level deeper)
local level = tonumber(string.sub(node_at_cursor:type(), -1))
if level ~= nil then
heading_level = level
end
end
-- heading level of 'node_at_cursor' (summary headings should be one level deeper)
local level = tonumber(string.sub(node_at_cursor:type(), -1))

local dirman = neorg.modules.get_module("core.dirman")

Expand All @@ -186,21 +237,28 @@ module.on_event = function(event)
return
end

local ws_root = dirman.get_current_workspace()[2]
local generated = module.config.public.strategy(
dirman.get_norg_files(dirman.get_current_workspace()[1]) or {},
ws_root,
level + 1
)
local current_workspace = dirman.get_current_workspace()
local ws_name = current_workspace[1]
local ws_root = current_workspace[2]
local generated =
module.config.public.strategy(dirman.get_norg_files(ws_name) or {}, ws_root, heading_level + 2)

if not generated or vim.tbl_isempty(generated) then
neorg.utils.notify(
"No summary to generate! Either change the `strategy` option or ensure you have some indexable files in your workspace."
)
return
end
-- use a tag to contain the result
local content = {
string.rep(" ", heading_level) .. "|group summary " .. ws_name,
}
for _, gen in ipairs(generated) do
table.insert(content, gen)
end
table.insert(content, string.rep(" ", heading_level) .. "|end")

vim.api.nvim_buf_set_lines(buffer, event.cursor_position[1], event.cursor_position[1], true, generated)
vim.api.nvim_buf_set_lines(buffer, start_line, end_line, true, content)
end
end

Expand Down