Add "vibe-coded" go-helper utils
This commit is contained in:
137
lua/scripts/go-extract-interface.lua
Normal file
137
lua/scripts/go-extract-interface.lua
Normal file
@ -0,0 +1,137 @@
|
||||
local M = {}
|
||||
|
||||
-- Parse method signature from a line
|
||||
local function parse_method(line)
|
||||
-- Match: func (receiver) MethodName(params) (returns)
|
||||
local pattern = "^func%s+%([^)]+%)%s+([%w_]+)%s*(%b())%s*(.*)"
|
||||
local name, params, returns = line:match(pattern)
|
||||
|
||||
if name then
|
||||
-- Clean up returns (remove leading spaces and parentheses if single return)
|
||||
returns = returns:gsub("^%s+", "")
|
||||
if returns:match("^%b()") then
|
||||
returns = " " .. returns
|
||||
elseif returns ~= "" then
|
||||
returns = " " .. returns
|
||||
end
|
||||
|
||||
return name .. params .. returns
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Find all methods for a given struct type
|
||||
local function find_struct_methods(struct_name, bufnr)
|
||||
local methods = {}
|
||||
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
|
||||
|
||||
-- Pattern to match methods with the struct as receiver
|
||||
-- Matches both pointer and value receivers
|
||||
local patterns = {
|
||||
"^func%s+%(%s*%w+%s+%*?" .. struct_name .. "%s*%)", -- Standard pattern
|
||||
}
|
||||
|
||||
for i, line in ipairs(lines) do
|
||||
for _, pattern in ipairs(patterns) do
|
||||
if line:match(pattern) then
|
||||
local method_sig = parse_method(line)
|
||||
if method_sig then
|
||||
table.insert(methods, method_sig)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return methods
|
||||
end
|
||||
|
||||
-- Get struct name under cursor
|
||||
local function get_struct_name()
|
||||
local line = vim.api.nvim_get_current_line()
|
||||
|
||||
-- Try to match: type StructName struct
|
||||
local struct_name = line:match("^type%s+([%w_]+)%s+struct")
|
||||
|
||||
if not struct_name then
|
||||
-- Try to match if cursor is on struct keyword
|
||||
struct_name = line:match("type%s+([%w_]+)%s+struct")
|
||||
end
|
||||
|
||||
return struct_name
|
||||
end
|
||||
|
||||
-- Generate interface from methods
|
||||
local function generate_interface(struct_name, methods)
|
||||
if #methods == 0 then
|
||||
return nil, "No methods found for struct " .. struct_name
|
||||
end
|
||||
|
||||
-- Create interface name (conventionally, I + StructName or StructName + er)
|
||||
local interface_name = "I" .. struct_name
|
||||
|
||||
local lines = {
|
||||
"type " .. interface_name .. " interface {",
|
||||
}
|
||||
|
||||
for _, method in ipairs(methods) do
|
||||
local method_without_bracket = method:gsub("{$", "")
|
||||
local cleaned_method = method_without_bracket:gsub("%s+$", "")
|
||||
table.insert(lines, "\t" .. cleaned_method)
|
||||
end
|
||||
|
||||
table.insert(lines, "}")
|
||||
|
||||
return lines, nil
|
||||
end
|
||||
|
||||
-- Main function to extract interface
|
||||
function M.extract_interface()
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
|
||||
-- Check if we're in a Go file
|
||||
local filetype = vim.bo[bufnr].filetype
|
||||
if filetype ~= "go" then
|
||||
vim.notify("This command only works in Go files", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
-- Get struct name under cursor
|
||||
local struct_name = get_struct_name()
|
||||
if not struct_name then
|
||||
vim.notify("Cursor is not on a struct definition", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
-- Find all methods for this struct
|
||||
local methods = find_struct_methods(struct_name, bufnr)
|
||||
|
||||
-- Generate interface
|
||||
local interface_lines, err = generate_interface(struct_name, methods)
|
||||
if err then
|
||||
vim.notify(err, vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
|
||||
-- Insert interface above the struct definition
|
||||
local cursor_line = vim.api.nvim_win_get_cursor(0)[1]
|
||||
vim.api.nvim_buf_set_lines(bufnr, cursor_line - 1, cursor_line - 1, false, interface_lines)
|
||||
vim.api.nvim_buf_set_lines(bufnr, cursor_line, cursor_line, false, { "" }) -- Empty line
|
||||
|
||||
vim.notify("Interface extracted: " .. #methods .. " methods found", vim.log.levels.INFO)
|
||||
end
|
||||
|
||||
-- Setup function for lazy.nvim
|
||||
function M.setup()
|
||||
-- Create command
|
||||
vim.api.nvim_create_user_command("GoExtractInterface", M.extract_interface, {
|
||||
desc = "Extract interface from Go struct under cursor",
|
||||
})
|
||||
|
||||
-- Optional: Add keybinding
|
||||
vim.keymap.set("n", "<leader>cei", M.extract_interface, {
|
||||
desc = "Extract interface from struct",
|
||||
silent = true,
|
||||
})
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user