Skip to content

Commit b40eb8c

Browse files
committed
wip
1 parent e319f25 commit b40eb8c

File tree

1 file changed

+84
-22
lines changed

1 file changed

+84
-22
lines changed

lua/nui/tree/init.lua

Lines changed: 84 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
local Object = require("nui.object")
22
local _ = require("nui.utils")._
33
local defaults = require("nui.utils").defaults
4-
local is_type = require("nui.utils").is_type
54
local tree_util = require("nui.tree.util")
65

76
-- returns id of the first window that contains the buffer
@@ -11,11 +10,12 @@ local function get_winid(bufnr)
1110
return vim.fn.win_findbuf(bufnr)[1]
1211
end
1312

13+
---@param get_tree fun(): NuiTree
1414
---@param nodes NuiTree.Node[]
1515
---@param parent_node? NuiTree.Node
1616
---@param get_node_id nui_tree_get_node_id
1717
---@return { by_id: table<string, NuiTree.Node>, root_ids: string[] }
18-
local function initialize_nodes(nodes, parent_node, get_node_id)
18+
local function initialize_nodes(get_tree, nodes, parent_node, get_node_id)
1919
local start_depth = parent_node and parent_node:get_depth() + 1 or 1
2020

2121
---@type table<string, NuiTree.Node>
@@ -26,7 +26,9 @@ local function initialize_nodes(nodes, parent_node, get_node_id)
2626
---@param node NuiTree.Node
2727
---@param depth number
2828
local function initialize(node, depth)
29+
node._tree = get_tree
2930
node._depth = depth
31+
node._height = 0
3032
node._id = get_node_id(node)
3133
node._initialized = true
3234

@@ -75,6 +77,8 @@ end
7577
---@field _depth integer
7678
---@field _parent_id? string
7779
---@field _child_ids? string[]
80+
---@field _next string
81+
---@field _prev string
7882
---@field __children? NuiTree.Node[]
7983
---@field [string] any
8084
local TreeNode = {
@@ -147,6 +151,9 @@ end
147151
---@field node_id_by_linenr table<integer, string>
148152
---@field prepare_node nui_tree_prepare_node
149153
---@field win_options table<string, any> # deprecated
154+
---@field head? string
155+
---@field tail? string
156+
---@field get_tree fun(): NuiTree
150157

151158
---@class nui_tree_options
152159
---@field bufnr integer
@@ -212,6 +219,10 @@ function Tree:init(options)
212219
linenr = {},
213220
}
214221

222+
self._.get_tree = function()
223+
return self
224+
end
225+
215226
_.set_buf_options(self.bufnr, self._.buf_options)
216227

217228
---@deprecated
@@ -253,14 +264,48 @@ end
253264
---@return nil|integer linenr
254265
---@return nil|integer linenr
255266
function 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 {})
267+
local by_id = self.nodes.by_id
268+
269+
if type(node_id_or_linenr) == "string" then
270+
local node = by_id[node_id_or_linenr]
271+
if not node then
272+
return
273+
end
274+
275+
local linenr = 1
276+
local head = by_id[self._head]
277+
while head and head ~= node do
278+
head = by_id[head._next]
279+
linenr = linenr + 1
280+
end
281+
282+
return node, linenr, linenr + node._height - 1
283+
284+
-- return node, unpack(self._.linenr_by_node_id[node_id_or_linenr] or {})
258285
end
259286

260287
local winid = get_winid(self.bufnr)
261288
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 {})
289+
290+
local node, linenr_left = by_id[self._head], linenr - 1
291+
local node_height_below = node and node._height
292+
while node and linenr_left > 0 do
293+
linenr_left = linenr_left - 1
294+
node_height_below = node_height_below - 1
295+
if node_height_below == 0 then
296+
node = by_id[node._next]
297+
node_height_below = node and node._height
298+
end
299+
end
300+
301+
if not node then
302+
return
303+
end
304+
305+
return node, linenr + node_height_below - node._height, linenr + node_height_below - 1
306+
307+
-- local node_id = self._.node_id_by_linenr[linenr]
308+
-- return self.nodes.by_id[node_id], unpack(self._.linenr_by_node_id[node_id] or {})
264309
end
265310

