diff --git a/plugins/default.nix b/plugins/default.nix index 8300b4dd..66dab56b 100644 --- a/plugins/default.nix +++ b/plugins/default.nix @@ -101,6 +101,7 @@ ./utils/nvim-bqf.nix ./utils/nvim-colorizer.nix ./utils/nvim-osc52.nix + ./utils/nvim-ufo.nix ./utils/oil.nix ./utils/project-nvim.nix ./utils/presence-nvim.nix diff --git a/plugins/utils/nvim-ufo.nix b/plugins/utils/nvim-ufo.nix new file mode 100644 index 00000000..2913b26f --- /dev/null +++ b/plugins/utils/nvim-ufo.nix @@ -0,0 +1,82 @@ +{ + pkgs, + config, + lib, + ... +}: +with lib; let + cfg = config.plugins.nvim-ufo; + helpers = import ../helpers.nix {inherit lib;}; +in { + options.plugins.nvim-ufo = + helpers.extraOptionsOptions + // { + enable = mkEnableOption "nvim-ufo"; + + package = helpers.mkPackageOption "nvim-ufo" pkgs.vimPlugins.nvim-ufo; + + openFoldHlTimeout = helpers.defaultNullOpts.mkInt 400 '' + Time in millisecond between the range to be highlgihted and to be cleared + while opening the folded line, `0` value will disable the highlight + ''; + + providerSelector = helpers.defaultNullOpts.mkStr "null" '' + A lua function as a selector for fold providers. + ''; + + closeFoldKinds = helpers.mkNullOrOption types.attrs '' + After the buffer is displayed (opened for the first time), close the + folds whose range with `kind` field is included in this option. For now, + 'lsp' provider's standardized kinds are 'comment', 'imports' and 'region', + run `UfoInspect` for details if your provider has extended the kinds. + ''; + + foldVirtTextHandler = helpers.defaultNullOpts.mkStr "null" "A lua function to customize fold virtual text"; + + enableGetFoldVirtText = helpers.defaultNullOpts.mkBool false '' + Enable a function with `lnum` as a parameter to capture the virtual text + for the folded lines and export the function to `get_fold_virt_text` field of + ctx table as 6th parameter in `fold_virt_text_handler` + ''; + + preview = { + winConfig = { + border = + helpers.defaultNullOpts.mkNullable (types.either types.str (types.listOf types.str)) "rounded" + "The border for preview window, `:h nvim_open_win() | call search('border:')`"; + + winblend = helpers.defaultNullOpts.mkInt 12 "The winblend for preview window, `:h winblend`"; + + winhighlight = helpers.defaultNullOpts.mkStr "Normal:Normal" "The winhighlight for preview window, `:h winhighlight`"; + + maxheight = helpers.defaultNullOpts.mkInt 20 "The max height of preview window"; + }; + + mappings = helpers.mkNullOrOption types.attrs "Mappings for preview window"; + }; + }; + + config = let + options = with cfg; + { + open_fold_hl_timeout = openFoldHlTimeout; + provider_selector = helpers.ifNonNull' providerSelector (helpers.mkRaw providerSelector); + close_fold_kinds = closeFoldKinds; + fold_virt_text_handler = helpers.ifNonNull' foldVirtTextHandler (helpers.mkRaw foldVirtTextHandler); + enable_get_fold_virt_text = enableGetFoldVirtText; + + preview = with preview; { + inherit mappings; + win_config = winConfig; + }; + } + // cfg.extraOptions; + in + mkIf cfg.enable { + extraPlugins = [cfg.package]; + + extraConfigLua = '' + require("ufo").setup(${helpers.toLuaObject options}) + ''; + }; +} diff --git a/tests/test-sources/plugins/utils/nvim-ufo.nix b/tests/test-sources/plugins/utils/nvim-ufo.nix new file mode 100644 index 00000000..e0386119 --- /dev/null +++ b/tests/test-sources/plugins/utils/nvim-ufo.nix @@ -0,0 +1,72 @@ +{ + empty = { + plugins.nvim-ufo.enable = true; + }; + + example = { + plugins.nvim-ufo = { + enable = true; + providerSelector = '' + function(bufnr, filetype, buftype) + local ftMap = { + vim = "indent", + python = {"indent"}, + git = "" + } + + return ftMap[filetype] + end + ''; + + foldVirtTextHandler = '' + 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 + ''; + }; + }; + + defaults = { + plugins.nvim-ufo = { + enable = true; + openFoldHlTimeout = 400; + providerSelector = null; + closeFoldKinds = {}; + foldVirtTextHandler = null; + enableGetFoldVirtText = false; + preview = { + winConfig = { + border = "rounded"; + winblend = 12; + winhighlight = "Normal:Normal"; + maxheight = 20; + }; + mappings = {}; + }; + }; + }; +}