A fancier way to fold your code.
- Dynamic foldtext. Can be customised per-buffer & per-window.
- Allows customizing the foldtext with parts to make the process easier. Each part can also be individually enabled/disabled.
- Completely different foldtext based on filetype, buftype & conditions.
Foldtext.nvim
can be installed via your favourite package managers.
For lazy.lua
/plugins.lua
users.
{
"OXY2DEV/foldtext.nvim",
lazy = false
}
For plugins/foldtext.lua
users.
return {
"OXY2DEV/foldtext.nvim",
lazy = false
}
local MiniDeps = require("mini.deps");
MiniDeps.add({
source = "OXY2DEV/foldtext.nvim"
});
You can install the plugin via rocks.nvim
with the following command.
:Rocks install foldtext.nvim
Folds in markdown starting with a line containing <summary></summary>
will show the text inside it.
Try setting your foldmethod
to indent
and see what this code block looks like.
<detail>
<summary>An example summary</summary>
Some text
</detail>
You will see something like this.
This also works in other foldmethods
too!
In a lua
file, if a fold's starting line contains ${}
with some text inside this will render as a custom fold.
For example, folding this text will show a lua icon on the fold text
-- ${default}
vim.print("Hello neovim");
You can also add titles to your folds.
-- ${func, A helper function}
local function test()
vim.print("Test");
end
This becomes something like this,
They also have various options,
- default, shows the lua logo
- conf, shows a cog
- ui, shows a phone
- func, shows a function symbol
- hl, shows a palette symbol
- calc, shows a calculator
- dep, shows a box
Foldtext's configuration table is as follows
{
ft_ignore = {}, -- file types to ignore
bt_ignore = {}, -- buf types to ignore
default = {}, -- default fold text configuration
custom = {} -- Condition based fold text configurations
}
Foldtexts are created with parts. Each part is a table that shows some text in the foldtext.
Foldtext come with a few parts to get you started with creating foldtexts.
{
type = "raw", -- Part type
condition = function (win, buf)
-- Condition for the part
return true;
end
}
Shows some string in the fold text.
{
type = "raw",
text = "Fold",
hl = "Folded"
}
Shows the number of lines folded.
{
type = "fold_size",
hl = "Special"
}
Indents the foldtext to match the original text.
Note
Fold texts do not scroll horizontally.
{
type = "indent",
hl = "CursorLine"
}
Allows writing a custom handler for the foldtext.
{
type = "custom",
handler = function (window, buffer)
-- { text, highlight_group }
return { "Hello world", "Special" };
end
}
The function can also return a list of tables.
{
type = "custom",
handler = function (window, buffer)
-- { { text, highlight_group } }
return {
{ "Hello", "Special" },
{ "world", "Normal" },
};
end
}
The custom
option can be used to make condition-based
foldtext.
custom = {
{
ft = {}, -- file types where it will be used
bt = {}, -- buf types where it will be used
condition = function (win, buf)
-- Additional conditions
return true;
end,
-- Configuration table
config = {}
}
}
Tip
You can use ft, bt & cond together for more control over the foldtext.
This foldtext is used in markdown files when the fold starts on a line containing a <summary>
tag.
It display whatever is used as the summary(kinda, like how Github does)
{
ft = { "markdown" },
condition = function (_, buf)
local ln = table.concat(vim.fn.getbufline(buf, vim.v.foldstart))
if ln:match("^%s*<summary>(.-)</summary>") then
return true;
else
return false;
end
end,
config = {
{
type = "indent",
hl = "TabLineSel"
},
{
type = "raw",
text = "ο ",
hl = "Title"
},
{
type = "custom",
handler = function (_, buf)
local ln = table.concat(vim.fn.getbufline(buf, vim.v.foldstart))
return { ln:match("^%s*<summary>(.-)</summary>"), "Title" };
end
}
}
}