At first, I use the set foldmethod=marker, and move the cursor to the { of one function, use the zf% to fold current function. But there are a lot of functions in this file. How can I fold all functions in this file? And I don't want to fold {} in the functions.
If you :set foldmethod=syntax
the folds will be specified from the syntax definitions. If you prefer you can :set foldmethod=indent
to have the indentation define the folds.
You can close all folds with zM
. If you have nested folds and you want to fold level by level, use zm
. To open folds use zR
(all) and zr
(level by level).
zm
and zr
, the official documentation says it is "More" and "Reduce". (Still not quite intuitive, but as most things in vim world, it is what it is.) –
Medrano zR
I get put in replace mode, and zM
says no fold found (even though I can fold individually with just z
). The only line in my rc modifying z is nnoremap z za
Any clues? –
Elizaelizabet M
as Mask
and R
as Reveal
as I find it more intuitive than more/reduce. –
Airy set foldmethod=indent
into .vimrc
but it works in files where I manually set command :set foldmethod=indent
–
Pat If each function has its opening brace on the first column you could do:
:%g/^{/normal! zf%
Maybe it is more clear this way:
:%g /^{/ normal! zf%
the g
command selects lines according to the following pattern, and executes an ex command (here normal!
to play normal mode keystrokes).
See :help :g
and :help :normal
I came across this when I was searching for a similar thing. You would have obviously figured this out by now, but for the benefit of other people i'll answer it anyway.
You need to put in the following lines in your .vimrc:
set foldmethod=syntax
set foldnestmax=1
I was trying to do the same and ended up simply doing:
setlocal foldmethod=marker
setlocal foldmarker={,}
It uses the marker fold method and changes the marker to a single curly brace (by default the marker is {{{
).
set foldlevel=0
will fold everything from the start, what is ment to be folded. Depending on the language, and your fold function, the contents of fold will vary.
zM
do the same thing. –
Bonin Try :%g/\(function\_.\{-}\)\@<={/ normal! f{zf%
Explain bit by bit:
:%g
- search globaly in a whole file
/\(function\_.\{-}\)\@<={/
- pattern to find first '{' after any 'function' and put cursor on begin of string with that '{'
normal! f{zf%
- execute forward to '{' f{
and make fold with move '%' zf%
on that string
DISCLAIMER: I'm fairly new to vim/nvim and still exploring the whole functionality and plugin scene of the nvim ecosystem and I'm therefore far from an expert. As this thread here is also almost ancient and the given answers here didn't really solve my needs and maybe others might have similar needs, I post my approaches I have come up with.
In order to achieve an automatic method level folding of C-like slangs like Java, JavaScript, C# and so forth with nvim-lsp configured I had to use this in my nvim.lua file:
vim.o.foldmethod = 'indent'
vim.o.foldlevel = 2
vim.o.foldlevelstart = 1
vim.o.foldnestmax = 2
This setting will automatically fold the body of all method or functions of standard classes, but not of sub-blocks within those functions/methods exactly as I prefer it. These settings though may fail on inner and/or nested classes.
While I am not a big fan of automatic folding, I am currently experimenting with a manual way to get the job done so that I have control over when folding occurs.
In order to achieve this, I first added further keybindings for the move context to the treesitter configuration:
-- added custom keybindings to treesitter
vim.defer_fn(function()
require('nvim-treesitter.configs').setup {
...
textobjects = {
...
move = {
...
goto_next_start = {
...
[']b'] = '@function.inner',
},
goto_next_end = {
...
[']B'] = '@function.inner',
},
goto_previous_start = {
...
['[b'] = '@function.inner',
},
goto_previous_end = {
...
['[B'] = '@function.inner',
},
}
}
}
}
This basically allows me to jump to the inside of methods with ]b
or upwards to the previous method via [b
.
Next, I created a keybinding for creating a folding from the inside, basically folding everything between [
and ]
or {
and }
. This keybind is not limited to the functions or methods but can also fold blocks within those, depending on where the cursor is located at:
-- add a custom menu option to WhichKey
require('which-key').register {
...
['<leader>f'] = { name = '[F]old', _ = 'which_key_ignore' },
}
vim.o.foldmethod = 'manual'
vim.keymap.set('n', '<leader>fb', 'zfiB', { desc = 'Fold [b]lock' })
vim.keymap.set('n', '<leader>fB', 'zo', { desc = 'Unfold [B]lock' })
In combination with the above treesitter keybind it is now just a matter of calling ]b
to jump inside the next function/method and folding the method via <leader>fb
(or whatever keybind is preferred here).
As I haven't figured out how to write a lua function that iterates through all function/method treesitter/LSP objects and applies the required steps on a custom keybind, I currently created a macro that looks like that when viewed via :reg
:
:reg @f
Type Name Content
c "f ]b fbj
where the same keybinds as described above were used and a final move down after the folding as otherwise the macro would attempt to fold the same function all over again.
When calling the macro now with @f
and then with 1000@@
for a file with plenty of methods and 2.6k lines the script takes a bit of time to fold all methods but it gets the job done. The macro will only execute as long as it finds further methods to jump to so overshooting the macro repetition isn't a big deal here IMO. The macro also only operates downwards. So it allows you basically to fold all methods from the current cursor location on and leaves the method above untouched.
Adding the following keybinds therefore to the init.lua file allows me to fold all of the methods at and below the cursor position and unfold them again:
vim.keymap.set('n', '<leader>fa', "@f1000@@", { desc = 'Fold all' })
vim.keymap.set('n', '<leader>fA', "zR", { desc = 'Unfold [A]ll' })
This method should also work for nested classes as it basically uses the LSP tree to navigate through the file.
A word of warning though, if you have plugins like Tagbar or Vista installed, folding functions may drive these plugins nuts and block your nvim from operating smoothly (for some time). I therefore configured Vista in the lazy plugin manager to load lazily. Even with disabled Tagbar/Vista nvim takes a noticeable amount of time before it can be used as usual. Not sure what's making it almost freeze for like 15-20 seconds at worst time before it suddenly catches up and behaves normal again.
While this setup for sure isn't perfect, at last it gets the job done while giving me the control to fold stuff on my terms.
© 2022 - 2024 — McMap. All rights reserved.
:help fold
you can see all the fold related stuff. – Alchemize