266311
---@param parent_id? string parent node's id
@@ -285,7 +330,7 @@ end
285330
---@param nodes NuiTree.Node[]
286331
---@param parent_node? NuiTree.Node
287332
function Tree:_add_nodes(nodes, parent_node)
288-
local new_nodes = initialize_nodes(nodes, parent_node, self._.get_node_id)
333+
local new_nodes = initialize_nodes(self._.get_tree, nodes, parent_node, self._.get_node_id)
289334

290335
self.nodes.by_id = vim.tbl_extend("force", self.nodes.by_id, new_nodes.by_id)
291336

@@ -307,8 +352,8 @@ end
307352
---@param nodes NuiTree.Node[]
308353
---@param parent_id? string parent node's id
309354
function Tree:set_nodes(nodes, parent_id)
310-
self._.node_id_by_linenr = {}
311-
self._.linenr_by_node_id = {}
355+
-- self._.node_id_by_linenr = {}
356+
-- self._.linenr_by_node_id = {}
312357

313358
if not parent_id then
314359
self.nodes = { by_id = {}, root_ids = {} }
@@ -387,11 +432,13 @@ function Tree:_prepare_content(linenr_start)
387432
local tree_linenr = 0
388433
local lines = { len = tree_linenr }
389434

390-
local node_id_by_linenr = {}
391-
internal.node_id_by_linenr = node_id_by_linenr
435+
-- local node_id_by_linenr = {}
436+
-- internal.node_id_by_linenr = node_id_by_linenr
437+
438+
-- local linenr_by_node_id = {}
439+
-- internal.linenr_by_node_id = linenr_by_node_id
392440

393-
local linenr_by_node_id = {}
394-
internal.linenr_by_node_id = linenr_by_node_id
441+
local prev_node = nil
395442

396443
local function prepare(node_id, parent_node)
397444
local node = by_id[node_id]
@@ -400,30 +447,42 @@ function Tree:_prepare_content(linenr_start)
400447
end
401448

402449
local node_lines = internal.prepare_node(node, parent_node)
450+
local node_lines_len = 0
403451
if node_lines then
404452
if type(node_lines) ~= "table" or node_lines.content then
405453
list_wrapper[1] = node_lines
406454
node_lines = list_wrapper
407455
end
408456
---@cast node_lines -string, -NuiLine
409457

410-
local node_linenr = linenr_by_node_id[node_id] or {}
411-
for node_line_idx = 1, #node_lines do
458+
-- local node_linenr = linenr_by_node_id[node_id] or {}
459+
node_lines_len = #node_lines
460+
for node_line_idx = 1, node_lines_len do
412461
local node_line = node_lines[node_line_idx]
413462

414463
tree_linenr = tree_linenr + 1
415-
local buffer_linenr = tree_linenr + linenr_start - 1
464+
-- local buffer_linenr = tree_linenr + linenr_start - 1
416465

417466
lines[tree_linenr] = node_line
418467

419-
node_id_by_linenr[buffer_linenr] = node_id
468+
-- node_id_by_linenr[buffer_linenr] = node_id
469+
470+
-- if node_line_idx == 1 then
471+
-- node_linenr[1] = buffer_linenr
472+
-- end
473+
-- node_linenr[2] = buffer_linenr
474+
end
475+
-- linenr_by_node_id[node_id] = node_linenr
476+
end
477+
node._height = node_lines_len
420478

421-
if node_line_idx == 1 then
422-
node_linenr[1] = buffer_linenr
423-
end
424-
node_linenr[2] = buffer_linenr
479+
if node._height > 0 then
480+
node._prev = prev_node
481+
if prev_node then
482+
node._prev = node._prev:get_id()
483+
prev_node._next = node:get_id()
425484
end
426-
linenr_by_node_id[node_id] = node_linenr
485+
prev_node = node
427486
end
428487

429488
local child_ids = node._child_ids
@@ -439,6 +498,9 @@ function Tree:_prepare_content(linenr_start)
439498
prepare(root_ids[node_id_idx])
440499
end
441500

501+
self._head = root_ids[1]
502+
self._tail = prev_node
503+
442504
lines.len = tree_linenr
443505

444506
return lines

0 commit comments

Comments
 (0)