Pretty Fold
โ ๏ธ WARNING: Neovim v0.7 or higher is requiredThere is a 0.6 branch which is lack of some features.
Pretty Fold is a lua plugin for Neovim which provides framework for easy foldtext customization. Filetype specific and foldmethod specific configuration is supported.
simplescreenrecorder-2022-01-05_20.24.21.mp4
Installation and quickstart
Installation and setup example with packer:
use{ 'anuvyklack/pretty-fold.nvim',
config = function()
require('pretty-fold').setup()
end
}
Foldtext configuration
The plugin comes with the following defaults (the description of each option is below):
config = {
sections = {
left = {
'content',
},
right = {
' ', 'number_of_folded_lines', ': ', 'percentage', ' ',
function(config) return config.fill_char:rep(3) end
}
},
fill_char = 'โข',
remove_fold_markers = true,
-- Keep the indentation of the content of the fold string.
keep_indentation = true,
-- Possible values:
-- "delete" : Delete all comment signs from the fold string.
-- "spaces" : Replace all comment signs with equal number of spaces.
-- false : Do nothing with comment signs.
process_comment_signs = 'spaces',
-- Comment signs additional to the value of `&commentstring` option.
comment_signs = {},
-- List of patterns that will be removed from content foldtext section.
stop_words = {
'@brief%s*', -- (for C++) Remove '@brief' and all spaces after.
},
add_close_pattern = true, -- true, 'last_line' or false
matchup_patterns = {
{ '{', '}' },
{ '%(', ')' }, -- % to escape lua pattern char
{ '%[', ']' }, -- % to escape lua pattern char
},
ft_ignore = { 'neorg' },
}
sections
The main part. Contains two tables: config.sections.left
and
config.sections.right
which content will be left and right aligned
respectively. Each of them can contain names of the
components and functions that returns string.
Built-in components
The strings from the table below will be expanded according to the table.
Item | Expansion |
---|---|
'content' |
The content of the first non-blank line of the folded region, somehow modified according to other options. |
'number_of_folded_lines' |
The number of folded lines. |
'percentage' |
The percentage of the folded lines out of the whole buffer. |
Custom functions
All functions accept config table as an argument, so if you would like to pass
any arguments into your custom function, place them into the config table which
you pass to setup
function and then you can access them inside your function,
like this:
require('pretty-fold').setup {
custom_function_arg = 'Hello from inside custom function!',
sections = {
left = {
function(config)
return config.custom_function_arg
end
},
}
}
fill_char
default: 'โข'
Character used to fill the space between the left and right sections.
remove_fold_markers
default: true
Remove foldmarkers from the content
component.
keep_indentation
default: true
Keep the indentation of the content of the fold string.
process_comment_signs
What to do with comment signs:
default: spaces
Option | Description |
---|---|
'delete' |
delete all comment signs from the foldstring |
'spaces' |
replace all comment signs with equal number of spaces |
false |
do nothing with comment signs |
comment_signs
default: {}
Table with comment signs additional to the value of &commentstring
option.
Add additional comment signs only when you really need them. Otherwise, they
give computational overhead without any benefits.
Example for Lua. Default &commentstring
value for Lua is: '--'
.
comment_signs = {
{ '--[[', '--]]' }, -- multiline comment
}
Example for C++. Default &commentstring
value for C++ is: { '/*', '*/' }
comment_signs = { '//' }
stop_words
default: '@brief%s*'
(for C++) Remove '@brief' and all spaces after.
Lua patterns that will be
removed from the content
section.
add_close_pattern
default: true
If this option is set to true
for all opening patterns that will be found in
the first non-blank line of the folded region, all corresponding closing
elements will be added after ellipsis. (The synthetical string with matching
closing elements will be constructed).
If it is set to last_line
, the last line content (without comments) will be
added after the ellipsis . This behavior was the first algorithm I
implemented, but turns out it is not always relevant. For some languages (at
least for all lisps) this does not work. Since it is already written and if
someone like this behavior, I keep this option to choose.
matchup_patterns
The list with matching elements. Each item is a list itself with two items: opening lua pattern and close string which will be added if oppening pattern is found.
Examples for lua (Lua patterns are explained with railroad diagrams):
matchup_patterns = {
-- โโ Start of line โโโญโโโโโโโโฎโโ "do" โโ End of line โโข
-- โฐโ WSP โโฏ
{ '^%s*do$', 'end' }, -- `do ... end` blocks
-- โโ Start of line โโโญโโโโโโโโฎโโ "if" โโข
-- โฐโ WSP โโฏ
{ '^%s*if', 'end' },
-- โโ Start of line โโโญโโโโโโโโฎโโ "for" โโข
-- โฐโ WSP โโฏ
{ '^%s*for', 'end' },
-- โโ "function" โโโญโโโโโโโโฎโโ "(" โโข
-- โฐโ WSP โโฏ
{ 'function%s*%(', 'end' }, -- 'function(' or 'function ('
{ '{', '}' },
{ '%(', ')' }, -- % to escape lua pattern char
{ '%[', ']' }, -- % to escape lua pattern char
},
The comment substring in foldtext is correctly handled on close elements adding.
If process_comment_signs = 'spaces'
is set, the output will be
Setup for particular filetype
This plugin provides two setup functions.
-
The first one setup configuration which will be used for all filetypes for which you doesn't set their own configuration.
require('pretty-fold').setup(config: table)
-
The second one allows to setup filetype specific configuration:
require('pretty-fold').ft_setup(filtype: string, config: table)
Example of ready to use foldtext configuration only for lua files
require('pretty-fold').ft_setup('lua', {
matchup_patterns = {
{ '^%s*do$', 'end' }, -- do ... end blocks
{ '^%s*if', 'end' }, -- if ... end
{ '^%s*for', 'end' }, -- for
{ 'function%s*%(', 'end' }, -- 'function( or 'function (''
{ '{', '}' },
{ '%(', ')' }, -- % to escape lua pattern char
{ '%[', ']' }, -- % to escape lua pattern char
},
}
ft_ignore
options
default: { 'neorg' }
Filetypes to be ignored.
ft_ignore
is a unique option. It exists only in a single copy for all global
and filetype specific configurations. You can pass it in any function
(setup()
or ft_setup()
) and all this values will be collected in this one
single value.
Foldmethod specific configuration
The pretty-fold.nvim plugin supports saparate configuration for different foldmethods. For this pass the configuration table for a particular foldmethod as a value to the key named after foldmethod.
You can also pass global
configuration table for all foldmethods and tune
only desired options in foldmethod specific config table. All options that
don't have value in foldmethod config table will be taken from global
config
table.
Example:
require('pretty-fold').setup({
global = {...}, -- global config table for all foldmethods
marker = { process_comment_signs = 'spaces' },
expr = { process_comment_signs = false },
})
Examples
require('pretty-fold').setup{
keep_indentation = false,
fill_char = 'โข',
sections = {
left = {
'+', function() return string.rep('-', vim.v.foldlevel) end,
' ', 'number_of_folded_lines', ':', 'content',
}
}
}
require('pretty-fold').setup{
keep_indentation = false,
fill_char = 'โ',
sections = {
left = {
'โ ', function() return string.rep('*', vim.v.foldlevel) end, ' โโซ', 'content', 'โฃ'
},
right = {
'โซ ', 'number_of_folded_lines', ': ', 'percentage', ' โฃโโ',
}
}
}
Configuration for C++ to get nice foldtext for Doxygen comments
require('pretty-fold').ft_setup('cpp', {
process_comment_signs = false,
comment_signs = {
'/**', -- C++ Doxygen comments
},
stop_words = {
-- โโ "*" โโโญโโโโโโโโฎโโ "@brief" โโโญโโโโโโโโฎโโโข
-- โฐโ WSP โโฏ โฐโ WSP โโฏ
'%*%s*@brief%s*',
},
})
Preview
Preview module have been moved into separate plugin.
Additional information
Check 'fillchars' option. From lua it can be set the next way:
vim.opt.fillchars:append('fold:โข')