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

Enhance `zC` and `zO` #42

Open kevinhwang91 opened 2 years ago

kevinhwang91 commented 2 years ago

Feature description

Sometimes it's too unexpected while typing zC and zO.

Describe the solution you'd like

Use a selector with a preview based on foldlevel to show the result.

Additional context

No response

kevinhwang91 commented 1 year ago
local function hateRepeatFold(char)
    local function setScrollOff(val)
        local view = vim.fn.winsaveview()
        vim.wo.so = val
        vim.fn.winrestview(view)
    end

    local event = require('ufo.lib.event')
    event:emit('setOpenFoldHl')
    vim.keymap.set('n', 'h', function()
        local shouldClose = vim.fn.foldlevel('.') ~= 0
        if shouldClose then
            event:emit('setOpenFoldHl', false)
            setScrollOff(10)
        end
        return shouldClose and 'zc' or 'h'
    end, {buffer = 0, expr = true})
    vim.keymap.set('n', 'l', function()
        local shouldOpen = vim.fn.foldclosed('.') ~= -1
        if shouldOpen then
            event:emit('setOpenFoldHl', false)
            setScrollOff(10)
        end
        return shouldOpen and 'zo' or 'l'
    end, {buffer = 0, expr = true})
    vim.api.nvim_create_autocmd('CursorMoved', {
        group = vim.api.nvim_create_augroup('HateRepeatFoldAug', {}),
        buffer = 0,
        once = true,
        callback = function()
            pcall(vim.keymap.del, 'n', 'h', {buffer = 0})
            pcall(vim.keymap.del, 'n', 'l', {buffer = 0})
            setScrollOff(0)
            event:emit('setOpenFoldHl')
        end
    })
    return 'mzz' .. char
end

for _, c in ipairs({'c', 'o', 'a', 'C', 'O', 'A', 'v'}) do
    vim.keymap.set('n', 'z' .. c, function() return hateRepeatFold(c) end, {expr = true})
end

I'm using this script to improve native fold actions. Any feedbacks are welcome. If this is not bad, only export an API to enable/disable open fold highlighting on-the-fly.

Andrew15-5 commented 5 months ago
n  zO          * <Lua 406: ~/.config/nvim/lua/custom/configs/ufo.lua:74>
        Last set from Lua                                               

https://github.com/kevinhwang91/nvim-ufo/assets/37143421/69d2703a-0c4a-4330-9104-5648820c6659

I think I have a pretty reasonable workflow: hide everything with zM, then only open what I need with zo or zO, but when editing it automatically closes the opened fold. This is really annoying, and it not only happens with the default keymaps, but also with the snippet above. I really thought it would fix it, but it doesn't. Do you know why it does that? But works fine after zR?

my setup ```lua 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 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 -- `handler` is the 2nd parameter of `setFoldVirtTextHandler`, -- check out `./lua/ufo.lua` and search `setFoldVirtTextHandler` for detail. require("ufo").setup { fold_virt_text_handler = handler, open_fold_hl_timeout = 150, -- close_fold_kinds = { "imports", "comment" }, preview = { win_config = { -- border = { "", "─", "", "", "", "─", "", "" }, winhighlight = "Normal:Folded", winblend = 0, }, mappings = { -- scrollU = { "", "" }, -- scrollD = { "", "" }, scrollU = "", scrollD = "", jumpTop = "[", jumpBot = "]", }, }, } ``` ```lua { -- folds "kevinhwang91/nvim-ufo", dependencies = "kevinhwang91/promise-async", config = function() require "custom.configs.ufo" end, }, ```
kevinhwang91 commented 5 months ago
n  zO          * <Lua 406: ~/.config/nvim/lua/custom/configs/ufo.lua:74>
        Last set from Lua                                               

auto-close-folds.mp4 I think I have a pretty reasonable workflow: hide everything with zM, then only open what I need with zo or zO, but when editing it automatically closes the opened fold. This is really annoying, and it not only happens with the default keymaps, but also with the snippet above. I really thought it would fix it, but it doesn't. Do you know why it does that? But works fine after zR?

my setup

Not related to this issue, please follow the setup in README and check out your foldlevel.

Andrew15-5 commented 5 months ago

I did follow and it looks like nothing helps. I posted an issue: https://github.com/kevinhwang91/nvim-ufo/issues/206.