kevinhwang91 / nvim-ufo

Not UFO in the sky, but an ultra fold in Neovim.
BSD 3-Clause "New" or "Revised" License
2.34k stars 49 forks source link

Unhandled exception when opening different file type. #21

Closed zbindenren closed 2 years ago

zbindenren commented 2 years ago

Neovim version (nvim -v | head -n1)

nvim v0.7.0

Operating system/version

arch linux

How to reproduce the issue

  1. Open a go file (golang lsp is started)
  2. Open another file (yaml for example) Then the following exception happens:
Error executing vim.schedule lua callback: UnhandledPromiseRejection with the reason:                                                                                                                                                                                                         
{ ["message"] = cannot parse non-Go file file:///home/rz/repos/gitlab.comlinux/ces/ces-operator/config/crd/bases/example.com_compauthcertificates.yaml, ["code"] =  }                                                                                                             
stack traceback:                                                                                                                                                                                                                                                                              
        ...re/nvim/site/pack/packer/start/nvim-ufo/lua/ufo/fold.lua:51: in function <Anonymous:40>

Expected behavior

No exception should happen.

Actual behavior

As mentioned above an exception happens.

kevinhwang91 commented 2 years ago

Look like you have two ls supporting folding range at the same time.

https://github.com/kevinhwang91/nvim-ufo/blob/24067ef90dd33da08e5a27e18e0de03b93fe4c2d/lua/ufo/provider/lsp/nvim.lua#L50-L52

I am not familiar with the selector for nvim lsp. In coc.nvim, there's a doc selector for each client.

Any tips?

zbindenren commented 2 years ago

Unfortunately I am not familiar either. Maybe add a help wanted label?

BTW: with the newest version I sometimes still get an exception with neogit:

Error executing vim.schedule lua callback: UnhandledPromiseRejection with the reason:                                                                                                                                                                                                         
{ ["message"] = stat /home/rz/repos/gitlab.com/linux/ces/ces-operator/.git/NEOGIT_COMMIT_EDITMSG: no such file or directory, ["code"] =  }
kevinhwang91 commented 2 years ago

What's your clients attach the error buffer? Could you mind post the vim.lsp.get_active_clients({bufnr = bufnr}) result here?

BTW: with the newest version I sometimes still get an exception with neogit:

You must use filetype to filter out yourself.

Finally, which language sever do you use and always attach any buffer? That's the root cause of the issue you are encountering. I can't reproduce the issue......

zbindenren commented 2 years ago

And another one for yaml:

Error executing vim.schedule lua callback: UnhandledPromiseRejection with the reason:                                                                                                                                                                                                         
{ ["message"] = Request textDocument/foldingRange failed with message: Cannot read property 'lineFoldingOnly' of undefined, ["code"] = -3260 } 
kevinhwang91 commented 2 years ago

can't reproduce all your error, need your language server information.

kevinhwang91 commented 2 years ago

Update the code. Run nvim: UFO_LOG=info nvim Get log: tail -f ~/.cache/nvim/ufo.log

zbindenren commented 2 years ago

Here the logs:

ufo.log.gz

zbindenren commented 2 years ago

Maybe the problem could also be the null-ls plugin.

kevinhwang91 commented 2 years ago

And another one for yaml:

Error executing vim.schedule lua callback: UnhandledPromiseRejection with the reason:                                                                                                                                                                                                         
{ ["message"] = Request textDocument/foldingRange failed with message: Cannot read property 'lineFoldingOnly' of undefined, ["code"] = -3260 } 

You haven't set:

local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.foldingRange = {
    dynamicRegistration = false,
    lineFoldingOnly = true
}

from the log you provide.

From the log, only one server attach the buffer, I think the this error log is about { ["message"] = Request textDocument/foldingRange failed with message: Cannot read property 'lineFoldingOnly' of undefined, ["code"] = -3260 }, not the first error you post.

zbindenren commented 2 years ago

I think I have set it in the configuration (see below):

local status_ok, ufo = pcall(require, "ufo")
if not status_ok then
    vim.notify("ufo (fold) plugin not found!")
    return
end

vim.wo.foldlevel = 99
vim.wo.foldenable = true

local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.foldingRange = {
    dynamicRegistration = false,
    lineFoldingOnly = true,
}

local handler = function(virtText, lnum, endLnum, width, truncate)
    local newVirtText = {}
    local suffix = ("  %d "):format(endLnum - lnum)
    local sufWidth = vim.fn.strdisplaywidth(suffix)
    local targetWidth = width - sufWidth
    local curWidth = 0
    for _, chunk in ipairs(virtText) do
        local chunkText = chunk[1]
        local chunkWidth = vim.fn.strdisplaywidth(chunkText)
        if targetWidth > curWidth + chunkWidth then
            table.insert(newVirtText, chunk)
        else
            chunkText = truncate(chunkText, targetWidth - curWidth)
            local hlGroup = chunk[2]
            table.insert(newVirtText, { chunkText, hlGroup })
            chunkWidth = vim.fn.strdisplaywidth(chunkText)
            -- str width returned from truncate() may less than 2nd argument, need padding
            if curWidth + chunkWidth < targetWidth then
                suffix = suffix .. (" "):rep(targetWidth - curWidth - chunkWidth)
            end
            break
        end
        curWidth = curWidth + chunkWidth
    end
    table.insert(newVirtText, { suffix, "MoreMsg" })
    return newVirtText
end

-- global handler
ufo.setup({
    fold_virt_text_handler = handler,
})
kevinhwang91 commented 2 years ago

I think I have set it in the configuration (see below):

local status_ok, ufo = pcall(require, "ufo")
if not status_ok then
  vim.notify("ufo (fold) plugin not found!")
  return
end

vim.wo.foldlevel = 99
vim.wo.foldenable = true

local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.foldingRange = {
  dynamicRegistration = false,
  lineFoldingOnly = true,
}

local handler = function(virtText, lnum, endLnum, width, truncate)
  local newVirtText = {}
  local suffix = ("  %d "):format(endLnum - lnum)
  local sufWidth = vim.fn.strdisplaywidth(suffix)
  local targetWidth = width - sufWidth
  local curWidth = 0
  for _, chunk in ipairs(virtText) do
      local chunkText = chunk[1]
      local chunkWidth = vim.fn.strdisplaywidth(chunkText)
      if targetWidth > curWidth + chunkWidth then
          table.insert(newVirtText, chunk)
      else
          chunkText = truncate(chunkText, targetWidth - curWidth)
          local hlGroup = chunk[2]
          table.insert(newVirtText, { chunkText, hlGroup })
          chunkWidth = vim.fn.strdisplaywidth(chunkText)
          -- str width returned from truncate() may less than 2nd argument, need padding
          if curWidth + chunkWidth < targetWidth then
              suffix = suffix .. (" "):rep(targetWidth - curWidth - chunkWidth)
          end
          break
      end
      curWidth = curWidth + chunkWidth
  end
  table.insert(newVirtText, { suffix, "MoreMsg" })
  return newVirtText
end

-- global handler
ufo.setup({
  fold_virt_text_handler = handler,
})

If you are using cmp:

local nvim_lsp = require('lspconfig')
local capabilities = require('cmp_nvim_lsp').update_capabilities(vim.lsp.protocol.make_client_capabilities())
capabilities.textDocument.foldingRange = {
    dynamicRegistration = false,
    lineFoldingOnly = true
}
local servers = {'gopls', 'yamlls'}
for _, ls in ipairs(servers) do
    nvim_lsp[ls].setup {
        capabilities = capabilities,
        on_attach = on_attach,
        flags = {debounce_text_changes = 150}
    }
end
zbindenren commented 2 years ago

this seems to work, thx