function TABLE_CONTAINS(tbl, x) local found = false for _, v in pairs(tbl) do if v == x then found = true end end return found end local icons = vim.g.pcode_icons.folding local M = {} if vim.g.pcode_nvimufo then M.ufo = { "kevinhwang91/nvim-ufo", dependencies = { "kevinhwang91/promise-async", { "luukvbaal/statuscol.nvim", config = function() local builtin = require "statuscol.builtin" require("statuscol").setup { setopt = true, relculright = true, segments = { { text = { "%s" }, click = "v:lua.ScSa" }, { text = { builtin.foldfunc }, condition = { builtin.not_empty, true, builtin.not_empty }, click = "v:lua.ScFa", }, { text = { builtin.lnumfunc, " " }, click = "v:lua.ScLa" }, }, } end, }, }, enabled = true, lazy = true, event = "VeryLazy", 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 -- vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep: ,foldclose:]] -- vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep: ,foldclose:]] -- vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep:│,foldclose:]] -- vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep:│,foldclose:]] -- vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep:│,foldclose:]] -- vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep:│,foldclose:]] -- vim.o.fillchars = [[eob: ,fold: ,foldopen:▾,foldsep:│,foldclose:▸]] vim.opt.fillchars = { vert = icons.vert, fold = icons.fold, eob = icons.eob, diff = icons.diff, msgsep = icons.msgsep, foldopen = icons.foldopen, foldsep = icons.foldsep, foldclose = icons.foldclose, } -- these are "extra", change them as you like vim.keymap.set("n", "zR", require("ufo").openAllFolds) vim.keymap.set("n", "zM", require("ufo").closeAllFolds) vim.cmd("highlight FoldColumn guifg=" .. vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID "Comment"), "fg")) -- start ini bagian code support comment dan import local ftMap = { vim = "indent", python = { "indent" }, git = "", } 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 require("ufo").setup { open_fold_hl_timeout = 150, close_fold_kinds_for_ft = { -- default = { "imports", "comment" }, -- json = { "array" }, -- c = { "comment", "region" }, }, preview = { win_config = { border = { "", "─", "", "", "", "─", "", "" }, winhighlight = "Normal:Folded", winblend = 0, }, mappings = { scrollU = "<C-u>", scrollD = "<C-d>", jumpTop = "[", jumpBot = "]", }, }, provider_selector = function(bufnr, filetype, buftype) return ftMap[filetype] or customizeSelector end, fold_virt_text_handler = function(virt_text, lnum, end_lnum, width, truncate) local result = {} local closed_fold_text = "comments ..." -- Teks yang ingin ditampilkan local import_fold_text = "import ..." -- Teks yang ingin ditampilkan local is_comment = false -- Variabel untuk mengecek apakah ini komentar local is_import = false local is_bracket = false -- Memeriksa apakah baris awal dari fold adalah komentar local start_line = vim.api.nvim_buf_get_lines(0, lnum - 1, lnum, false)[1] -- cari comentar dengan awalan /* untuk generaal comment if start_line:find "^%s*%/%*" then is_comment = true -- cara commentar dengan awalan <!-- untuk html elseif start_line:find "^%s*<!--" then is_comment = true -- cari comentar dengan awalan -- untuk lua elseif start_line:find "^%s*%-%-" then is_comment = true end -- cek fold yang berawalan import if start_line:find "^%s*import" then is_import = true end -- cek fold dengan akhiran { if start_line:find "%s*{%s*$" then is_bracket = true end if is_comment then local suffix = string.format(" %s ", closed_fold_text) local target_width = width - vim.fn.strdisplaywidth(suffix) local cur_width = 0 for _, chunk in ipairs(virt_text) do local chunk_text = chunk[1] local chunk_width = vim.fn.strdisplaywidth(chunk_text) if target_width > cur_width + chunk_width then table.insert(result, chunk) else chunk_text = truncate(chunk_text, target_width - cur_width) local hl_group = chunk[2] table.insert(result, { chunk_text, hl_group }) break end cur_width = cur_width + chunk_width end -- Menambahkan teks 'Comments ...' ke akhir baris yang dilipat table.insert(result, { suffix, "NonText" }) elseif is_import then local suffix = (" %d "):format(end_lnum - lnum) local sufWidth = vim.fn.strdisplaywidth(suffix) local targetWidth = width - sufWidth local curWidth = 0 for _, chunk in ipairs(virt_text) do local chunkText = chunk[1] local chunkWidth = vim.fn.strdisplaywidth(chunkText) if targetWidth > curWidth + chunkWidth then table.insert(result, chunk) else chunkText = truncate(chunkText, targetWidth - curWidth) local hlGroup = chunk[2] table.insert(result, { 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(result, { " import⋯ ", "NonText" }) table.insert(result, { suffix, "MoreMsg" }) else local _end = end_lnum - 1 local final_text = vim.trim(vim.api.nvim_buf_get_text(0, _end, 0, _end, -1, {})[1]) local suffix = final_text:format(end_lnum - lnum) local suffix_width = vim.fn.strdisplaywidth(suffix) local target_width = width - suffix_width local cur_width = 0 for _, chunk in ipairs(virt_text) do local chunk_text = chunk[1] local chunk_width = vim.fn.strdisplaywidth(chunk_text) if target_width > cur_width + chunk_width then table.insert(result, chunk) else chunk_text = truncate(chunk_text, target_width - cur_width) local hl_group = chunk[2] table.insert(result, { chunk_text, hl_group }) chunk_width = vim.fn.strdisplaywidth(chunk_text) -- str width returned from truncate() may less than 2nd argument, need padding if cur_width + chunk_width < target_width then suffix = suffix .. (" "):rep(target_width - cur_width - chunk_width) end break end cur_width = cur_width + chunk_width end table.insert(result, { " ⋯ ", "NonText" }) local l = { "javascriptreact", "typescriptreact" } if TABLE_CONTAINS(l, vim.bo.filetype) and not is_bracket then table.insert(result, { suffix, "TSPunctBracket" }) end end return result end, } -- end bagian code support comment dan import vim.api.nvim_create_autocmd("FileType", { pattern = { "NvimTree", "lazy", "mason", }, callback = function() require("ufo").detach() vim.opt_local.foldenable = false end, }) end, } else M.ufo = {} end return M.ufo