Open fisher-j opened 10 months ago
vim.b.ufo_foldlevel -> vim.w.ufo_foldlevel
Have you encountered any performance issues by customizing yourself? IMO, the built-in zr
and zm
behaviors are not good workflow.
Maybe enhance ufo to preview the folded/unfolded level code in the future.
I agree this should be easy to do, but I don't know how to find the greatest fold level of the document.
Is there a way of querying what the largest fold level is for a document?
On Thu, Aug 24, 2023 at 4:24 PM Kevin Hwang @.***> wrote:
vim.b.ufo_foldlevel -> vim.w.ufo_foldlevel
Have you encountered any performance issues by customizing yourself? IMO, the built-in zr and zm behaviors are not good workflow.
Maybe enhance ufo to preview the folded/unfolded level code in the future.
— Reply to this email directly, view it on GitHub https://github.com/kevinhwang91/nvim-ufo/issues/150#issuecomment-1692538787, or unsubscribe https://github.com/notifications/unsubscribe-auth/APBWHQKDA2WB6BYF4CVEGOLXW7PEVANCNFSM6AAAAAA35MGRIU . You are receiving this because you authored the thread.Message ID: @.***>
Have you understood the comment https://github.com/kevinhwang91/nvim-ufo/issues/62#issuecomment-1207198496 ?
Yes, I see you say that incremental folding and virtual_foldlevel tracking
would be hard to implement. In that case, I'm can deal with working with
1zm 2zm...
On Thu, Aug 24, 2023 at 4:50 PM Kevin Hwang @.***> wrote:
Have you understood the comment #62 (comment) https://github.com/kevinhwang91/nvim-ufo/issues/62#issuecomment-1207198496 ?
— Reply to this email directly, view it on GitHub https://github.com/kevinhwang91/nvim-ufo/issues/150#issuecomment-1692558334, or unsubscribe https://github.com/notifications/unsubscribe-auth/APBWHQK7I7BP5V6EQBMJBF3XW7SF3ANCNFSM6AAAAAA35MGRIU . You are receiving this because you authored the thread.Message ID: @.***>
Hey @fisher-j and anyone else who comes across this.
I've implemented this in my Neovim config somewhat and thus far it's been working well enough for me.
Here's the code:
-- Ensure our ufo foldlevel is set for the buffer
vim.api.nvim_create_autocmd("BufReadPre", {
callback = function()
vim.b.ufo_foldlevel = 0
end
})
---@param num integer Set the fold level to this number
local set_buf_foldlevel = function(num)
vim.b.ufo_foldlevel = num
require("ufo").closeFoldsWith(num)
end
---@param num integer The amount to change the UFO fold level by
local change_buf_foldlevel_by = function(num)
local foldlevel = vim.b.ufo_foldlevel or 0
-- Ensure the foldlevel can't be set negatively
if foldlevel + num >= 0 then
foldlevel = foldlevel + num
else
foldlevel = 0
end
set_buf_foldlevel(foldlevel)
end
-- Keymaps
vim.keymap.set("n", "zm", function()
local count = vim.v.count
if count == 0 then
count = 1
end
change_buf_foldlevel_by(-(count))
end, { desc = "UFO: Fold More" })
vim.keymap.set("n", "zr", function()
local count = vim.v.count
if count == 0 then
count = 1
end
change_buf_foldlevel_by(count)
end, { desc = "UFO: Fold Less" })
-- 99% sure `zS` isn't mapped by default
vim.keymap.set("n", "zS", function()
if vim.v.count == 0 then
vim.notify("No foldlevel given to set!", vim.log.levels.WARN)
else
set_buf_foldlevel(vim.v.count)
end
end, { desc = "UFO: Set Foldlevel" })
Mostly I've just written a wrapper around require('ufo').closeFoldsWith
to keep track of a separate ufo_foldlevel
buffer variable.
If you're curious, I've implemented it into my config here. I use lazy.nvim to manage my plugins so I set my keybindings through lazy's keys
table. That's the only significant difference between the code above and my code in terms of the folding.
I'm sure there's problems that can be caused/extend from this, but thus far it seems to be working quite well for me. YMMV.
Hope someone else finds this helpful 🙂.
Thanks for this code snippet @treatybreaker ! I am looking to improve it a bit, @kevinhwang91 is there a way internally to retrieve the max fold level of a buffer? I'm curious if this information is stored anywhere when setting up the folds
Here is the code I'm trying to get working currently:
-- return the max fold level of the buffer (for now doing the opposite and folding incrementally is unbounded)
-- Also jarring if you start folding incrementally after opening all folds
local function max_level()
-- return vim.wo.foldlevel -- find a way for this to return max fold level
return 0
end
---Set the fold level to the provided value and store it locally to the buffer
---@param num integer the fold level to set
local function set_fold(num)
-- vim.w.ufo_foldlevel = math.min(math.max(0, num), max_level()) -- when max_level is implemneted properly
vim.b.ufo_foldlevel = math.max(0, num)
require("ufo").closeFoldsWith(vim.b.ufo_foldlevel)
end
---Shift the current fold level by the provided amount
---@param dir number positive or negative number to add to the current fold level to shift it
local shift_fold = function(dir) set_fold((vim.b.ufo_foldlevel or max_level()) + dir) end
-- when max_level is implemented properly
-- vim.keymap.set("n", "zR", function() set_win_fold(max_level()) end, { desc = "Open all folds" })
vim.keymap.set("n", "zR", require("ufo").openAllFolds, { desc = "Open all folds" })
vim.keymap.set("n", "zM", function() set_fold(0) end, { desc = "Close all folds" })
vim.keymap.set("n", "zr", function() shift_fold(vim.v.count == 0 and 1 or vim.v.count) end, { desc = "Fold less" })
vim.keymap.set("n", "zm", function() shift_fold(-(vim.v.count == 0 and 1 or vim.v.count)) end, { desc = "Fold more" })
If we had a way to dynamically fetch the max fold level from nvim-ufo
it would be completely seamless when moving between using zr
/zm
alongside zR
and zM
. Let me know what you think and if anyone knows of this sort of information being available!
Here is the code I'm trying to get working currently:
-- return the max fold level of the buffer (for now doing the opposite and folding incrementally is unbounded) -- Also jarring if you start folding incrementally after opening all folds local function max_level() -- return vim.wo.foldlevel -- find a way for this to return max fold level return 0 end ---Set the fold level to the provided value and store it locally to the buffer ---@param num integer the fold level to set local function set_fold(num) -- vim.w.ufo_foldlevel = math.min(math.max(0, num), max_level()) -- when max_level is implemneted properly vim.b.ufo_foldlevel = math.max(0, num) require("ufo").closeFoldsWith(vim.b.ufo_foldlevel) end ---Shift the current fold level by the provided amount ---@param dir number positive or negative number to add to the current fold level to shift it local shift_fold = function(dir) set_fold((vim.b.ufo_foldlevel or max_level()) + dir) end -- when max_level is implemented properly -- vim.keymap.set("n", "zR", function() set_win_fold(max_level()) end, { desc = "Open all folds" }) vim.keymap.set("n", "zR", require("ufo").openAllFolds, { desc = "Open all folds" }) vim.keymap.set("n", "zM", function() set_fold(0) end, { desc = "Close all folds" }) vim.keymap.set("n", "zr", function() shift_fold(vim.v.count == 0 and 1 or vim.v.count) end, { desc = "Fold less" }) vim.keymap.set("n", "zm", function() shift_fold(-(vim.v.count == 0 and 1 or vim.v.count)) end, { desc = "Fold more" })
If we had a way to dynamically fetch the max fold level from
nvim-ufo
it would be completely seamless when moving between usingzr
/zm
alongsidezR
andzM
. Let me know what you think and if anyone knows of this sort of information being available!
May take time to explore.
It looks like it is possible for nvim-ufo
to provide the said vim.w.ufo_foldlevel
variable right now, by adding some code that increments and decrements the variable inside the existing APIs. Much like the @PriceHiller's implementation https://github.com/kevinhwang91/nvim-ufo/issues/150#issuecomment-1867928299 but embedding the whole tracking code inside the API itself so that users do not need an extra wrapper.
Of course, this is not "directly" fetching the actual max fold level.
(currently the only way to do that is by analyzing the overlapping ranges of ufo.getFolds()
)
Just carefully tracking the invocation of folds to accurately "guess" the current fold level.
In a way this could be considered not very elegant. However, it probably works and definitely does not hinder the performance. There may be edge cases that might cause the tracking variable to go out of sync with the actual fold level - but for now I cannot think of any.
So, is there a particular reason this solution cannot be integrated in the nvim-ufo
's code?
Are you not satisfied with the said lack of "elegance" or the potential of edge cases?
Perhaps working on more clean and robust solution on your mind?
So, is there a particular reason this solution cannot be integrated in the
nvim-ufo
's code? Are you not satisfied with the said lack of "elegance" or the potential of edge cases? Perhaps working on more clean and robust solution on your mind?
Have you seen zR
doc? zR
will make foldlevel
become the highest fold level and ufo doesn't know the highest fold level. Even from getFolds
method, ufo knows all ranges, but the user can type zf
to create a new fold that makes the trace of vim.w.ufo_foldlevel
invalid.
@mehalter has mentioned we need a way to get the highest level. Frankly speaking, this is a laborious task. I have no time to explore the upstream source code and port it to ufo.
I have completely forgotten about the fact that foldmethod
remains "manual" because I never manually created folds while using nvim-ufo
. Welp, fair enough. In my use case it'd work fine because I do not use zf
but I agree this method is flawed and shouldn't be included in the plugin code.
Feature description
Related to #62, I would like it if
zr
would decrease the amount of folding andzm
would increase the amount of folding.Describe the solution you'd like
Starting with no folds,
zm
would need to be aware of the maximum fold level currently used in a document and incrementally reduce this value. The foldlevel could possibly be tracked by a buffer local variable (vim.b.ufo_foldlevel
?), similar tofoldlevel
.zr
would then incrementvim.b.ufo_foldlevel
up to the maximum currently used in the document.Additional context
Thank you for your work on this plugin, it has made it possible for me to use folds on large markdown documents with many code chunks, where before it was impossibly slow!