Skip to content

Commit

Permalink
fix(toc): sync cursor position on saving
Browse files Browse the repository at this point in the history
  • Loading branch information
champignoom committed Nov 28, 2023
1 parent 7d15837 commit a7104b0
Showing 1 changed file with 37 additions and 32 deletions.
69 changes: 37 additions & 32 deletions lua/neorg/modules/core/qol/toc/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@ module.config.public = {
local start_lines_of_toc_buf = {}
local last_row_of_norg_win = {}

local function upper_bound(array, v)
-- assume array is sorted
-- find index of first element in array that is > v
local l = 1
local r = #array

while l <= r do
local m = math.floor((l+r)/2)
if v >= array[m] then
l = m + 1
else
r = m - 1
end
end

return l
end

module.public = {
parse_toc_macro = function(buffer)
local toc, toc_name = false, nil
Expand Down Expand Up @@ -153,6 +171,21 @@ module.public = {
return qflist_data
end,

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
return
end
last_row_of_norg_win[original_window] = current_row_1b

local start_lines = start_lines_of_toc_buf[ui_buffer]
assert(start_lines)

local current_toc_item_idx = upper_bound(start_lines, current_row_1b-1) - 1
local current_toc_row = current_toc_item_idx==0 and 1 or current_toc_item_idx + start_lines.offset
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)

Expand Down Expand Up @@ -263,24 +296,6 @@ local function get_max_virtcol()
return result
end

local function upper_bound(array, v)
-- assume array is sorted
-- find index of first element in array that is > v
local l = 1
local r = #array

while l <= r do
local m = math.floor((l+r)/2)
if v >= array[m] then
l = m + 1
else
r = m - 1
end
end

return l
end

module.on_event = function(event)
if event.split_type[2] ~= module.name then
return
Expand Down Expand Up @@ -353,6 +368,8 @@ module.on_event = function(event)

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)
last_row_of_norg_win[previous_window] = nil
module.public.update_cursor(previous_buffer, previous_window, buffer, window)
end,
})

Expand All @@ -373,6 +390,7 @@ module.on_event = function(event)

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_cursor(previous_buffer, previous_window, buffer, window)
end,
})

Expand All @@ -382,24 +400,11 @@ module.on_event = function(event)
buffer = previous_buffer,
callback = function(ev)
assert(ev.buf == previous_buffer)
local content_window = vim.fn.bufwinid(ev.buf)

if not vim.api.nvim_buf_is_valid(buffer) or not vim.api.nvim_buf_is_loaded(buffer) then
return true
end

local current_row_1b = vim.fn.line('.', content_window)
if last_row_of_norg_win[content_window] == current_row_1b then
return
end
last_row_of_norg_win[content_window] = current_row_1b

local start_lines = start_lines_of_toc_buf[buffer]
assert(start_lines)

local current_toc_item_idx = upper_bound(start_lines, current_row_1b-1) - 1
local current_toc_row = current_toc_item_idx==0 and 1 or current_toc_item_idx + start_lines.offset
vim.api.nvim_win_set_cursor(window, { current_toc_row, 0 })
module.public.update_cursor(ev.buf, vim.fn.bufwinid(ev.buf), buffer, window)
end,
})
end
Expand Down

0 comments on commit a7104b0

Please sign in to comment.