@@ -27,6 +27,8 @@ module.setup = function()
27
27
}
28
28
end
29
29
30
+ --- Track if the next TOC open was automatic. Used to determine if we should enter the TOC or not.
31
+ local next_open_is_auto = false
30
32
module .load = function ()
31
33
modules .await (" core.neorgcmd" , function (neorgcmd )
32
34
neorgcmd .add_commands_from_table ({
@@ -42,14 +44,13 @@ module.load = function()
42
44
end )
43
45
44
46
if module .config .public .auto_toc .open then
45
- vim .api .nvim_create_autocmd (" BufEnter " , {
47
+ vim .api .nvim_create_autocmd (" BufWinEnter " , {
46
48
pattern = " *.norg" ,
47
49
callback = function ()
48
- local win = vim .api .nvim_get_current_win ()
49
- vim .cmd ([[ Neorg toc]] )
50
- if not module .config .public .auto_toc .enter then
51
- vim .api .nvim_set_current_win (win )
52
- end
50
+ vim .schedule (function ()
51
+ next_open_is_auto = true
52
+ vim .cmd ([[ Neorg toc]] )
53
+ end )
53
54
end ,
54
55
})
55
56
end
@@ -63,12 +64,19 @@ module.config.public = {
63
64
-- `max_width`
64
65
fit_width = true ,
65
66
67
+ -- max width of the ToC window when `fit_width = true` (in columns)
68
+ max_width = 30 ,
69
+
70
+ -- when set, the ToC window will always be this many cols wide.
71
+ -- will override `fit_width` and ignore `max_width`
72
+ fixed_width = nil ,
73
+
66
74
-- enable `cursorline` in the ToC window, and sync the cursor position between ToC and content
67
75
-- window
68
76
sync_cursorline = true ,
69
77
70
- -- max width of the ToC window when `fit_width = true` (in columns )
71
- max_width = 30 ,
78
+ -- Enter a ToC window opened manually (any ToC window not opened by auto_toc )
79
+ enter = true ,
72
80
73
81
-- options for automatically opening/entering the ToC window
74
82
auto_toc = {
@@ -303,9 +311,9 @@ module.public = {
303
311
)
304
312
305
313
for _ , line in
306
- ipairs (
307
- vim .api .nvim_buf_get_text (norg_buffer , row_start_0b , col_start_0b , row_end_0bin , col_end_0bex , {})
308
- )
314
+ ipairs (
315
+ vim .api .nvim_buf_get_text (norg_buffer , row_start_0b , col_start_0b , row_end_0bin , col_end_0bex , {})
316
+ )
309
317
do
310
318
table.insert (heading_texts , line )
311
319
end
@@ -355,19 +363,24 @@ module.public = {
355
363
}
356
364
357
365
module .private = {
358
- --- set the width of the ToC window
366
+ --- get the width of the ToC window
367
+ --- @param ui_data table
368
+ --- @return number
359
369
get_toc_width = function (ui_data )
360
- local max_virtcol_1bex = module .private .get_max_virtcol ()
361
- local current_winwidth = vim .fn .winwidth (vim .fn .bufwinid (ui_data .buffer ))
362
- local new_winwidth = math.min (current_winwidth , math.max (module .config .public .max_width , max_virtcol_1bex - 1 ))
370
+ if type (module .config .public .fixed_width ) == " number" then
371
+ return module .config .public .fixed_width
372
+ end
373
+ local max_virtcol_1bex = module .private .get_max_virtcol (ui_data .window )
374
+ local current_winwidth = vim .api .nvim_win_get_width (ui_data .window )
375
+ local new_winwidth = math.min (current_winwidth , module .config .public .max_width , max_virtcol_1bex - 1 )
363
376
return new_winwidth + 1
364
377
end ,
365
378
366
- get_max_virtcol = function ()
367
- local n_line = vim .fn .line (" $" )
379
+ get_max_virtcol = function (win )
380
+ local n_line = vim .fn .line (" $" , win )
368
381
local result = 1
369
382
for i = 1 , n_line do
370
- result = math.max (result , vim .fn .virtcol ({ i , " $" }))
383
+ result = math.max (result , vim .fn .virtcol ({ i , " $" }, 0 , win ))
371
384
end
372
385
return result
373
386
end ,
@@ -397,12 +410,22 @@ local function unlisten_if_closed(listener)
397
410
end
398
411
end
399
412
400
- local function create_ui (tabpage , mode )
413
+ --- Create a split window and buffer for the table of contents. Set buffer and window options
414
+ --- accordingly
415
+ --- @param tabpage number
416
+ --- @param split_dir " left" | " right"
417
+ --- @param enter boolean
418
+ --- @return table
419
+ local function create_ui (tabpage , split_dir , enter )
401
420
assert (tabpage == vim .api .nvim_get_current_tabpage ())
402
421
403
422
toc_namespace = toc_namespace or vim .api .nvim_create_namespace (" neorg/toc" )
404
- local ui_buffer , ui_window =
405
- module .required [" core.ui" ].create_vsplit ((" toc-%d" ):format (tabpage ), { ft = " norg" }, mode )
423
+ local ui_buffer , ui_window = module .required [" core.ui" ].create_vsplit (
424
+ (" toc-%d" ):format (tabpage ),
425
+ enter ,
426
+ { ft = " norg" },
427
+ { split = split_dir , win = 0 , style = " minimal" }
428
+ )
406
429
407
430
local ui_wo = vim .wo [ui_window ]
408
431
ui_wo .scrolloff = 999
@@ -427,6 +450,15 @@ local function create_ui(tabpage, mode)
427
450
return ui_data
428
451
end
429
452
453
+ --- should we enter the ToC window?
454
+ local function enter_toc_win ()
455
+ local do_enter = module .config .public .enter
456
+ if next_open_is_auto then
457
+ do_enter = module .config .public .auto_toc .enter
458
+ end
459
+ return do_enter
460
+ end
461
+
430
462
module .on_event = function (event )
431
463
if event .split_type [2 ] ~= module .name then
432
464
return
@@ -456,15 +488,20 @@ module.on_event = function(event)
456
488
return
457
489
end
458
490
module .public .update_toc (toc_title , ui_data_of_tabpage [tabpage ], norg_buffer )
491
+
492
+ if enter_toc_win () then
493
+ vim .api .nvim_set_current_win (ui_data_of_tabpage [tabpage ].window )
494
+ end
459
495
return
460
496
end
461
497
462
- local ui_data = create_ui (tabpage , (event .content [1 ] or " left" ) == " left" )
498
+ local ui_data = create_ui (tabpage , event .content [1 ] or " left" , enter_toc_win ())
499
+ next_open_is_auto = false
463
500
464
501
module .public .update_toc (toc_title , ui_data_of_tabpage [tabpage ], norg_buffer )
465
502
466
503
if module .config .public .fit_width then
467
- vim .cmd (( " vertical resize %d " ): format ( module .private .get_toc_width (ui_data ) ))
504
+ vim .api . nvim_win_set_width ( ui_data . window , module .private .get_toc_width (ui_data ))
468
505
end
469
506
470
507
local close_buffer_callback = function ()
0 commit comments