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

Gtd performance #275

Merged
merged 10 commits into from
Dec 28, 2021
17 changes: 10 additions & 7 deletions lua/neorg/modules/core/gtd/queries/creators.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ module.public = {
module.private.insert_tag({ node.node, bufnr }, node["waiting.for"], syntax.waiting)

if not opts.no_save then
vim.api.nvim_buf_call(bufnr, function()
vim.cmd([[ write! ]])
end)
module.required["core.queries.native"].apply_temp_changes(bufnr)
end
end,

Expand Down Expand Up @@ -133,7 +131,8 @@ module.public = {

-- There is no content in the document
if not document then
end_row = vim.api.nvim_buf_line_count(bufnr)
local temp_buf = module.required["core.queries.native"].get_temp_buf(bufnr)
end_row = vim.api.nvim_buf_line_count(temp_buf)
else
-- Check if last child is a project
local nb_childs = document[1]:child_count()
Expand Down Expand Up @@ -190,7 +189,8 @@ module.private = {
local indendation = string.rep(" ", location[2])
table.insert(inserter, indendation .. prefix .. content)

vim.api.nvim_buf_set_lines(bufnr, location[1], location[1], false, inserter)
local temp_buf = module.required["core.queries.native"].get_temp_buf(bufnr)
vim.api.nvim_buf_set_lines(temp_buf, location[1], location[1], false, inserter)

-- Get all nodes for `type` and return the one that is present at `location`
local nodes = module.public.get(type .. "s", { bufnr = bufnr })
Expand Down Expand Up @@ -237,20 +237,23 @@ module.private = {

local parent_tag_set = module.required["core.queries.native"].find_parent_node(node, "carryover_tag_set")

local queries = module.required["core.queries.native"]
local temp_buf = queries.get_temp_buf(node[2])

if #parent_tag_set == 0 then
-- No tag created, i will insert the tag just before the node or at specific line
if opts.line then
node_line = opts.line
end
vim.api.nvim_buf_set_lines(node[2], node_line, node_line, false, inserter)
vim.api.nvim_buf_set_lines(temp_buf, node_line, node_line, false, inserter)
return true
else
-- Gets the last tag in the found tag_set and append after it
local tags_number = parent_tag_set[1]:child_count()
local last_tag = parent_tag_set[1]:child(tags_number - 1)
local start_row, _, _, _ = ts_utils.get_node_range(last_tag)

vim.api.nvim_buf_set_lines(node[2], start_row, start_row, false, inserter)
vim.api.nvim_buf_set_lines(temp_buf, start_row, start_row, false, inserter)
return true
end
end,
Expand Down
6 changes: 4 additions & 2 deletions lua/neorg/modules/core/gtd/queries/modifiers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ module.public = {
end

-- Replacing old option with new one (The empty string is to prevent lines below to wrap)
vim.api.nvim_buf_set_text(object.bufnr, start_row, start_col, end_row, end_col, { value, "" })
local temp_buf = module.required["core.queries.native"].get_temp_buf(object.bufnr)
vim.api.nvim_buf_set_text(temp_buf, start_row, start_col, end_row, end_col, { value, "" })

return module.public.update(object, node_type)
end,
Expand Down Expand Up @@ -123,7 +124,8 @@ module.public = {
local start_row, start_col, end_row, end_col = ts_utils.get_node_range(fetched_node)

-- Deleting object
vim.api.nvim_buf_set_text(object.bufnr, start_row, start_col, end_row, end_col, { "" })
local temp_buf = module.required["core.queries.native"].get_temp_buf(object.bufnr)
vim.api.nvim_buf_set_text(temp_buf, start_row, start_col, end_row, end_col, { "" })

return module.public.update(object, node_type), start_row
end,
Expand Down
4 changes: 3 additions & 1 deletion lua/neorg/modules/core/gtd/queries/retrievers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ module.public = {
end

for _, bufnr in pairs(bufnrs) do
local nodes = module.required["core.queries.native"].query_nodes_from_buf(tree, bufnr)
---@type core.queries.native
local queries = module.required["core.queries.native"]
local nodes = queries.query_nodes_from_buf(tree, bufnr)
vim.list_extend(res, nodes)
end

Expand Down
4 changes: 1 addition & 3 deletions lua/neorg/modules/core/gtd/ui/selection_popups.lua
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,7 @@ module.public = {
end
end

vim.api.nvim_buf_call(task.bufnr, function()
vim.cmd(" write ")
end)
module.required["core.queries.native"].apply_temp_changes(task.bufnr)
end)

module.private.display_messages()
Expand Down
2 changes: 1 addition & 1 deletion lua/neorg/modules/core/keybinds/default_keybinds.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ module.public = {
},
i = {
{ "<C-l>", "core.integrations.telescope.insert_link" },
}
},
}, {
silent = true,
noremap = true,
Expand Down
90 changes: 87 additions & 3 deletions lua/neorg/modules/core/queries/native/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ module.examples = {
local nodes = module.required["core.queries.native"].query_nodes_from_buf(tree, buf)
local extracted_nodes = module.required["core.queries.native"].extract_nodes(nodes)

-- Free the text in memory after reading nodes
module.required["core.queries.native"].reset_data(buf)

print(nodes, extracted_nodes)
end,
}
Expand Down Expand Up @@ -126,7 +129,8 @@ module.public = {
local ts_utils = module.required["core.integrations.treesitter"].get_ts_utils()

for _, node in ipairs(nodes) do
local extracted = ts_utils.get_node_text(node[1], node[2])
local temp_buf = module.public.get_temp_buf(node[2])
local extracted = ts_utils.get_node_text(node[1], temp_buf)

if opts.all_lines then
table.insert(res, extracted)
Expand Down Expand Up @@ -166,14 +170,93 @@ module.public = {
end
return res
end,

--- Creates an unlisted temp buffer reading from the original bufnr.
--- This does prevent triggering norg autocommands
--- @param buf number #The bufnr to get text from
--- @param opts table? #Custom options
--- - opts.no_force_read boolean? #If true, will not read original buffer if it fails to open
--- @return number #The temporary bufnr
get_temp_buf = function(buf, opts)
opts = opts or {}
-- If we don't have any previous private data, get the file text
if not module.private.data.temp_bufs[buf] then
-- Get the file name from bufnr
local uri = vim.uri_from_bufnr(buf)
local fname = vim.uri_to_fname(uri)

-- Open and read all lines in the file
local f, err = io.open(fname, "r")
local lines
if not f then
log.warn("Can't read file " .. fname)
if opts.no_force_read then
log.error(err)
return
end
lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
else
lines = f:read("*a")
lines = vim.split(lines, "\n")
f:close()
end

-- Stores the lines in a temp buffer
local temp_buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(temp_buf, 0, -1, false, lines)
vim.api.nvim_buf_attach(temp_buf, false, {
on_lines = function()
module.private.data.temp_bufs[buf].changed = true
end,
})
module.private.data.temp_bufs[buf] = { buf = temp_buf, changed = false }
end

return module.private.data.temp_bufs[buf].buf
end,

apply_temp_changes = function(buf)
local temp_buf = module.private.data.temp_bufs[buf]
if temp_buf and temp_buf.changed then
-- Write the lines to original file
local lines = vim.api.nvim_buf_get_lines(temp_buf.buf, 0, -1, false)
local uri = vim.uri_from_bufnr(buf)
local fname = vim.uri_to_fname(uri)

neorg.lib.when(vim.fn.bufloaded(buf) == 1, function()
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
vim.api.nvim_buf_call(buf, neorg.lib.wrap(vim.cmd, "write!"))
end, neorg.lib.wrap(vim.fn.writefile, lines, fname))

-- We reset the state as false because we are consistent with the original file
temp_buf.changed = false
end
end,

--- Deletes the content from data.
--- If no buffer is provided, will delete every buffer datas
--- @overload fun()
--- @param buf number #The content relative to the provided buffer
delete_content = function(buf)
neorg.lib.when(buf, function()
module.private.data.temp_bufs[buf] = nil
end, function()
module.private.data.temp_bufs = {}
end)
end,
}

module.private = {
data = {
-- Must be a table of keys like buffer = string_content
temp_bufs = {},
},
--- Get the root node from a `bufnr`
--- @param bufnr number
--- @return userdata
get_buf_root_node = function(bufnr)
local parser = vim.treesitter.get_parser(bufnr, "norg")
local temp_buf = module.public.get_temp_buf(bufnr)
local parser = vim.treesitter.get_parser(temp_buf, "norg")
local tstree = parser:parse()[1]
return tstree:root()
end,
Expand Down Expand Up @@ -307,7 +390,8 @@ With that in mind, you can do something like this (for example):
end

if where[1] == "child_content" then
if node:type() == where[2] and ts_utils.get_node_text(node, opts.bufnr)[1] == where[3] then
local temp_buf = module.public.get_temp_buf(opts.bufnr)
if node:type() == where[2] and ts_utils.get_node_text(node, temp_buf)[1] == where[3] then
return true
end
end
Expand Down