94 lines
3.6 KiB
Lua
94 lines
3.6 KiB
Lua
local function show_function_lines()
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
local ft = vim.bo[bufnr].filetype
|
|
local lang = vim.treesitter.language.get_lang(ft) or ft
|
|
local parser = vim.treesitter.get_parser(bufnr, lang)
|
|
if not parser then
|
|
return
|
|
end
|
|
local ns = vim.api.nvim_create_namespace('function_lines')
|
|
vim.api.nvim_buf_clear_namespace(bufnr, ns, 0, -1)
|
|
-- Tree-sitter query for C functions, with three cases:
|
|
-- Case 1: Regular function (no pointer)
|
|
-- Case 2: Function returning a pointer (one pointer_declarator)
|
|
-- Case 3: Function returning a double pointer (two pointer_declarator nodes)
|
|
local query = vim.treesitter.query.parse(lang, [[
|
|
; Case 1: Regular function (no pointer)
|
|
(function_definition
|
|
declarator: (function_declarator
|
|
declarator: (identifier) @func_name
|
|
)
|
|
body: (compound_statement) @func_body
|
|
) @func;
|
|
; Case 2: Function returning a pointer (one pointer_declarator)
|
|
(function_definition
|
|
declarator: (pointer_declarator
|
|
declarator: (function_declarator
|
|
declarator: (identifier) @func_name
|
|
)
|
|
)
|
|
body: (compound_statement) @func_body
|
|
) @func;
|
|
; Case 3: Function returning a double pointer (two pointer_declarator nodes)
|
|
(function_definition
|
|
declarator: (pointer_declarator
|
|
declarator: (pointer_declarator
|
|
declarator: (function_declarator
|
|
declarator: (identifier) @func_name
|
|
)
|
|
)
|
|
)
|
|
body: (compound_statement) @func_body
|
|
) @func
|
|
]])
|
|
for _, tree in ipairs(parser:parse()) do
|
|
local root = tree:root()
|
|
-- Iterate over each capture from the query
|
|
for id, node, _ in query:iter_captures(root, bufnr, 0, -1) do
|
|
if query.captures[id] == "func_body" then
|
|
-- Get the range of the compound statement.
|
|
-- The range includes the braces, so we subtract 2 to get the interior.
|
|
local start_line, _, end_line, _ = node:range()
|
|
local total_lines = end_line - start_line - 1
|
|
if total_lines < 0 then
|
|
total_lines = 0
|
|
end
|
|
-- Get the lines between the braces.
|
|
local lines = vim.api.nvim_buf_get_lines(bufnr, start_line + 1, end_line, false)
|
|
local comment_lines = 0
|
|
for _, line in ipairs(lines) do
|
|
-- Adjust this pattern as needed for your comment style.
|
|
if line:match("^%s*//") then
|
|
comment_lines = comment_lines + 1
|
|
end
|
|
end
|
|
local non_comment_lines = total_lines - comment_lines
|
|
-- Prepare the virtual text.
|
|
local virt_text = nil
|
|
if comment_lines > 0 then
|
|
-- If there are comment lines, display two numbers:
|
|
-- Total lines / non-comment lines.
|
|
virt_text = {{ ' ' .. total_lines .. ' / ' .. non_comment_lines, 'Comment' }}
|
|
else
|
|
-- If no comments, display only the total line count.
|
|
virt_text = {{ ' ' .. total_lines, 'Comment' }}
|
|
end
|
|
-- Place the virtual text on the closing brace line.
|
|
vim.api.nvim_buf_set_extmark(bufnr, ns, end_line, -1, {
|
|
virt_text = virt_text,
|
|
virt_text_pos = 'eol',
|
|
})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- Auto-command to run the function for C files on buffer enter or after writing.
|
|
vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost' }, {
|
|
pattern = '*.c',
|
|
callback = show_function_lines,
|
|
})-- Auto-command to run the function for C files on buffer enter or after writing.
|
|
vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost' }, {
|
|
pattern = '*.c',
|
|
callback = show_function_lines,
|
|
})
|