docs: update

This commit is contained in:
kevinhwang91 2022-06-18 22:33:45 +08:00
parent a9a422b2f0
commit 9569085ffd
9 changed files with 199 additions and 20 deletions

View file

@ -8,6 +8,8 @@ The goal of nvim-ufo is to make Neovim's fold look modern and keep high performa
<https://user-images.githubusercontent.com/17562139/173796287-9842fb3a-37c2-47fb-8968-6e7600c0fcef.mp4>
> [setup foldcolumn like demo](https://github.com/kevinhwang91/nvim-ufo/issues/4)
---
## Table of contents
@ -45,6 +47,7 @@ vim.wo.foldenable = true
-- option 1: coc.nvim as LSP client
use {'neoclide/coc.nvim', branch = 'master', run = 'yarn install --frozen-lockfile'}
--
-- option 2: nvim lsp as LSP client
-- tell the sever the capability of foldingRange
@ -53,6 +56,7 @@ capabilities.textDocument.foldingRange = {
dynamicRegistration = false,
lineFoldingOnly = true
}
--
require('ufo').setup()
```
@ -66,7 +70,7 @@ Use fold as usual.
### How does nvim-ufo get the folds?
If ufo detect `foldmethod` option is not `diff` or `marker`, it will request the providers to get
the folds, the request strategy formed by the main and the fallback. The default value of main is
the folds, the request strategy is formed by the main and the fallback. The default value of main is
`lsp` and the default value of fallback is `indent` which implemented by ufo.
Changing the text in a buffer will request the providers for folds.
@ -83,11 +87,12 @@ Changing the text in a buffer will request the providers for folds.
default = 400
},
provider_selector = {
description = [[a function as a selector for fold providers, TODO]],
description = [[a function as a selector for fold providers. For now, there are 'lsp' and 'indent'
providers]],
default = nil
},
fold_virt_text_handler = {
description = [[a function customize fold virt text, TODO]],
description = [[a function customize fold virt text, see ### Customize fold text]],
default = nil
}
}
@ -99,22 +104,24 @@ Changing the text in a buffer will request the providers for folds.
hi default link UfoFoldedEllipsis Comment
```
- `UfoFoldedEllipsis`: highlight ellipsis at the end of folded line
- `UfoFoldedEllipsis`: highlight ellipsis at the end of folded line, invalid if
`fold_virt_text_handler` is set.
## Advanced configuration
Configuration can be found at [example.lua](./doc/example.lua)
### Customize provider selector
```lua
local ftMap = {
vim = 'indent',
c = 'indent',
python = {'indent'},
git = ''
}
require('ufo').setup({
provider_selector = function(bufnr, filetype)
-- return a string type use a built-in provider
-- return a string type use internal providers
-- return a string in a table like a string type
-- return empty string '' will disable any providers
-- return `nil` will use default value {'lsp', 'indent'}

73
doc/example.lua Normal file
View file

@ -0,0 +1,73 @@
---@diagnostic disable: unused-local, unused-function
local function selectProviderWithFt()
local ftMap = {
vim = 'indent',
python = {'indent'},
git = ''
}
require('ufo').setup({
provider_selector = function(bufnr, filetype)
-- return a string type use ufo providers
-- return a string in a table like a string type
-- return empty string '' will disable any providers
-- return `nil` will use default value {'lsp', 'indent'}
return ftMap[filetype]
end
})
end
local function selectProviderWithFunc()
require('ufo').setup({
provider_selector = function(bufnr, filetype)
-- use indent provider for c fieltype
if filetype == 'c' then
return function()
return require('ufo').getFolds('indent', bufnr)
end
end
end
})
end
local handler = function(virtText, lnum, endLnum, width, truncate)
local newVirtText = {}
local suffix = ('  %d '):format(endLnum - lnum)
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)
-- text length returned from truncate() may less than 2rd argument, need padding
if curWidth + chunkWidth < targetWidth then
suffix = suffix .. (' '):rep(targetWidth - curWidth - chunkWidth)
end
break
end
curWidth = curWidth + chunkWidth
end
table.insert(newVirtText, {suffix, 'MoreMsg'})
return newVirtText
end
local function customizeFoldText()
-- global handler
require('ufo').setup({
fold_virt_text_handler = handler
}
end
local function customizeBufFoldText()
-- buffer scope handler
-- will override global handler if it is existed
local bufnr = vim.api.nvim_get_current_buf()
require('ufo').setVirtTextHandler(bufnr, handler)
end

17
doc/ufo.txt Normal file
View file

@ -0,0 +1,17 @@
*ufo.txt*
*nvimufo.txt*
*nvim-ufo.txt*
type `gf` or `CTRL-W gf` under the PATH value :)
`URL`: https://github.com/kevinhwang91/nvim-ufo
`PATH`: ../README.md
`PATH`: ../lua/ufo/config.lua |nvim-ufo-default-config|
`PATH`: ../lua/ufo.lua |nvim-ufo-api|
`PATH`: ../doc/example.lua |nvim-ufo-example|
vim:ft=help

View file

@ -1,9 +1,9 @@
---Export methods to the users, `require('ufo').method(...)`
---@class Ufo
local M = {}
local cmd = vim.cmd
local fn = vim.fn
local api = vim.api
---Setup configuration and enable ufo
---@param opts? UfoConfig
function M.setup(opts)
opts = opts or {}
M._config = opts
@ -14,6 +14,8 @@ function M.goPreviousStartFold()
return require('ufo.action').goPreviousStartFold()
end
---Inspect ufo information by bufnr
---@param bufnr? number current buffer default
function M.inspect(bufnr)
local msg = require('ufo.main').inspectBuf(bufnr)
if not msg then
@ -23,32 +25,48 @@ function M.inspect(bufnr)
end
end
---Enable ufo
function M.enable()
require('ufo.main').enable()
end
---Disable ufo
function M.disable()
require('ufo.main').disable()
end
---Check whether the buffer has been attached
---@param bufnr? number current buffer default
---@return boolean
function M.hasAttached(bufnr)
return require('ufo.main').inspectBuf(bufnr) ~= nil
end
---Attach bufnr to enable ufo features
---@param bufnr? number current buffer default
function M.attach(bufnr)
require('ufo.main').attach(bufnr)
end
---Detach bufnr to disable ufo features
---@param bufnr? number current buffer default
function M.detach(bufnr)
require('ufo.main').detach(bufnr)
end
function M.getFoldingRange(providerName, bufnr)
---Get foldingRange from the ufo internal providers by name
---@param providerName string
---@param bufnr number
---@return UfoFoldingRange|Promise
function M.getFolds(providerName, bufnr)
local ok, res = pcall(require, 'ufo.provider.' .. providerName)
assert(ok, ([[Can't find %s provider]]):format(providerName))
return res.getFolds(bufnr)
end
---Set a fold virtual text handler for a buffer, will override global handler if it's existed
---@param bufnr number
---@param handler UfoFoldVirtTextHandler reference to `config.fold_virt_text_handler`
function M.setFoldVirtTextHandler(bufnr, handler)
require('ufo.decorator').setVirtTextHandler(bufnr, handler)
end

View file

@ -1,8 +1,57 @@
---@class UfoConfig
---@field open_fold_hl_timeout number
---@field provider_selector function
---@field fold_virt_text_handler UfoFoldVirtTextHandler
local config = {}
---@field fold_virt_text_handler function
local Config = {}
---@alias UfoProviderEnum
---| 'lsp'
---| 'indent'
---
---@param bufnr number
---@param filetype string buffer filetype
---@return UfoProviderEnum|string[]|function|nil
---return a string type use ufo providers
---return a string in a table like a string type
---return empty string '' will disable any providers
---return `nil` will use default value {'lsp', 'indent'}
---@diagnostic disable-next-line: unused-function, unused-local
function Config.provider_selector(bufnr, filetype) end
---@class UfoFoldVirtTextHandlerContext
---@field bufnr number buffer for closed fold
---@field winid number window for closed fold
---@field text string text for the first line of closed fold
---run `:h nvim_buf_set_extmark` and search `virt_text` optional parameter for details
---@class ExtmarkVirtText
---@field text string
---@field highlight string|number
---@class UfoFoldVirtTextHandler
---Ufo actually uses a virtual text with `nvim_buf_set_extmark` to overlap the first line of
---closed fold
---@param virtText ExtmarkVirtText contained text and highlight captured by Ufo, reused by caller
---@param lnum number first line of closed fold, like `v:foldstart in foldtext()`
---@param endLnum number last line of closed fold, like `v:foldend in foldtext()`
---@param width number text area width, exclude the foldcolumn, signcolumn and numberwidth
---@param truncate fun(str: string, width: number): string truncate the str to become specific width,
---return width of string is equal or less than str's width.
---For example: '1': 1 cell, '你': 2 cells, '2': 1 cell, '好': 2 cells
---truncate('1你2好', 1) return '1'
---truncate('1你2好', 2) return '1'
---truncate('1你2好', 3) return '1你'
---truncate('1你2好', 4) return '1你2'
---truncate('1你2好', 5) return '1你2'
---truncate('1你2好', 6) return '1你2好'
---truncate('1你2好', 7) return '1你2好'
---truncate('1你2好', 8) return '1你2好'
---@param ctx UfoFoldVirtTextHandlerContext context for handler
---@return ExtmarkVirtText[]
---@diagnostic disable-next-line: unused-function, unused-local
function Config.fold_virt_text_handler(virtText, lnum, endLnum, width, truncate, ctx) end
local function init()
local ufo = require('ufo')
@ -12,10 +61,10 @@ local function init()
provider_selector = nil,
fold_virt_text_handler = nil,
}
config = vim.tbl_deep_extend('keep', ufo._config or {}, def)
Config = vim.tbl_deep_extend('keep', ufo._config or {}, def)
ufo._config = nil
end
init()
return config
return Config

View file

@ -179,7 +179,6 @@ local function onEnd(name, tick)
fb:closeFold(lnum, endLnum, virtText, width)
end
end
fb.width = width
end)
end
local lnum = api.nvim_win_get_cursor(winid)[1]
@ -214,7 +213,7 @@ function Decorator.defaultVirtTextHandler(virtText, lnum, endLnum, width, trunca
local hlGroup = chunk[2]
table.insert(newVirtText, {chunkText, hlGroup})
chunkWidth = fn.strdisplaywidth(chunkText)
-- text length returned from truncate() may less than 2rd argument, need padding
-- str width returned from truncate() may less than 2rd argument, need padding
if curWidth + chunkWidth < targetWidth then
suffix = suffix .. (' '):rep(targetWidth - curWidth - chunkWidth)
end

View file

@ -63,10 +63,10 @@ local function updateFold(bufnr)
bufnr, (uv.hrtime() - s) / 1e6))
end
local p, ranges = res[1], res[2]
fb.targetProvider = type(p) == 'string' and p or 'external'
if not ranges or #ranges == 0 or not utils.isBufLoaded(bufnr) then
return
end
fb.targetProvider = type(p) == 'string' and p or 'external'
winid = fn.bufwinid(bufnr)
local newChangedtick = api.nvim_buf_get_changedtick(bufnr)
fb.version = newChangedtick

View file

@ -65,7 +65,8 @@ function M.inspectBuf(bufnr)
end
local msg = {}
table.insert(msg, 'Buffer: ' .. bufnr)
table.insert(msg, 'Main provider: ' .. fb.providers[1])
local main = fb.providers[1]
table.insert(msg, 'Main provider: ' .. (type(main) == 'function' and 'external' or main))
if fb.providers[2] then
table.insert(msg, 'Fallback provider: ' .. fb.providers[2])
end
@ -92,5 +93,4 @@ function M.foldtext()
return utils.expandTab(text, vim.bo.ts)
end
return M

View file

@ -15,6 +15,22 @@ local function getFunction(m)
return type(m) == 'string' and modules[m].getFolds or m
end
---@alias UfoFoldingRangeKind
---| 'comment'
---| 'imports'
---| 'region'
---@class UfoFoldingRange
---@field startLine number
---@field startCharacter? number
---@field endLine number
---@field endCharacter? number
---@field kind? UfoFoldingRangeKind
---
---@param providers table
---@param bufnr number
---@return Promise
function Provider.requestFoldingRange(providers, bufnr)
local main, fallback = providers[1], providers[2]
local mainFunc = getFunction(main)