kevinhwang91 / nvim-ufo

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

Conflict between ufo and reactive.nvim causes weird behavior of nvim-cmp scroll_docs #223

Closed b1nhack closed 1 month ago

b1nhack commented 1 month ago

Neovim version (nvim -v | head -n1)

NVIM v0.10.0

Operating system/version

macOS 14.5

How to reproduce the issue

As per the documentation, I have the following minimal configuration:

vim.o.foldcolumn = "0" -- '0' is not bad
vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value
vim.o.foldlevelstart = 99
vim.o.foldenable = true

require("ufo").setup({
    provider_selector = function(bufnr, filetype, buftype)
    return { "treesitter", "indent" }
    end,
})

nvim-cmp has the following keymap:

["<C-h>"] = cmp.mapping(function(fallback) 
    if cmp.visible_docs() then             
        cmp.scroll_docs(-5)                
    else                                   
        fallback()                         
    end                                    
end),                                      
["<C-b>"] = cmp.mapping(function(fallback) 
    if cmp.visible_docs() then             
        cmp.scroll_docs(5)                 
    else                                   
        fallback()                         
    end                                    
end),                                      

At this point, the scroll_docs function will cause some confusion. vim.o.foldenable = true does not cause problems when ufo is disabled.

Expected behavior

nvim-cmp scroll_docs normal behavior.

Actual behavior

nvim-cmp scroll_docs causes confusion.

kevinhwang91 commented 1 month ago

what's error msg?

b1nhack commented 1 month ago

what's error msg?

No error message, just scroll_docs causes strange behavior, cmp.scroll_docs() moves my cursor forward one character, and the autocomplete window goes back to its original state

b1nhack commented 1 month ago

I did more testing, and it turns out that the problem has nothing to do with vim.o.foldenable, but with ufo itself!

kevinhwang91 commented 1 month ago

can't reproduce it.

b1nhack commented 1 month ago

can't reproduce it.

Okay, I'll try to make a minimal configuration. There may be other conflicts.

b1nhack commented 1 month ago

I'm sorry, using ufo and nvim-cmp minimal configuration did not cause the problem. It should be other plugins and ufo that caused the problem, because if I disable ufo, everything works fine. I will continue testing.

b1nhack commented 1 month ago

In fact, reactive.nvim and ufo have some conflicts, which will cause this problem when they exist at the same time. I don't know who is the source of the problem. The minimum configuration is as follows:

-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify("./.repro", ":p")

-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
    vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
    vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
    {
        "rasulomaroff/reactive.nvim",

        config = function()
            require("reactive").setup({
                builtin = {
                    cursorline = true,
                    cursor = true,
                    modemsg = true,
                },
            })
        end,
    },

    {
        "williamboman/mason.nvim",

        config = function()
            require("mason").setup()
        end,
    },
    {
        "WhoIsSethDaniel/mason-tool-installer.nvim",

        config = function()
            require("mason-tool-installer").setup({
                ensure_installed = {
                    "lua-language-server",
                },
            })
        end,
    },
    {
        "neovim/nvim-lspconfig",

        config = function()
            require("lspconfig").lua_ls.setup({})
        end,
    },
    {
        "hrsh7th/nvim-cmp",
        dependencies = {
            "hrsh7th/cmp-nvim-lsp",
        },

        config = function()
            local cmp = require("cmp")

            cmp.setup({
                mapping = {
                    ["<C-u>"] = cmp.mapping(function(fallback)
                        if cmp.visible() then
                            cmp.select_prev_item()
                        else
                            fallback()
                        end
                    end),
                    ["<C-e>"] = cmp.mapping(function(fallback)
                        if cmp.visible() then
                            cmp.select_next_item()
                        else
                            fallback()
                        end
                    end),

                    ["<C-h>"] = cmp.mapping(function(fallback)
                        if cmp.visible_docs() then
                            cmp.scroll_docs(-5)
                        else
                            fallback()
                        end
                    end),
                    ["<C-b>"] = cmp.mapping(function(fallback)
                        if cmp.visible_docs() then
                            cmp.scroll_docs(5)
                        else
                            fallback()
                        end
                    end),
                },
                sources = cmp.config.sources({
                    { name = "nvim_lsp" },
                }),
            })
        end,
    },

    {
        "nvim-treesitter/nvim-treesitter",

        config = function()
            require("nvim-treesitter.configs").setup({
                ensure_installed = { "c", "lua", "vim", "vimdoc", "query" },
            })
        end,
    },
    {
        "kevinhwang91/nvim-ufo",
        dependencies = {
            "kevinhwang91/promise-async",
        },

        config = function()
            vim.o.foldcolumn = "1" -- '0' is not bad
            vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value
            vim.o.foldlevelstart = 99
            vim.o.foldenable = true

            -- Using ufo provider need remap `zR` and `zM`. If Neovim is 0.6.1, remap yourself
            vim.keymap.set("n", "zR", require("ufo").openAllFolds)
            vim.keymap.set("n", "zM", require("ufo").closeAllFolds)

            require("ufo").setup({
                provider_selector = function(bufnr, filetype, buftype)
                    return { "treesitter", "indent" }
                end,
            })
        end,
    },
}
require("lazy").setup(plugins, {
    root = root .. "/plugins",
})
kevinhwang91 commented 1 month ago

The issue is complex. reactive.nvim fires a redraw, and then ufo invokes vim.api.nvim_win_call to make the floating window of nvim-cmp broken.

I'm not sure if there's an issue of vim.api.nvim_set_decoration_provider used by ufo.

b1nhack commented 1 month ago

In which repository do you think this problem would be more simple and elegant to solve? Or should it be solved in conjunction with the reactive.nvim contributors?

kevinhwang91 commented 1 month ago

Solved by ufo.

b1nhack commented 1 month ago

Ha ha ha, let me know if you need any help.