Skip to content

Commit

Permalink
fix(toc): various fixes (#1500)
Browse files Browse the repository at this point in the history
  • Loading branch information
benlubas authored Jul 5, 2024
1 parent 99b3249 commit 83637f1
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 49 deletions.
3 changes: 2 additions & 1 deletion lua/neorg/modules/core/looking-glass/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,11 @@ module.on_event = function(event)
-- TODO: Make the vsplit location configurable (i.e. whether it spawns on the left or the right)
local vsplit = module.required["core.ui"].create_vsplit(
"code-block-" .. tostring(code_block_info.start.row) .. tostring(code_block_info["end"].row), -- This is done to make the name of the vsplit unique
true,
{
filetype = (code_block_info.parameters[1] or "none"),
},
true
{ split = "left" }
)

if not vsplit then
Expand Down
83 changes: 60 additions & 23 deletions lua/neorg/modules/core/qol/toc/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ module.setup = function()
}
end

---Track if the next TOC open was automatic. Used to determine if we should enter the TOC or not.
local next_open_is_auto = false
module.load = function()
modules.await("core.neorgcmd", function(neorgcmd)
neorgcmd.add_commands_from_table({
Expand All @@ -42,14 +44,13 @@ module.load = function()
end)

if module.config.public.auto_toc.open then
vim.api.nvim_create_autocmd("BufEnter", {
vim.api.nvim_create_autocmd("BufWinEnter", {
pattern = "*.norg",
callback = function()
local win = vim.api.nvim_get_current_win()
vim.cmd([[Neorg toc]])
if not module.config.public.auto_toc.enter then
vim.api.nvim_set_current_win(win)
end
vim.schedule(function()
next_open_is_auto = true
vim.cmd([[Neorg toc]])
end)
end,
})
end
Expand All @@ -63,12 +64,19 @@ module.config.public = {
-- `max_width`
fit_width = true,

-- max width of the ToC window when `fit_width = true` (in columns)
max_width = 30,

-- when set, the ToC window will always be this many cols wide.
-- will override `fit_width` and ignore `max_width`
fixed_width = nil,

-- enable `cursorline` in the ToC window, and sync the cursor position between ToC and content
-- window
sync_cursorline = true,

-- max width of the ToC window when `fit_width = true` (in columns)
max_width = 30,
-- Enter a ToC window opened manually (any ToC window not opened by auto_toc)
enter = true,

-- options for automatically opening/entering the ToC window
auto_toc = {
Expand Down Expand Up @@ -303,9 +311,9 @@ module.public = {
)

for _, line in
ipairs(
vim.api.nvim_buf_get_text(norg_buffer, row_start_0b, col_start_0b, row_end_0bin, col_end_0bex, {})
)
ipairs(
vim.api.nvim_buf_get_text(norg_buffer, row_start_0b, col_start_0b, row_end_0bin, col_end_0bex, {})
)
do
table.insert(heading_texts, line)
end
Expand Down Expand Up @@ -355,19 +363,24 @@ module.public = {
}

module.private = {
---set the width of the ToC window
---get the width of the ToC window
---@param ui_data table
---@return number
get_toc_width = function(ui_data)
local max_virtcol_1bex = module.private.get_max_virtcol()
local current_winwidth = vim.fn.winwidth(vim.fn.bufwinid(ui_data.buffer))
local new_winwidth = math.min(current_winwidth, math.max(module.config.public.max_width, max_virtcol_1bex - 1))
if type(module.config.public.fixed_width) == "number" then
return module.config.public.fixed_width
end
local max_virtcol_1bex = module.private.get_max_virtcol(ui_data.window)
local current_winwidth = vim.api.nvim_win_get_width(ui_data.window)
local new_winwidth = math.min(current_winwidth, module.config.public.max_width, max_virtcol_1bex - 1)
return new_winwidth + 1
end,

get_max_virtcol = function()
local n_line = vim.fn.line("$")
get_max_virtcol = function(win)
local n_line = vim.fn.line("$", win)
local result = 1
for i = 1, n_line do
result = math.max(result, vim.fn.virtcol({ i, "$" }))
result = math.max(result, vim.fn.virtcol({ i, "$" }, 0, win))
end
return result
end,
Expand Down Expand Up @@ -397,12 +410,22 @@ local function unlisten_if_closed(listener)
end
end

local function create_ui(tabpage, mode)
---Create a split window and buffer for the table of contents. Set buffer and window options
---accordingly
---@param tabpage number
---@param split_dir "left" | "right"
---@param enter boolean
---@return table
local function create_ui(tabpage, split_dir, enter)
assert(tabpage == vim.api.nvim_get_current_tabpage())

toc_namespace = toc_namespace or vim.api.nvim_create_namespace("neorg/toc")
local ui_buffer, ui_window =
module.required["core.ui"].create_vsplit(("toc-%d"):format(tabpage), { ft = "norg" }, mode)
local ui_buffer, ui_window = module.required["core.ui"].create_vsplit(
("toc-%d"):format(tabpage),
enter,
{ ft = "norg" },
{ split = split_dir, win = 0, style = "minimal" }
)

local ui_wo = vim.wo[ui_window]
ui_wo.scrolloff = 999
Expand All @@ -427,6 +450,15 @@ local function create_ui(tabpage, mode)
return ui_data
end

--- should we enter the ToC window?
local function enter_toc_win()
local do_enter = module.config.public.enter
if next_open_is_auto then
do_enter = module.config.public.auto_toc.enter
end
return do_enter
end

module.on_event = function(event)
if event.split_type[2] ~= module.name then
return
Expand Down Expand Up @@ -456,15 +488,20 @@ module.on_event = function(event)
return
end
module.public.update_toc(toc_title, ui_data_of_tabpage[tabpage], norg_buffer)

if enter_toc_win() then
vim.api.nvim_set_current_win(ui_data_of_tabpage[tabpage].window)
end
return
end

local ui_data = create_ui(tabpage, (event.content[1] or "left") == "left")
local ui_data = create_ui(tabpage, event.content[1] or "left", enter_toc_win())
next_open_is_auto = false

module.public.update_toc(toc_title, ui_data_of_tabpage[tabpage], norg_buffer)

if module.config.public.fit_width then
vim.cmd(("vertical resize %d"):format(module.private.get_toc_width(ui_data)))
vim.api.nvim_win_set_width(ui_data.window, module.private.get_toc_width(ui_data))
end

local close_buffer_callback = function()
Expand Down
45 changes: 20 additions & 25 deletions lua/neorg/modules/core/ui/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -151,24 +151,18 @@ module.public = {

--- Creates a new vertical split
---@param name string the name of the buffer
---@param config table a table of <option> = <value> keypairs signifying buffer-local options for the buffer contained within the split
---@param left boolean if true will spawn the vertical split on the left (default is right)
---@return number?, number? #The buffer of the vertical split
create_vsplit = function(name, config, left)
---@param enter boolean enter the window or not
---@param buf_config table a table of <option> = <value> keypairs signifying buffer-local options for the buffer contained within the split
---@param win_config table table of <option>=<value> keypairs for `nvim_open_win`, must provide `win`
---@return number?, number? #The buffer and window numbers of the vertical split
create_vsplit = function(name, enter, buf_config, win_config)
vim.validate({
name = { name, "string" },
config = { config, "table" },
left = { left, "boolean", true },
enter = { enter, "boolean", true },
config = { buf_config, "table" },
win_config = { win_config, "table" },
})

left = left or false

vim.cmd("vsplit")

if left then
vim.cmd("wincmd H")
end

local buf = vim.api.nvim_create_buf(false, true)

local default_options = {
Expand All @@ -180,17 +174,18 @@ module.public = {
}

vim.api.nvim_buf_set_name(buf, "neorg://" .. name)
vim.api.nvim_win_set_buf(0, buf)

vim.api.nvim_set_option_value("number", false, { win = 0 })
vim.api.nvim_set_option_value("relativenumber", false, { win = 0 })
local win_options = {
vertical = true,
}
win_options = vim.tbl_deep_extend("keep", win_options, win_config)
local window = vim.api.nvim_open_win(buf, enter, win_options)

vim.api.nvim_win_set_buf(0, buf)
vim.api.nvim_set_option_value("number", false, { win = window })
vim.api.nvim_set_option_value("relativenumber", false, { win = window })

-- Merge the user provided options with the default options and apply them to the new buffer
module.public.apply_buffer_options(buf, vim.tbl_extend("keep", config or {}, default_options))

local window = vim.api.nvim_get_current_win()
module.public.apply_buffer_options(buf, vim.tbl_extend("keep", buf_config or {}, default_options))

-- Make sure to clean up the window if the user leaves the popup at any time
vim.api.nvim_create_autocmd({ "BufDelete", "WinClosed" }, {
Expand Down Expand Up @@ -225,9 +220,9 @@ module.public = {
name = "display/" .. name

if split_type == "vsplitl" then
return module.public.create_vsplit(name, {}, true)
return module.public.create_vsplit(name, true, {}, { split = "left" })
elseif split_type == "vsplitr" then
return module.public.create_vsplit(name, {}, false)
return module.public.create_vsplit(name, true, {}, { split = "right" })
elseif split_type == "split" then
return module.public.create_split(name, {})
else
Expand Down Expand Up @@ -329,9 +324,9 @@ module.public = {
name = "norg/" .. name .. ".norg"

if split_type == "vsplitl" then
return module.public.create_vsplit(name, {}, true)
return module.public.create_vsplit(name, true, {}, { split = "left" })
elseif split_type == "vsplitr" then
return module.public.create_vsplit(name, {}, false)
return module.public.create_vsplit(name, true, {}, { split = "right" })
elseif split_type == "split" then
return module.public.create_split(name, {})
else
Expand Down

0 comments on commit 83637f1

Please sign in to comment.