grapp-dev / nui-components.nvim

A feature-rich and highly customizable library for creating user interfaces in Neovim.
https://nui-components.grapp.dev
MIT License
303 stars 6 forks source link

Tree fixes for nested node handling (scroll and id generation) #6

Closed willothy closed 5 months ago

willothy commented 5 months ago

Fixes issues with the tree component throwing errors when provided a list of nodes with more than 1 level of depth.

  1. Lazily generate ids with get_node_id instead of generating them only for top-level nodes
  2. Recursively calculate tree height on scroll to take into account expanded/contracted nodes
mobily commented 5 months ago

hey @willothy, thanks for contributing! I'm wondering if you could provide the code that generates the bug. I plan on writing some unit tests, and it would be great to cover that case.

willothy commented 5 months ago

Any configuration of a tree with more than one level of nodes caused errors for me, are you not able to reproduce?

I don't have the original code but I can come up with a small example

mobily commented 5 months ago

Any configuration of a tree with more than one level of nodes

I probably haven't tested that case.

I don't have the original code but I can come up with a small example

that would be helpful!

willothy commented 5 months ago

This can reproduce the error for me:

local NC = require("nui-components")

local body = function()
  return NC.tree({
    size = 5,
    border_label = "Results",
    data = {
      NC.node({
        text = "Result 1",
      }),
      NC.node({
        text = "Result 2",
      }, {
        NC.node({
          text = "Result 3",
        }),
        NC.node({
          text = "Result 4",
        }),
      }),
    },
    prepare_node = function(node, line, component)
      local depth = node:get_depth()
      line:append(string.rep(" ", (depth - 1) * 2))
      if node:has_children() then
        if node:is_expanded() then
          line:append("v ")
        else
          line:append("> ")
        end
      else
        line:append("- ")
      end
      line:append(node.text)
      return line
    end,
  })
end

local view = NC.create_renderer({
  width = 40,
  height = 5,
})

view:render(body)