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:]] vim.o.statuscolumn = "%s" -- sign column .. "%=" .. "%{%" -- evaluate this, and then evaluate what it returns .. "&number ?" .. "(v:relnum ?" -- when showing relative numbers, make sure to pad so things don't shift as you move the cursor .. 'printf("%"..len(line("$")).."s", v:relnum)' .. ":" .. "v:lnum" .. ")" .. ":" .. '""' .. "%}" .. "%#FoldColumn#" -- highlight group for fold .. "%{" -- expression for showing fold expand/colapse .. "foldlevel(v:lnum) > foldlevel(v:lnum - 1)" -- any folds? .. "? (foldclosed(v:lnum) == -1" -- currently open? .. '? ""' -- point down .. ': ""' -- point to right .. ")" .. ': " "' -- blank for no fold, or inside fold .. "}" .. " " local ftMap = { vim = "indent", python = { "indent" }, git = "", } ---@param bufnr number ---@return Promise local function customizeSelector(bufnr) local function handleFallbackException(err, providerName) if type(err) == "string" and err:match("UfoFallbackException") then return require("ufo").getFolds(bufnr, providerName) else return require("promise").reject(err) end end return require("ufo") .getFolds(bufnr, "lsp") :catch(function(err) return handleFallbackException(err, "treesitter") end) :catch(function(err) return handleFallbackException(err, "indent") end) end 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 require("ufo").setup({ provider_selector = function(_, filetype, _) return ftMap[filetype] or customizeSelector end, fold_virt_text_handler = handler, }) -- Using ufo provider need remap `zR` and `zM`. If Neovim is 0.6.1, remap yourself require("which-key").register({ z = { R = { require("ufo").openAllFolds, "Open all folds" }, M = { require("ufo").closeAllFolds, "Close all folds" }, }, })