snacks.nvim icon indicating copy to clipboard operation
snacks.nvim copied to clipboard

bug(statuscolumn): Adjacent folds not displaying correctly with foldopen

Open gczcn opened this issue 9 months ago • 11 comments

Did you check docs and existing issues?

  • [x] I have read all the snacks.nvim docs
  • [x] I have updated the plugin to the latest version before submitting this issue
  • [x] I have searched the existing issues of snacks.nvim
  • [x] I have searched the existing issues of plugins related to this issue

Neovim version (nvim -v)

0.11.0-dev-1930+gb2fa51bf15

Operating system/version

macOS 15.3.1

Describe the bug

When there are two adjacent folds, the part that determines whether a line is the beginning of a fold may not work properly. This is because when two folds are adjacent, the foldlevel of the previous line of the latter fold may be the same as that of the previous line, causing this line to be considered a line in a fold.

a simple example:

Image

line 361 does not display the foldopen symbol.

Steps To Reproduce

  1. Ensure the statuscolumn section in the configuration has the open option set to true
  2. Create a lua file and enter the following content, making sure there are adjacent folds in the file
if true then
  print('true')
end
if false then
  print('false')
end
  1. Problem occurs

Expected Behavior

Correctly display foldopen symbols for adjacent folds.

Repro

vim.o.foldlevel = 99
vim.o.foldmethod = 'expr'
vim.o.foldexpr = "v:lua.vim.treesitter.foldexpr()"
vim.env.LAZY_STDPATH = ".repro"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()

require("lazy.minit").repro({
  spec = {
    {
      "folke/snacks.nvim",
      opts = {
        statuscolumn = {
          folds = {
            open = true,
          },
        },
      },
    },

    -- install the treesitter parser for lua
    {
      "nvim-treesitter/nvim-treesitter",
      opts = {
        ensure_installed = { 'lua' },
      },
    },
  },
})

-- Example
if true then
  -- ...
end
if false then
  -- ...
end

gczcn avatar Mar 08 '25 14:03 gczcn

That's because vim.fn.foldlevel() which is used by the statuscolumn returns the same number of level folding for those mappings.

vim.keymap.set("n", "t", function()    <-- foldlevel is some number here
  fadskfjas
end)
vim.keymap.set("n", "s", function()    <-- foldlevel here is the same as the previous
  fjasiofaja
end)

The opened markers show up only at lines where the foldlevel is not the same between the current and previous line.

dpetka2001 avatar Mar 08 '25 15:03 dpetka2001

Actually, if we change the line here https://github.com/folke/snacks.nvim/blob/bc0630e43be5699bb94dadc302c0d21615421d93/lua/snacks/statuscolumn.lua#L147 with the following elseif config.folds.open and vim.treesitter.foldexpr(vim.v.lnum):sub(1, 1) == ">" then I believe it behaves more to how you describe.

dpetka2001 avatar Mar 08 '25 15:03 dpetka2001

Actually, if we change the line here

snacks.nvim/lua/snacks/statuscolumn.lua

Line 147 in bc0630e

elseif config.folds.open and vim.fn.foldlevel(lnum) > vim.fn.foldlevel(lnum - 1) then with the following elseif config.folds.open and vim.treesitter.foldexpr(vim.v.lnum):sub(1, 1) == ">" then I believe it behaves more to how you describe.

For me, this solved the problem. However, as described in this issue, using vim.treesitter.foldexpr() will only allow folds provided by treesitter.

gczcn avatar Mar 08 '25 16:03 gczcn

Sorry, I just closed this question by accident.

gczcn avatar Mar 08 '25 16:03 gczcn

I see, you're right. I wasn't aware of that issue. Then probably my PR which essentially reverts the change that was made for that issue you mentioned will be denied. I'm not aware of a better solution in this case.

Hopefully, maintainer will have a better idea with regards to this. Maybe it's possible maybe not. But vim.fn.foldlevel() only returns the level which for adjacent foldings will be the same.

I'll close my PR and wait for maintainer's input.

dpetka2001 avatar Mar 08 '25 16:03 dpetka2001

The statuscol.nvim plugin can handle this situation correctly, but I can't understand its code.

gczcn avatar Mar 09 '25 04:03 gczcn

I pushed a change which somewhat takes into consideration vim.lsp.foldexpr() as well, but there's a small caveat (which I mention in my PR).

I'm sure maintainer will have a more proper answer with regards to that.

dpetka2001 avatar Mar 09 '25 09:03 dpetka2001

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Apr 09 '25 02:04 github-actions[bot]

Not stale.

dpetka2001 avatar Apr 09 '25 06:04 dpetka2001

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar May 10 '25 02:05 github-actions[bot]

Not stale

dpetka2001 avatar May 10 '25 02:05 dpetka2001

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Jun 10 '25 02:06 github-actions[bot]

Go sleep

dpetka2001 avatar Jun 10 '25 06:06 dpetka2001

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Jul 31 '25 02:07 github-actions[bot]

Shh

dpetka2001 avatar Jul 31 '25 03:07 dpetka2001

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Sep 01 '25 02:09 github-actions[bot]

.

dpetka2001 avatar Sep 01 '25 04:09 dpetka2001

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Oct 03 '25 02:10 github-actions[bot]

🤔

gczcn avatar Oct 03 '25 03:10 gczcn