Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance zC and zO #42

Open
kevinhwang91 opened this issue Jul 5, 2022 · 4 comments
Open

Enhance zC and zO #42

kevinhwang91 opened this issue Jul 5, 2022 · 4 comments
Labels
enhancement New feature or request

Comments

@kevinhwang91
Copy link
Owner

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 kevinhwang91 added the enhancement New feature or request label Jul 5, 2022
@kevinhwang91
Copy link
Owner Author

kevinhwang91 commented Oct 4, 2022

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
Copy link

Andrew15-5 commented Mar 14, 2024

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
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 = { "<PageUp>", "<C-u>" },
      -- scrollD = { "<PageDown>", "<C-d>" },
      scrollU = "<PageUp>",
      scrollD = "<PageDown>",
      jumpTop = "[",
      jumpBot = "]",
    },
  },
}
  { -- folds
    "kevinhwang91/nvim-ufo",
    dependencies = "kevinhwang91/promise-async",
    config = function()
      require "custom.configs.ufo"
    end,
  },

@kevinhwang91
Copy link
Owner Author

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
Copy link

I did follow and it looks like nothing helps. I posted an issue: #206.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants