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

Signal values are not being unsubscribed on component unmount #30

Closed b0o closed 5 months ago

b0o commented 5 months ago

To reproduce: Update the value of a signal 100ms after the renderer unmounts.

Expected: If the SignalValue were properly unsubscribed on unmount, this should be safe, and should have no effect.

Actual: An error is thrown:

Error executing vim.schedule lua callback: nui.nvim/lua/nui/line/init.lua:72: Invalid 'buffer': Expected Lua number
stack traceback:
    [C]: in function 'nvim_buf_set_lines'
    nui.nvim/lua/nui/line/init.lua:72: in function 'render'
    ...vim/nui-components.nvim/lua/nui-components/paragraph.lua:184: in function 'func'
    ...nvim/nui-components.nvim/lua/nui-components/utils/fn.lua:117: in function 'ieach'
    ...vim/nui-components.nvim/lua/nui-components/paragraph.lua:165: in function 'modify_fn'
    ...ui-components.nvim/lua/nui-components/component/init.lua:400: in function <...ui-components.nvim/lua/nui-components/component/init.lua:398>
local n = require 'nui-components'

local renderer = n.create_renderer {
  width = 60,
  height = 12,
}

local signal = n.create_signal {
  name = '',
}

renderer:on_unmount(function()
  vim.defer_fn(function()
    signal.name = 'foo'
  end, 100)
end)

local body = function()
  return n.rows(
    n.paragraph {
      is_focusable = false,
      lines = signal.name:map(function(name)
        return {
          n.line(n.text('Name: ', 'Keyword'), name),
        }
      end),
    },
    n.gap(1),
    n.form(
      { id = 'form' },
      n.text_input {
        autofocus = true,
        max_lines = 1,
        border_label = 'Name',
        on_change = function(val)
          signal.name = val
        end,
      }
    )
  )
end

renderer:render(body)