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

bug: `renderer:render()` will render blank box when called a 2nd time from a function #39

Closed vague2k closed 4 months ago

vague2k commented 4 months ago

In my plugin I want to render the ui through a function so it can mapped to a keymap, but when the function is called a 2nd time a blank box appears.

I'm pretty sure this is a bug, but if it is not, and there's a specific way a plugin should handle spawning the UI through a function, please let me know!

steps to reproduce

  1. create a component body
  2. wrap renderer:render(body) in a function like so
    local function render_this()
    renderer:render(body)
    end
  3. call the function once, should look normal,
  4. close the render. (renderer:close())
  5. call the function again. Should show blank box.

visual reproduction

https://github.com/grapp-dev/nui-components.nvim/assets/121782036/e591a159-6383-4e0d-8092-be5fc0d7da68

the code i used in the visual reproduction

local n = require("nui-components")
local api = require("huez.api")
local utils = require("huez.utils")

local function tonode(themes)
  local nodes = {}
  for _, theme in pairs(themes) do
    local node = n.option(theme, { name = theme })
    table.insert(nodes, node)
  end
  return nodes
end

-- TODO: let create_renderer to take in a function or a table of acceptable values
local renderer = n.create_renderer({
  width = 40,
  height = vim.api.nvim_win_get_height(0),
  relative = "editor",
  -- position starts from the left corner
  position = {
    row = 0,
    col = vim.api.nvim_win_get_width(0) - 3,
  },
})

local body = n.columns(n.rows(
  { flex = 2 },
  n.prompt({
    autofocus = true,
    prefix = " ::: ",
    size = 1,
    border_label = {
      text = "󰌁 Huez",
      align = "center",
    },
  }),

  n.select({
    flex = 1,
    autofocus = false,
    border_label = "Themes",
    data = tonode(api.get_installed_themes(vim.g.huez_config.exclude)),
    on_change = function(theme)
      vim.cmd("colorscheme " .. theme.name)
    end,
    on_select = function(theme)
      api.save_colorscheme(theme.name)
      renderer:close()
      utils.log_info("Selected " .. theme.name)
    end,
  })
))

renderer:add_mappings({
  {
    mode = "n",
    key = "q",
    handler = function()
      renderer:close()
    end,
  },
})

renderer:on_unmount(function()
  vim.cmd("colorscheme " .. api.get_colorscheme())
end)

-- FIXME: how can i get this to a usercommand without making it bug out
-- renderer:render(body)

local function pick_colorscheme()
  renderer:render(body)
end

return {
  pick_colorscheme = pick_colorscheme,
}
mobily commented 4 months ago

@vague2k please check the docs at https://nui-components.grapp.dev/docs/renderer#render. In your case, body should be a function, let me know if this solves your issue.

local body = function()
  return n.columns(…)
end
vague2k commented 4 months ago

yeah that works, slight oversight thanks!