diff options
| -rw-r--r-- | autoload/nvim_treesitter.vim | 4 | ||||
| -rw-r--r-- | doc/nvim-treesitter.txt | 21 | ||||
| -rw-r--r-- | lua/nvim-treesitter.lua | 52 |
3 files changed, 77 insertions, 0 deletions
diff --git a/autoload/nvim_treesitter.vim b/autoload/nvim_treesitter.vim index f24a98d73..813cc3e50 100644 --- a/autoload/nvim_treesitter.vim +++ b/autoload/nvim_treesitter.vim @@ -2,6 +2,10 @@ function! nvim_treesitter#statusline(len) abort return luaeval("require'nvim-treesitter'.statusline(_A)", a:len) endfunction +function! nvim_treesitter#named_statusline(...) abort + return luaeval("require'nvim-treesitter'.named_statusline(_A)", get(a:, 1, {})) +endfunction + function! nvim_treesitter#foldexpr() abort return luaeval(printf('require"nvim-treesitter.fold".get_fold_indic(%d)', v:lnum)) endfunction diff --git a/doc/nvim-treesitter.txt b/doc/nvim-treesitter.txt index 1bf5ef310..86250736b 100644 --- a/doc/nvim-treesitter.txt +++ b/doc/nvim-treesitter.txt @@ -423,6 +423,27 @@ could be used as a statusline indicator. Note: The `size` argument is optional. When specified, the string will not be longer than `size`. + *nvim_treesitter#named_statusline()* +nvim_treesitter#named_statusline(opts)~ + +Returns a string describing the current position in the file. This +could be used as a statusline indicator. +Default options (lua syntax): +> + { + indicator_size = 100, + type_patterns = {'class', 'function', 'method'}, + transform_fn = function(line) return line:gsub('[%[%(%{]*%s*$', '') end, + separator = ' -> ' + } +< +- `indicator_size` - How long should the string be. If longer, it is cut from + the beginning. +- `type_patterns` - Which node type patterns to match. +- `transform_fn` - Function used to transform the single item in line. By + default removes opening brackets and spaces from end. +- `separator` - Separator between nodes. + *nvim_treesitter#foldexpr()* nvim_treesitter#foldexpr()~ diff --git a/lua/nvim-treesitter.lua b/lua/nvim-treesitter.lua index f90e264db..b61164268 100644 --- a/lua/nvim-treesitter.lua +++ b/lua/nvim-treesitter.lua @@ -53,4 +53,56 @@ function M.statusline(indicator_size) end end +local get_line_for_node = function(node, type_patterns, transform_fn) + local node_type = node:type() + local is_valid = false + for _, rgx in ipairs(type_patterns) do + if node_type:find(rgx) then + is_valid = true + break + end + end + if not is_valid then return '' end + local range = {node:range()} + local line = transform_fn(vim.trim(vim.fn.getline(range[1] + 1))) + -- Escape % to avoid statusline to evaluate content as expression + return line:gsub('%%', '%%%%') +end + +-- Trim spaces and opening brackets from end +local transform_line = function(line) + return line:gsub('[%[%(%{]*%s*$', '') +end + +function M.named_statusline(opts) + if not parsers.has_parser() then return end + local options = opts or {} + local indicator_size = options.indicator_size or 100 + local type_patterns = options.type_patterns or {'class', 'function', 'method'} + local transform_fn = options.transform_fn or transform_line + local separator = options.separator or ' -> ' + + local current_node = ts_utils.get_node_at_cursor() + if not current_node then return "" end + + local lines = {} + local expr = current_node + + while expr do + local line = get_line_for_node(expr, type_patterns, transform_fn) + if line ~= '' and not vim.tbl_contains(lines, line) then + table.insert(lines, 1, line) + end + expr = expr:parent() + end + + local text = table.concat(lines, separator) + local text_len = #text + if text_len > indicator_size then + return '...'..text:sub(text_len - indicator_size, text_len) + end + + return text +end + return M |
