11local Object = require (" nui.object" )
22local _ = require (" nui.utils" )._
33local defaults = require (" nui.utils" ).defaults
4- local is_type = require (" nui.utils" ).is_type
54local tree_util = require (" nui.tree.util" )
65
76-- returns id of the first window that contains the buffer
1514--- @param parent_node ? NuiTree.Node
1615--- @param get_node_id nui_tree_get_node_id
1716--- @return { by_id : table<string , NuiTree.Node> , root_ids : string[] }
18- local function initialize_nodes (nodes , parent_node , get_node_id )
17+ local function initialize_nodes (tree , nodes , parent_node , get_node_id )
1918 local start_depth = parent_node and parent_node :get_depth () + 1 or 1
2019
2120 --- @type table<string , NuiTree.Node>
@@ -26,7 +25,9 @@ local function initialize_nodes(nodes, parent_node, get_node_id)
2625 --- @param node NuiTree.Node
2726 --- @param depth number
2827 local function initialize (node , depth )
28+ node ._tree = tree
2929 node ._depth = depth
30+ node ._height = 0
3031 node ._id = get_node_id (node )
3132 node ._initialized = true
3233
7576--- @field _depth integer
7677--- @field _parent_id ? string
7778--- @field _child_ids ? string[]
79+ --- @field _next NuiTree.Node
80+ --- @field _prev NuiTree.Node
7881--- @field __children ? NuiTree.Node[]
7982--- @field [ string] any
8083local TreeNode = {
147150--- @field node_id_by_linenr table<integer , string>
148151--- @field prepare_node nui_tree_prepare_node
149152--- @field win_options table<string , any> # deprecated
153+ --- @field head ? NuiTree.Node
154+ --- @field tail ? NuiTree.Node
150155
151156--- @class nui_tree_options
152157--- @field bufnr integer
@@ -253,14 +258,46 @@ end
253258--- @return nil | integer linenr
254259--- @return nil | integer linenr
255260function Tree :get_node (node_id_or_linenr )
256- if is_type (" string" , node_id_or_linenr ) then
257- return self .nodes .by_id [node_id_or_linenr ], unpack (self ._ .linenr_by_node_id [node_id_or_linenr ] or {})
261+ if type (node_id_or_linenr ) == " string" then
262+ local node = self .nodes .by_id [node_id_or_linenr ]
263+ if not node then
264+ return
265+ end
266+
267+ local linenr = 1
268+ local head = self ._head
269+ while head and head ~= node do
270+ head = head ._next
271+ linenr = linenr + 1
272+ end
273+
274+ return node , linenr , linenr + node ._height - 1
275+
276+ -- return node, unpack(self._.linenr_by_node_id[node_id_or_linenr] or {})
258277 end
259278
260279 local winid = get_winid (self .bufnr )
261280 local linenr = node_id_or_linenr or vim .api .nvim_win_get_cursor (winid )[1 ]
262- local node_id = self ._ .node_id_by_linenr [linenr ]
263- return self .nodes .by_id [node_id ], unpack (self ._ .linenr_by_node_id [node_id ] or {})
281+
282+ local node , linenr_left = self ._head , linenr - 1
283+ local node_height_below = node and node ._height
284+ while node and linenr_left > 0 do
285+ linenr_left = linenr_left - 1
286+ node_height_below = node_height_below - 1
287+ if node_height_below == 0 then
288+ node = node ._next
289+ node_height_below = node and node ._height
290+ end
291+ end
292+
293+ if not node then
294+ return
295+ end
296+
297+ return node , linenr + node_height_below - node ._height , linenr + node_height_below - 1
298+
299+ -- local node_id = self._.node_id_by_linenr[linenr]
300+ -- return self.nodes.by_id[node_id], unpack(self._.linenr_by_node_id[node_id] or {})
264301end
265302
266303--- @param parent_id ? string parent node ' s id
285322--- @param nodes NuiTree.Node[]
286323--- @param parent_node ? NuiTree.Node
287324function Tree :_add_nodes (nodes , parent_node )
288- local new_nodes = initialize_nodes (nodes , parent_node , self ._ .get_node_id )
325+ local new_nodes = initialize_nodes (self , nodes , parent_node , self ._ .get_node_id )
289326
290327 self .nodes .by_id = vim .tbl_extend (" force" , self .nodes .by_id , new_nodes .by_id )
291328
307344--- @param nodes NuiTree.Node[]
308345--- @param parent_id ? string parent node ' s id
309346function Tree :set_nodes (nodes , parent_id )
310- self ._ .node_id_by_linenr = {}
311- self ._ .linenr_by_node_id = {}
347+ -- self._.node_id_by_linenr = {}
348+ -- self._.linenr_by_node_id = {}
312349
313350 if not parent_id then
314351 self .nodes = { by_id = {}, root_ids = {} }
@@ -387,11 +424,13 @@ function Tree:_prepare_content(linenr_start)
387424 local tree_linenr = 0
388425 local lines = { len = tree_linenr }
389426
390- local node_id_by_linenr = {}
391- internal .node_id_by_linenr = node_id_by_linenr
427+ -- local node_id_by_linenr = {}
428+ -- internal.node_id_by_linenr = node_id_by_linenr
392429
393- local linenr_by_node_id = {}
394- internal .linenr_by_node_id = linenr_by_node_id
430+ -- local linenr_by_node_id = {}
431+ -- internal.linenr_by_node_id = linenr_by_node_id
432+
433+ local prev_node = nil
395434
396435 local function prepare (node_id , parent_node )
397436 local node = by_id [node_id ]
@@ -400,30 +439,41 @@ function Tree:_prepare_content(linenr_start)
400439 end
401440
402441 local node_lines = internal .prepare_node (node , parent_node )
442+ local node_lines_len = 0
403443 if node_lines then
404444 if type (node_lines ) ~= " table" or node_lines .content then
405445 list_wrapper [1 ] = node_lines
406446 node_lines = list_wrapper
407447 end
408448 --- @cast node_lines - string , - NuiLine
409449
410- local node_linenr = linenr_by_node_id [node_id ] or {}
411- for node_line_idx = 1 , # node_lines do
450+ -- local node_linenr = linenr_by_node_id[node_id] or {}
451+ node_lines_len = # node_lines
452+ for node_line_idx = 1 , node_lines_len do
412453 local node_line = node_lines [node_line_idx ]
413454
414455 tree_linenr = tree_linenr + 1
415- local buffer_linenr = tree_linenr + linenr_start - 1
456+ -- local buffer_linenr = tree_linenr + linenr_start - 1
416457
417458 lines [tree_linenr ] = node_line
418459
419- node_id_by_linenr [buffer_linenr ] = node_id
460+ -- node_id_by_linenr[buffer_linenr] = node_id
420461
421- if node_line_idx == 1 then
422- node_linenr [1 ] = buffer_linenr
423- end
424- node_linenr [2 ] = buffer_linenr
462+ -- if node_line_idx == 1 then
463+ -- node_linenr[1] = buffer_linenr
464+ -- end
465+ -- node_linenr[2] = buffer_linenr
425466 end
426- linenr_by_node_id [node_id ] = node_linenr
467+ -- linenr_by_node_id[node_id] = node_linenr
468+ end
469+ node ._height = node_lines_len
470+
471+ if node ._height > 0 then
472+ node ._prev = prev_node
473+ if prev_node then
474+ prev_node ._next = node
475+ end
476+ prev_node = node
427477 end
428478
429479 local child_ids = node ._child_ids
@@ -439,6 +489,9 @@ function Tree:_prepare_content(linenr_start)
439489 prepare (root_ids [node_id_idx ])
440490 end
441491
492+ self ._head = by_id [root_ids [1 ]]
493+ self ._tail = prev_node
494+
442495 lines .len = tree_linenr
443496
444497 return lines
0 commit comments