Skip to content

choice‐popup

NAKAI Tsuyoshi edited this page Dec 8, 2023 · 8 revisions
[test]
prefix = 'test'
body = '${1|foo,bar,baz|} $2'

choice

It depends on whether you are using Vim or Neovim and what you are using as an auto-completion plugin. This is an example of using ddc.vim and pum.vim with Neovim.

Here's the gist

  • Check on DenippetNodeEnter that the current node is a choice, and if so, disable the auto-completion plugin and open popup.
  • Close the popup on DenippetNodeLeave if it is open, and enable auto-completion plugin.
  • Update the highlight on DenippetChoiceSelected.
local Popup = {}
                                                                       
function Popup.new()
  return setmetatable({
    nsid = vim.api.nvim_create_namespace("denippet_choice_popup"),
  }, { __index = Popup })
end
                                                                       
function Popup:open(node)
  self.buf = vim.api.nvim_create_buf(false, true)
  vim.api.nvim_buf_set_text(self.buf, 0, 0, 0, 0, node.items)
  local w, h = vim.lsp.util._make_floating_popup_size(node.items, {})
  self.win = vim.api.nvim_open_win(self.buf, false, {
    relative = "win",
    width = w,
    height = h,
    bufpos = { node.range.start.line, node.range.start.character },
    style = "minimal",
    border = "single",
  })
  self.extmark = vim.api.nvim_buf_set_extmark(
    self.buf,
    self.nsid,
    node.index,
    0,
    { hl_group = "incsearch", end_line = node.index + 1 }
  )
end
                                                                       
function Popup:update()
  vim.api.nvim_buf_del_extmark(self.buf, self.nsid, self.extmark)
  local node = vim.b.denippet_current_node
  self.extmark = vim.api.nvim_buf_set_extmark(
    self.buf,
    self.nsid,
    node.index,
    0,
    { hl_group = "incsearch", end_line = node.index + 1 }
  )
end
                                                                       
function Popup:close()
  if self.win then
    vim.api.nvim_win_close(self.win, true)
    self.buf = nil
    self.win = nil
    self.extmark = nil
  end
end
                                                                       
local popup = Popup.new()
                                                                       
local group = vim.api.nvim_create_augroup("denippet_choice_popup", {})
vim.api.nvim_create_autocmd("User", {
  group = group,
  pattern = "DenippetNodeEnter",
  callback = function()
    local node = vim.b.denippet_current_node
    if node and node.type == "choice" then
      vim.fn["ddc#custom#patch_global"]("ui", "none")
      popup:open(node)
    end
  end,
})
vim.api.nvim_create_autocmd("User", {
  group = group,
  pattern = "DenippetChoiceSelected",
  callback = function()
    popup:update()
  end,
})
vim.api.nvim_create_autocmd("User", {
  group = group,
  pattern = "DenippetNodeLeave",
  callback = function()
    popup:close()
    vim.fn["ddc#custom#patch_global"]("ui", "pum")
  end,
})
Clone this wiki locally