kevinhwang91 / nvim-ufo

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

Marker provider not works #233

Open shy-robin opened 1 month ago

shy-robin commented 1 month ago

Neovim version (nvim -v | head -n1)

0.10.0

Operating system/version

macOS 14.5

How to reproduce the issue

I can't use za to fold the range between // #region xxx and // #endregion markers. It will prompt the error: Cannot find fold.

https://github.com/user-attachments/assets/10abc167-fc9d-463b-8f46-180bb003de62

This is my lazyvim config:

-- Adding number suffix of folded lines instead of the default ellipsis
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

return {
  "kevinhwang91/nvim-ufo",
  dependencies = {
    "kevinhwang91/promise-async",
  },
  event = "BufRead",
  opts = {
    filetype_exclude = { "help", "alpha", "dashboard", "neo-tree", "Trouble", "lazy", "mason" },
  },
  keys = {
    {
      "zR",
      function()
        require("ufo").openAllFolds()
      end,
    },
    {
      "zM",
      function()
        require("ufo").closeAllFolds()
      end,
    },
    {
      "zr",
      function()
        require("ufo").openFoldsExceptKinds()
      end,
    },
    {
      "zm",
      function()
        require("ufo").closeFoldsWith()
      end,
    },
    -- 注意不要设置为 K,因为会被 LazyVim 设置的 K 覆盖
    -- TODO: conflict with coc
    {
      "gp",
      function()
        local winid = require("ufo").peekFoldedLinesUnderCursor()
        if not winid then
          vim.lsp.buf.hover()
        end
      end,
      desc = "Preview Fold",
    },
  },
  config = function()
    vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep: ,foldclose:]]
    -- 不需要设置,否则会有多余的间隙
    -- vim.o.foldcolumn = "1"
    vim.o.foldlevel = 99
    vim.o.foldlevelstart = 99
    vim.o.foldenable = true

    -- 清除折叠侧边栏所在列的高亮
    vim.api.nvim_set_hl(0, "FoldColumn", {})
    -- 高亮折叠的行
    vim.api.nvim_set_hl(0, "Folded", { bg = "#01579B" })

    require("ufo").setup({
      enable_get_fold_virt_text = true,
      open_fold_hl_timeout = 150,
      preview = {
        win_config = {
          border = { "╭", "─", "╮", "│", "╯", "─", "╰", "│" },
          winhighlight = "Normal:Folded",
          winblend = 0,
        },
        mappings = {
          -- TODO: conflict with coc
          -- scrollU = '<C-u>',
          -- scrollD = '<C-d>',
          jumpTop = "[",
          jumpBot = "]",
        },
      },
      fold_virt_text_handler = handler,
      provider_selector = function(bufnr, filetype, buftype)
        return { "treesitter", "marker" }
      end,
    })
  end,
}

Expected behavior

Fold the code between #region and #endregion like vscode.

Actual behavior

The code won't be folded and throw the error: cannot find fold.

kevinhwang91 commented 1 month ago

marker is a fallback provider with your config. For now, the ranges return from marker provider are not merged with the main provider.

Will make it become default behavior after solving the performance issue for marker.

dmmulroy commented 3 weeks ago

timely - was just coming to ask about this - is #219 what I should be watching for updates?

kevinhwang91 commented 3 weeks ago

Watching this issue is enough.

kevinhwang91 commented 2 weeks ago

Neovim can't handle the cross ranges like:

local ranges = {
  {
    endLine = 5,
    kind = "comment",
    startLine = 3
  }, {
    endLine = 7,
    kind = "marker",
    startLine = 4
  }
}

The two ranges are distorted and become [3,5] and [43,7]. You can enter visual selection mode and type zf to create two folds manually to verify the issue. echo foldlevel('.') may get the level under the cursor.

I have no idea how to solve this cross ranges issue. Users should decide which kind is a high priority range and discard the low priority by themselves.