Repository: neovim
Issue: LSP completion: display documentation if exists for an item
Labels: enhancement,lsp,completion,floatwin

### Problem

It seems that at the moment displaying documentation for LSP completion does not work. If I'm wrong please close this issue. 

We probably need to call [completionItem/resolve](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#completionItem_resolve) for each item. The only such call seems to be made for single submitted item. 

### Expected behavior

Display documentation attached to an item - maybe by the user choice with some new option on `vim.lsp.completion.BufferOpts`.

I have created a simple [example](https://gist.github.com/przepompownia/0690ebe28a24bd10b45118fceb980dfd) containing autocommand on `CompleteChanged` that shows that it's not difficult but not sure how it should like as a built-in functionality so I didn't create PR. 
 
```lua
vim.api.nvim_create_autocmd('FileType', {
  pattern = 'lua',
  callback = function (args)
    vim.treesitter.start(args.buf, 'lua')
    vim.lsp.start({
      name = 'lua-ls',
      cmd = {'lua-language-server'},
      root_dir = vim.fs.root(args.buf, 'init.lua'),
    })
  end,
})

vim.api.nvim_create_autocmd('LspAttach', {
  callback = function (args)
    local client = vim.lsp.get_client_by_id(args.data.client_id)

    vim.lsp.completion.enable(true, args.data.client_id, args.buf, {autotrigger = true})

    vim.keymap.set({'i'}, '<C-Space>', function ()
      vim.lsp.completion.trigger()
    end, {buffer = args.buf})

    vim.api.nvim_create_autocmd('CompleteChanged', {
      buffer = args.buf,
      callback = function ()
        local info = vim.fn.complete_info({'selected'})
        local completionItem = vim.tbl_get(vim.v.completed_item, 'user_data', 'nvim', 'lsp', 'completion_item')
        if nil == completionItem then
          return
        end

        client.request(vim.lsp.protocol.Methods.completionItem_resolve, completionItem, function (_err, result)
          if nil == result then
            return
          end

          local winData = vim.api.nvim__complete_set(info['selected'], {info = result.documentation.value})
          if not vim.api.nvim_win_is_valid(winData.winid) then
            return
          end
          vim.api.nvim_win_set_config(winData.winid, {border = 'rounded'})
          vim.treesitter.start(winData.bufnr, 'markdown')
          vim.wo[winData.winid].conceallevel = 3
        end, args.buf)

        vim.api.nvim_create_autocmd({'TextChangedI'}, {
          buffer = args.buf,
          callback = function ()
            vim.lsp.completion.trigger()
          end
        })
      end
    })
  end
})

vim.go.completeopt = 'menu,noselect,menuone,popup'

local pumMaps = {
  ['<Tab>'] = '<C-n>',
  ['<Down>'] = '<C-n>',
  ['<S-Tab>'] = '<C-p>',
  ['<Up>'] = '<C-p>',
  ['<CR>'] = '<C-y>',
}

for insertKmap, pumKmap in pairs(pumMaps) do
  vim.keymap.set(
    {'i'},
    insertKmap,
    function ()
      return vim.fn.pumvisible() == 1 and pumKmap or insertKmap
    end,
    {expr = true}
  )
end
```

![Screenshot](https://github.com/neovim/neovim/assets/11404453/8ba8f9b0-9c15-454d-8e9f-2ebefebfbd79)