Closed CRAG666 closed 1 year ago
neovim v0.9.0 src/nvim/screen.c
--> src/nvim/drawline.c
.
About line 421.
418 for (i = 0; i < MIN(fdc, level); i++) {
419 if (foldinfo.fi_lnum == lnum
420 && first_level + i >= foldinfo.fi_low_level) {
421 symbol = wp->w_p_fcs_chars.foldopen;
422 } else if (first_level == 1) {
423 symbol = wp->w_p_fcs_chars.foldsep;
424 } else if (first_level + i <= 9) {
425 symbol = '0' + first_level + i;
426 } else {
427 symbol = '>';
428 }
@kevinhwang91 Now that Neovim 0.9.0 is out, what is the right way to enable this look?
@pedropombeiro Now the plugin statuscol.nvim is stable enough and is worth a trying. The alternative approach is to change the code in screen.c
(that was refactored and renamed to drawline.c
) directly and build neovim by yourself.
Here is my entire UFO + Folding preview config, just in case someone needs this.
Setup folding option
-- UFO folding
vim.o.foldcolumn = "1" -- '0' is not bad
vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value
vim.o.foldlevelstart = 99
vim.o.foldenable = true
vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep: ,foldclose:]]
Install the plugin with lazy.nvim
return {
-- UFO folding
{
"kevinhwang91/nvim-ufo",
dependencies = {
"kevinhwang91/promise-async",
{
"luukvbaal/statuscol.nvim",
config = function()
local builtin = require("statuscol.builtin")
require("statuscol").setup({
relculright = true,
segments = {
{ text = { builtin.foldfunc }, click = "v:lua.ScFa" },
{ text = { "%s" }, click = "v:lua.ScSa" },
{ text = { builtin.lnumfunc, " " }, click = "v:lua.ScLa" },
},
})
end,
},
},
event = "BufReadPost",
opts = {
provider_selector = function()
return { "treesitter", "indent" }
end,
},
init = function()
vim.keymap.set("n", "zR", function()
require("ufo").openAllFolds()
end)
vim.keymap.set("n", "zM", function()
require("ufo").closeAllFolds()
end)
end,
},
-- Folding preview, by default h and l keys are used.
-- On first press of h key, when cursor is on a closed fold, the preview will be shown.
-- On second press the preview will be closed and fold will be opened.
-- When preview is opened, the l key will close it and open fold. In all other cases these keys will work as usual.
{ "anuvyklack/fold-preview.nvim", dependencies = "anuvyklack/keymap-amend.nvim", config = true },
}
Demo:
Let me join the party and share my config with one small extra "feature" of displaying the number of hidden rows near the colorcolumn or window edge (whichever is smaller).
return {
"kevinhwang91/nvim-ufo",
dependencies = "kevinhwang91/promise-async",
event = "VeryLazy",
opts = {
-- INFO: Uncomment to use treeitter as fold provider, otherwise nvim lsp is used
-- provider_selector = function(bufnr, filetype, buftype)
-- return { "treesitter", "indent" }
-- end,
open_fold_hl_timeout = 400,
close_fold_kinds = { "imports", "comment" },
preview = {
win_config = {
border = { "", "─", "", "", "", "─", "", "" },
-- winhighlight = "Normal:Folded",
winblend = 0,
},
mappings = {
scrollU = "<C-u>",
scrollD = "<C-d>",
jumpTop = "[",
jumpBot = "]",
},
},
},
init = function()
vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep: ,foldclose:]]
vim.o.foldcolumn = "1" -- '0' is not bad
vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value
vim.o.foldlevelstart = 99
vim.o.foldenable = true
end,
config = function(_, opts)
local handler = function(virtText, lnum, endLnum, width, truncate)
local newVirtText = {}
local totalLines = vim.api.nvim_buf_line_count(0)
local foldedLines = endLnum - lnum
local suffix = (" %d %d%%"):format(foldedLines, foldedLines / totalLines * 100)
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
local rAlignAppndx =
math.max(math.min(vim.opt.textwidth["_value"], width - 1) - curWidth - sufWidth, 0)
suffix = (" "):rep(rAlignAppndx) .. suffix
table.insert(newVirtText, { suffix, "MoreMsg" })
return newVirtText
end
opts["fold_virt_text_handler"] = handler
require("ufo").setup(opts)
vim.keymap.set("n", "zR", require("ufo").openAllFolds)
vim.keymap.set("n", "zM", require("ufo").closeAllFolds)
vim.keymap.set("n", "zr", require("ufo").openFoldsExceptKinds)
vim.keymap.set("n", "K", function()
local winid = require("ufo").peekFoldedLinesUnderCursor()
if not winid then
-- vim.lsp.buf.hover()
vim.cmd [[ Lspsaga hover_doc ]]
end
end)
end,
}
Examples:
@awerebea thats just amazing.
However the arrow and percentage for me appear where the code ends not and the end of the window like yours. How did you modify the 'hidden' data to be at the end of the window?
Hey @sudoCompetence! Glad you like it.
How did you modify... ?
Well, I just took the example from Customize fold text and modified it to take into account the textwidth
property, so in my implementation, the position actually depends on texdtwidth
but not on colorcolumn
, sorry for the confusion.
This is the diff of the changes made:
Idk if it's just me, but on nightly I had to change my statuscol config to include disable_ft = { 'trouble' }
, else Neovim crashes with a 134 exit code. Curious to know if anyone else experienced something similar.
@awerebea thats just amazing.
However the arrow and percentage for me appear where the code ends not and the end of the window like yours. How did you modify the 'hidden' data to be at the end of the window?
Sorry for commenting on this again but also wanted to make it so that the fold was all the way to the right so for those in the future that want this here. You can do it by doing the below: https://github.com/kevinhwang91/nvim-ufo/issues/4#issuecomment-1514537245
replace this line:
local rAlignAppndx = math.max(math.min(vim.opt.textwidth["_value"], width - 1) - curWidth - sufWidth, 0)
with
local rAlignAppndx = math.max(math.min(vim.api.nvim_win_get_width(0), width - 1) - curWidth - sufWidth, 0)
This will put the fold text as far width-wise as your buffer is
Example:
Hi @nick22985, Well, please feel free to change this snippet this way if you prefer this implementation. 😉 But for me personally, my original way looks better.
The proposed change only affects the display in a wide window, but I'm just used to limiting the width of the text in the window (99 characters for the Lua file type in this example). So it doesn't make much sense for me to place the fold text as far in width as the window of my current buffer.
I set the colorcolumn value equal to +1 for clarity in the following screenshots. wide window: proposed change current tight window: really long line with fold:
Again, it's just a matter of taste. In my opinion, all these cases are better covered by my current implementation, but it's obviously up to you to decide which way to use for yourself.
Thank you for your participation!
I have this minimal config for nvim-ufo
and it looks amazing to me.
Additional - adding vim.o.foldcolumn = 'auto:9'
will remove the annoying random number on foldcolumn and also adjust the foldcolumn size/width accordingly. Just simply add this on your config.
vim.o.foldcolumn = 'auto:9'
Currently my line looks like this and I would like it to be seen as yours