@@ -7,6 +7,8 @@ local utils = require("neo-tree.utils")
7
7
local highlights = require (" neo-tree.ui.highlights" )
8
8
local popups = require (" neo-tree.ui.popups" )
9
9
local events = require (" neo-tree.events" )
10
+ local keymap = require (" nui.utils.keymap" )
11
+ local autocmd = require (" nui.utils.autocmd" )
10
12
local log = require (" neo-tree.log" )
11
13
12
14
local M = {}
@@ -357,6 +359,7 @@ local enable_auto_close_floats = function()
357
359
end
358
360
359
361
create_window = function (state )
362
+ local bufname = string.format (" neo-tree %s [%s]" , state .name , state .tabnr )
360
363
local win_options = {
361
364
size = utils .resolve_config_option (state , " window.width" , " 40" ),
362
365
position = utils .resolve_config_option (state , " window.position" , " left" ),
@@ -400,39 +403,61 @@ create_window = function(state)
400
403
win :unmount ()
401
404
end )
402
405
end , { once = true })
406
+ state .winid = win .winid
407
+ state .bufnr = win .bufnr
408
+ vim .api .nvim_buf_set_name (state .bufnr , bufname )
403
409
404
410
-- why is this necessary?
405
411
vim .api .nvim_set_current_win (win .winid )
406
412
enable_auto_close_floats ()
413
+ elseif win_options .position == " split" then
414
+ local winid = vim .api .nvim_get_current_win ()
415
+ local bufnr = vim .fn .bufnr (bufname )
416
+ if bufnr < 1 then
417
+ bufnr = vim .api .nvim_create_buf (false , false )
418
+ vim .api .nvim_buf_set_name (bufnr , bufname )
419
+ end
420
+ state .winid = winid
421
+ state .bufnr = bufnr
422
+ vim .api .nvim_buf_set_option (bufnr , " buftype" , " nofile" )
423
+ vim .api .nvim_buf_set_option (bufnr , " swapfile" , false )
424
+ vim .api .nvim_buf_set_option (bufnr , " filetype" , " neo-tree" )
425
+ vim .api .nvim_buf_set_option (bufnr , " modifiable" , false )
426
+ vim .api .nvim_win_set_buf (winid , bufnr )
407
427
else
408
428
win = NuiSplit (win_options )
409
429
win :mount ()
430
+ state .winid = win .winid
431
+ state .bufnr = win .bufnr
432
+ vim .api .nvim_buf_set_name (state .bufnr , bufname )
410
433
end
411
434
412
- state .winid = win .winid
413
- state .bufnr = win .bufnr
414
-
415
435
if type (state .bufnr ) == " number" then
416
- local bufname = string.format (" neo-tree %s [%s]" , state .name , state .tabnr )
417
- vim .api .nvim_buf_set_name (state .bufnr , bufname )
418
436
vim .api .nvim_buf_set_var (state .bufnr , " neo_tree_source" , state .name )
419
- vim .api .nvim_buf_set_var (state .bufnr , " neo_tree_winid" , state .winid )
420
437
vim .api .nvim_buf_set_var (state .bufnr , " neo_tree_tabnr" , state .tabnr )
438
+ vim .api .nvim_buf_set_var (state .bufnr , " neo_tree_position" , state .window .position )
439
+ vim .api .nvim_buf_set_var (state .bufnr , " neo_tree_winid" , state .winid )
421
440
end
422
441
423
- -- Used to track the position of the cursor within the tree as it gains and loses focus
424
- --
425
- -- Note `WinEnter` is often too early to restore the cursor position so we do not set
426
- -- that up here, and instead trigger those events manually after drawing the tree (not
427
- -- to mention that it would be too late to register `WinEnter` here for the first
428
- -- iteration of that event on the tree window)
429
- win :on ({ " WinLeave" }, function ()
430
- state .position .save ()
431
- end )
442
+ if win == nil then
443
+ autocmd .buf .define (state .bufnr , " WinLeave" , function ()
444
+ state .position .save ()
445
+ end )
446
+ else
447
+ -- Used to track the position of the cursor within the tree as it gains and loses focus
448
+ --
449
+ -- Note `WinEnter` is often too early to restore the cursor position so we do not set
450
+ -- that up here, and instead trigger those events manually after drawing the tree (not
451
+ -- to mention that it would be too late to register `WinEnter` here for the first
452
+ -- iteration of that event on the tree window)
453
+ win :on ({ " WinLeave" }, function ()
454
+ state .position .save ()
455
+ end )
432
456
433
- win :on ({ " BufDelete" }, function ()
434
- win :unmount ()
435
- end , { once = true })
457
+ win :on ({ " BufDelete" }, function ()
458
+ win :unmount ()
459
+ end , { once = true })
460
+ end
436
461
437
462
local skip_this_mapping = {
438
463
[" none" ] = true ,
@@ -452,7 +477,7 @@ create_window = function(state)
452
477
func = state .commands [func ]
453
478
end
454
479
if type (func ) == " function" then
455
- win : map ( " n" , cmd , function ()
480
+ keymap . set ( state . bufnr , " n" , cmd , function ()
456
481
func (state )
457
482
end , map_options )
458
483
else
@@ -483,14 +508,21 @@ end
483
508
--- @return boolean True if the window exists and is valid , false otherwise.
484
509
M .window_exists = function (state )
485
510
local window_exists
486
- if state .winid == nil then
511
+ local winid = utils .get_value (state , " winid" , 0 , true )
512
+ local bufnr = utils .get_value (state , " bufnr" , 0 , true )
513
+ local position = utils .get_value (state , " window.position" , " left" , true )
514
+
515
+ if winid == 0 then
487
516
window_exists = false
517
+ elseif position == " split" then
518
+ window_exists = vim .api .nvim_win_is_valid (winid )
519
+ and vim .api .nvim_buf_is_valid (bufnr )
520
+ and vim .api .nvim_win_get_buf (winid ) == bufnr
488
521
else
489
- local isvalid = M .is_window_valid (state . winid )
490
- window_exists = isvalid and (vim .api .nvim_win_get_number (state . winid ) > 0 )
522
+ local isvalid = M .is_window_valid (winid )
523
+ window_exists = isvalid and (vim .api .nvim_win_get_number (winid ) > 0 )
491
524
if not window_exists then
492
525
state .winid = nil
493
- local bufnr = utils .get_value (state , " bufnr" , 0 , true )
494
526
if bufnr > 0 and vim .api .nvim_buf_is_valid (bufnr ) then
495
527
state .bufnr = nil
496
528
local success , err = pcall (vim .api .nvim_buf_delete , bufnr , { force = true })
@@ -525,13 +557,17 @@ draw = function(nodes, state, parent_id)
525
557
end
526
558
527
559
-- Create the tree if it doesn't exist.
528
- if not M .window_exists (state ) then
560
+ if not parent_id and not M .window_exists (state ) then
529
561
create_window (state )
530
562
create_tree (state )
531
563
end
532
564
533
565
-- draw the given nodes
534
- state .tree :set_nodes (nodes , parent_id )
566
+ local success , msg = pcall (state .tree .set_nodes , state .tree , nodes , parent_id )
567
+ if not success then
568
+ log .error (" Error setting nodes: " , msg )
569
+ log .error (vim .inspect (state .tree :get_nodes ()))
570
+ end
535
571
if parent_id ~= nil then
536
572
-- this is a dynamic fetch of children that were not previously loaded
537
573
local node = state .tree :get_node (parent_id )
@@ -558,8 +594,10 @@ M.show_nodes = function(sourceItems, state, parentId)
558
594
events .fire_event (events .BEFORE_RENDER , state )
559
595
local level = 0
560
596
if parentId ~= nil then
561
- local parent = state .tree :get_node (parentId )
562
- level = parent :get_depth ()
597
+ local success , parent = pcall (state .tree .get_node , state .tree , parentId )
598
+ if success then
599
+ level = parent :get_depth ()
600
+ end
563
601
end
564
602
local nodes = create_nodes (sourceItems , state , level )
565
603
draw (nodes , state , parentId )
0 commit comments