Skip to content

Commit

Permalink
Merge pull request #275 from nvim-neorg/gtd-performance
Browse files Browse the repository at this point in the history
Gtd performance
  • Loading branch information
danymat authored Dec 28, 2021
2 parents 66e0628 + 397ba7b commit f9f0538
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 16 deletions.
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
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

0 comments on commit f9f0538

Please sign in to comment.