kevinhwang91 / nvim-ufo

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

How can I make it look equal to its configuration #4

Closed CRAG666 closed 1 year ago

CRAG666 commented 2 years ago

Currently my line looks like this and I would like it to be seen as yours screen-1655388054

AGou-ops commented 1 year ago

neovim v0.9.0 src/nvim/screen.c --> src/nvim/drawline.c.

About line 421.

 418   for (i = 0; i < MIN(fdc, level); i++) {
 419     if (foldinfo.fi_lnum == lnum
 420         && first_level + i >= foldinfo.fi_low_level) {
 421       symbol = wp->w_p_fcs_chars.foldopen;
 422     } else if (first_level == 1) {
 423       symbol = wp->w_p_fcs_chars.foldsep;
 424     } else if (first_level + i <= 9) {
 425       symbol = '0' + first_level + i;
 426     } else {
 427       symbol = '>';
 428     }
pedropombeiro commented 1 year ago

@kevinhwang91 Now that Neovim 0.9.0 is out, what is the right way to enable this look?

rockyzhang24 commented 1 year ago

@pedropombeiro Now the plugin statuscol.nvim is stable enough and is worth a trying. The alternative approach is to change the code in screen.c (that was refactored and renamed to drawline.c) directly and build neovim by yourself.

jellydn commented 1 year ago

Here is my entire UFO + Folding preview config, just in case someone needs this.

  1. Setup folding option

    -- UFO folding
    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
    vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep: ,foldclose:]]
  2. Install the plugin with lazy.nvim

    return {
    -- UFO folding
    {
    "kevinhwang91/nvim-ufo",
    dependencies = {
      "kevinhwang91/promise-async",
      {
        "luukvbaal/statuscol.nvim",
        config = function()
          local builtin = require("statuscol.builtin")
          require("statuscol").setup({
            relculright = true,
            segments = {
              { text = { builtin.foldfunc }, click = "v:lua.ScFa" },
              { text = { "%s" }, click = "v:lua.ScSa" },
              { text = { builtin.lnumfunc, " " }, click = "v:lua.ScLa" },
            },
          })
        end,
      },
    },
    event = "BufReadPost",
    opts = {
      provider_selector = function()
        return { "treesitter", "indent" }
      end,
    },
    
    init = function()
      vim.keymap.set("n", "zR", function()
        require("ufo").openAllFolds()
      end)
      vim.keymap.set("n", "zM", function()
        require("ufo").closeAllFolds()
      end)
    end,
    },
    -- Folding preview, by default h and l keys are used.
    -- On first press of h key, when cursor is on a closed fold, the preview will be shown.
    -- On second press the preview will be closed and fold will be opened.
    -- When preview is opened, the l key will close it and open fold. In all other cases these keys will work as usual.
    { "anuvyklack/fold-preview.nvim", dependencies = "anuvyklack/keymap-amend.nvim", config = true },
    }

Demo: https://gyazo.com/f5d5019313deed7c01faed43aa6e064f.gif

awerebea commented 1 year ago

Let me join the party and share my config with one small extra "feature" of displaying the number of hidden rows near the colorcolumn or window edge (whichever is smaller).

