Skip to content

Commit

Permalink
fix(toc): store offset data, put data together
Browse files Browse the repository at this point in the history
  • Loading branch information
champignoom committed Dec 13, 2023
1 parent 3e882df commit e058c31
Showing 1 changed file with 32 additions and 21 deletions.
53 changes: 32 additions & 21 deletions lua/neorg/modules/core/qol/toc/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ module.config.public = {
sync_cursorline = true,
}

local start_lines_of_toc_buf = {}
local last_row_of_norg_win = {}
local extmarks_of_norg_win = {}
local data_of_ui_buf = {}
local data_of_norg_win = {}
local toc_namespace

local function upper_bound(array, v)
-- assume array is sorted
Expand All @@ -85,17 +85,19 @@ local function upper_bound(array, v)
return l
end

local function get_target_location_under_cursor(ui_window, original_buffer, original_window)
local function get_target_location_under_cursor(ui_buffer, ui_window, original_buffer, original_window)
assert(ui_window == vim.fn.bufwinid(ui_buffer))
assert(original_window == vim.fn.bufwinid(original_buffer))

local curline = vim.api.nvim_win_get_cursor(ui_window)[1]
local extmark_lookup = extmarks_of_norg_win[original_window][curline - offset]
local offset = data_of_ui_buf[ui_buffer].offset
local extmark_lookup = data_of_norg_win[original_window].extmarks[curline - offset]

if not extmark_lookup then
return
end

return vim.api.nvim_buf_get_extmark_by_id(original_buffer, namespace, extmark_lookup, {})
return vim.api.nvim_buf_get_extmark_by_id(original_buffer, toc_namespace, extmark_lookup, {})
end

module.public = {
Expand Down Expand Up @@ -187,12 +189,12 @@ module.public = {

update_cursor = function(_original_buffer, original_window, ui_buffer, ui_window)
local current_row_1b = vim.fn.line(".", original_window)
if last_row_of_norg_win[original_window] == current_row_1b then
if data_of_norg_win[original_window].last_row == current_row_1b then
return
end
last_row_of_norg_win[original_window] = current_row_1b
data_of_norg_win[original_window].last_row = current_row_1b

local start_lines = start_lines_of_toc_buf[ui_buffer]
local start_lines = data_of_ui_buf[ui_buffer].start_lines
assert(start_lines)

local current_toc_item_idx = upper_bound(start_lines, current_row_1b - 1) - 1
Expand All @@ -203,18 +205,27 @@ module.public = {
vim.api.nvim_win_set_cursor(ui_window, { current_toc_row, 0 })
end,

update_toc = function(namespace, toc_title, original_buffer, original_window, ui_buffer, ui_window)
vim.api.nvim_buf_clear_namespace(original_buffer, namespace, 0, -1)
update_toc = function(toc_title, original_buffer, original_window, ui_buffer, ui_window)
vim.api.nvim_buf_clear_namespace(original_buffer, toc_namespace, 0, -1)

table.insert(toc_title, "")
vim.api.nvim_buf_set_lines(ui_buffer, 0, -1, true, toc_title)
local ui_buf_data = {}
data_of_ui_buf[ui_buffer] = ui_buf_data

local norg_win_data = {}
data_of_norg_win[original_window] = norg_win_data

local offset = vim.api.nvim_buf_line_count(ui_buffer)
ui_buf_data.offset = offset

local prefix, title
local extmarks = {}
norg_win_data.extmarks = extmarks

local start_lines = { offset = offset }
extmarks_of_norg_win[original_window] = extmarks
start_lines_of_toc_buf[ui_buffer] = start_lines
ui_buf_data.start_lines = start_lines

local toc_filter = module.config.public.toc_filter

local success = module.required["core.integrations.treesitter"].execute_query(
Expand Down Expand Up @@ -249,7 +260,7 @@ module.public = {

table.insert(
extmarks,
vim.api.nvim_buf_set_extmark(original_buffer, namespace, (prefix:start()), column, {})
vim.api.nvim_buf_set_extmark(original_buffer, toc_namespace, (prefix:start()), column, {})
)

table.insert(start_lines, (prefix:start()))
Expand Down Expand Up @@ -283,7 +294,7 @@ module.public = {

vim.api.nvim_buf_set_keymap(ui_buffer, "n", "<CR>", "", {
callback = function()
local location = get_target_location_under_cursor(ui_window, original_buffer, original_window)
local location = get_target_location_under_cursor(ui_buffer, ui_window, original_buffer, original_window)
if not location then
return
end
Expand Down Expand Up @@ -344,7 +355,7 @@ module.on_event = function(event)

-- FIXME(vhyrro): When the buffer already exists then simply refresh the buffer
-- instead of erroring out.
local namespace = vim.api.nvim_create_namespace("neorg/toc")
toc_namespace = toc_namespace or vim.api.nvim_create_namespace("neorg/toc")
local buffer, window =
module.required["core.ui"].create_vsplit("toc", { ft = "norg" }, (event.content[1] or "left") == "left")

Expand All @@ -354,7 +365,7 @@ module.on_event = function(event)
vim.api.nvim_win_set_option(window, "cursorline", true)
end

module.public.update_toc(namespace, toc_title, event.buffer, event.window, buffer, window)
module.public.update_toc(toc_title, event.buffer, event.window, buffer, window)
if module.config.public.sync_cursorline then
module.public.update_cursor(event.buffer, event.window, buffer, window)
end
Expand Down Expand Up @@ -391,9 +402,9 @@ module.on_event = function(event)
pattern = "*.norg",
callback = unlisten_if_closed(buffer, function(_ev)
toc_title = vim.split(module.public.parse_toc_macro(previous_buffer) or "Table of Contents", "\n")
module.public.update_toc(namespace, toc_title, previous_buffer, previous_window, buffer, window)
module.public.update_toc(toc_title, previous_buffer, previous_window, buffer, window)
if module.config.public.sync_cursorline then
last_row_of_norg_win[previous_window] = nil -- invalidate cursor cache
data_of_norg_win[previous_window].last_row = nil -- invalidate cursor cache
module.public.update_cursor(previous_buffer, previous_window, buffer, window)
end
end),
Expand All @@ -411,7 +422,7 @@ module.on_event = function(event)
previous_buffer, previous_window = buf, vim.api.nvim_get_current_win()

toc_title = vim.split(module.public.parse_toc_macro(buf) or "Table of Contents", "\n")
module.public.update_toc(namespace, toc_title, buf, previous_window, buffer, window)
module.public.update_toc(toc_title, buf, previous_window, buffer, window)
if module.config.public.sync_cursorline then
module.public.update_cursor(previous_buffer, previous_window, buffer, window)
end
Expand All @@ -429,7 +440,7 @@ module.on_event = function(event)

-- Ignore the first (fake) CursorMoved coming together with BufEnter of the ToC buffer
if ui_cursor_start_moving then
local location = get_target_location_under_cursor(window, previous_buffer, previous_window)
local location = get_target_location_under_cursor(buffer, window, previous_buffer, previous_window)
if location then
vim.api.nvim_win_set_cursor(previous_window, { location[1] + 1, location[2] })
vim.api.nvim_set_current_win(previous_window)
Expand Down

0 comments on commit e058c31

Please sign in to comment.