MunifTanjim / nui.nvim

UI Component Library for Neovim.
MIT License
1.62k stars 57 forks source link

How to Get Popup Texts (in multi-popup Layout) Before Unmount #356

Open harrisoncramer opened 6 months ago

harrisoncramer commented 6 months ago

Hello, thanks for the awesome plugin.

If I have several popups rendered in a Layout, and I want to get their text content before they are closed via normal Vim methods (for instance if someone uses :q to close the layout) how could I do this?

We have tried to get the text content by referencing the popup.bufnr for each, but this does not work. For instance:

  popup:on(event.BufUnload, function()
    -- Get the buffer text here via popup.bufnr
      local lines = vim.api.nvim_buf_get_lines(popup.bufnr, 0, -1, false)
  end)

This does not work because the popup is already removed by the time these events fire, and we see an error: Invalid buffer id: 11

MunifTanjim commented 5 months ago
function issue_356()
  local Popup = require("nui.popup")
  local Layout = require("nui.layout")

  local popupA = Popup({
    enter = true,
    focusable = true,
    border = {
      style = "rounded",
      text = {
        top = "A",
      },
    },
  })
  vim.api.nvim_buf_set_lines(popupA.bufnr, 0, -1, false, {
    "AAAAAAAAAA",
  })
  local popupB = Popup({
    enter = true,
    focusable = true,
    border = {
      style = "rounded",
      text = {
        top = "B",
      },
    },
  })
  vim.api.nvim_buf_set_lines(popupB.bufnr, 0, -1, false, {
    "BBBBBBBBBB",
  })

  popupA:on("BufUnload", function()
    local lines = vim.api.nvim_buf_get_lines(popupA.bufnr, 0, -1, false)
    print(vim.inspect({ lines }))
  end)

  popupB:on("BufUnload", function()
    local lines = vim.api.nvim_buf_get_lines(popupB.bufnr, 0, -1, false)
    print(vim.inspect({ lines }))
  end)

  local layout = Layout(
    {
      position = "50%",
      size = {
        width = "80%",
        height = "60%",
      },
    },
    Layout.Box({
      Layout.Box(popupA, { size = "50%" }),
      Layout.Box(popupB, { size = "50%" }),
    })
  )

  layout:mount()
end

issue_356()

I've tested with this, and it's working as expected.

Let me know if you have any reproducible example.