return {
  "kevinhwang91/nvim-ufo",
  dependencies = "kevinhwang91/promise-async",
  event = "VeryLazy",
  opts = {
    -- INFO: Uncomment to use treeitter as fold provider, otherwise nvim lsp is used
    -- provider_selector = function(bufnr, filetype, buftype)
    --   return { "treesitter", "indent" }
    -- end,
    open_fold_hl_timeout = 400,
    close_fold_kinds = { "imports", "comment" },
    preview = {
      win_config = {
        border = { "", "─", "", "", "", "─", "", "" },
        -- winhighlight = "Normal:Folded",
        winblend = 0,
      },
      mappings = {
        scrollU = "<C-u>",
        scrollD = "<C-d>",
        jumpTop = "[",
        jumpBot = "]",
      },
    },
  },
  init = function()
    vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep: ,foldclose:]]
    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
  end,
  config = function(_, opts)
    local handler = function(virtText, lnum, endLnum, width, truncate)
      local newVirtText = {}
      local totalLines = vim.api.nvim_buf_line_count(0)
      local foldedLines = endLnum - lnum
      local suffix = ("  %d %d%%"):format(foldedLines, foldedLines / totalLines * 100)
      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
      local rAlignAppndx =
        math.max(math.min(vim.opt.textwidth["_value"], width - 1) - curWidth - sufWidth, 0)
      suffix = (" "):rep(rAlignAppndx) .. suffix
      table.insert(newVirtText, { suffix, "MoreMsg" })
      return newVirtText
    end
    opts["fold_virt_text_handler"] = handler
    require("ufo").setup(opts)
    vim.keymap.set("n", "zR", require("ufo").openAllFolds)
    vim.keymap.set("n", "zM", require("ufo").closeAllFolds)
    vim.keymap.set("n", "zr", require("ufo").openFoldsExceptKinds)
    vim.keymap.set("n", "K", function()
      local winid = require("ufo").peekFoldedLinesUnderCursor()
      if not winid then
        -- vim.lsp.buf.hover()
        vim.cmd [[ Lspsaga hover_doc ]]
      end
    end)
  end,
}

Examples:

2023-04-19_145514 2023-04-19_145601
sudoCompetence commented 1 year ago

@awerebea thats just amazing.

However the arrow and percentage for me appear where the code ends not and the end of the window like yours. How did you modify the 'hidden' data to be at the end of the window?

awerebea commented 1 year ago

Hey @sudoCompetence! Glad you like it.

How did you modify... ?

Well, I just took the example from Customize fold text and modified it to take into account the textwidth property, so in my implementation, the position actually depends on texdtwidth but not on colorcolumn, sorry for the confusion.

This is the diff of the changes made: image

MariaSolOs commented 1 year ago

Idk if it's just me, but on nightly I had to change my statuscol config to include disable_ft = { 'trouble' }, else Neovim crashes with a 134 exit code. Curious to know if anyone else experienced something similar.

nick22985 commented 5 months ago

@awerebea thats just amazing.

However the arrow and percentage for me appear where the code ends not and the end of the window like yours. How did you modify the 'hidden' data to be at the end of the window?

Sorry for commenting on this again but also wanted to make it so that the fold was all the way to the right so for those in the future that want this here. You can do it by doing the below: https://github.com/kevinhwang91/nvim-ufo/issues/4#issuecomment-1514537245

replace this line:

local rAlignAppndx = math.max(math.min(vim.opt.textwidth["_value"], width - 1) - curWidth - sufWidth, 0)

with

local rAlignAppndx = math.max(math.min(vim.api.nvim_win_get_width(0), width - 1) - curWidth - sufWidth, 0)

This will put the fold text as far width-wise as your buffer is

Example: 28cf1c538b6970e74ebc76a3de326c52

awerebea commented 5 months ago

Hi @nick22985, Well, please feel free to change this snippet this way if you prefer this implementation. 😉 But for me personally, my original way looks better.

The proposed change only affects the display in a wide window, but I'm just used to limiting the width of the text in the window (99 characters for the Lua file type in this example). So it doesn't make much sense for me to place the fold text as far in width as the window of my current buffer.

I set the colorcolumn value equal to +1 for clarity in the following screenshots. wide window: proposed change ufo_0 current ufo_1 tight window: ufo_2 really long line with fold: ufo_3

Again, it's just a matter of taste. In my opinion, all these cases are better covered by my current implementation, but it's obviously up to you to decide which way to use for yourself.

Thank you for your participation!

geloman-likes-rust commented 3 months ago

I have this minimal config for nvim-ufo and it looks amazing to me. Screenshot from 2024-07-20 at 21:55:13

Additional - adding vim.o.foldcolumn = 'auto:9' will remove the annoying random number on foldcolumn and also adjust the foldcolumn size/width accordingly. Just simply add this on your config.

vim.o.foldcolumn = 'auto:9'