feat(struct_tags): add range support

This commit is contained in:
Oleksandr Smirnov 2025-08-29 18:37:28 +03:00
parent ca1d4fda88
commit 46725147f7
No known key found for this signature in database
7 changed files with 132 additions and 23 deletions

View file

@ -37,11 +37,22 @@ local u = require "gopher._utils"
local log = require "gopher._utils.log"
local struct_tags = {}
---@dochide
---@class gopher.StructTagInput
---@field tags string[] User provided tags
---@field range? gopher.StructTagRange (optional)
---@dochide
---@class gopher.StructTagRange
---@field start number
---@field end_ number
---@param fpath string
---@param bufnr integer
---@param range? gopher.StructTagRange
---@param user_args string[]
---@dochide
local function handle_tags(fpath, bufnr, user_args)
local function handle_tags(fpath, bufnr, range, user_args)
local st = ts.get_struct_under_cursor(bufnr)
-- stylua: ignore
@ -53,12 +64,19 @@ local function handle_tags(fpath, bufnr, user_args)
"-w",
}
if st.is_varstruct then
-- since `-strut` and `-line` cannot be combined together set set them only
-- if user doesn't do ranges
if range ~= nil then
table.insert(cmd, "-line")
table.insert(cmd, string.format("%d,%d", st.start_line, st.end_line))
table.insert(cmd, string.format("%d,%d", range.start, range.end_))
else
table.insert(cmd, "-struct")
table.insert(cmd, st.name)
if st.is_varstruct then
table.insert(cmd, "-line")
table.insert(cmd, string.format("%d,%d", st.start_line, st.end_line))
else
table.insert(cmd, "-struct")
table.insert(cmd, st.name)
end
end
for _, v in ipairs(user_args) do
@ -102,28 +120,30 @@ end
-- Adds tags to a struct under the cursor
-- See |gopher.nvim-struct-tags|
---@param ... string Tags to add to the struct fields. If not provided, it will use [config.gotag.default_tag]
---@param opts gopher.StructTagInput
---@dochide
function struct_tags.add(...)
local args = { ... }
function struct_tags.add(opts)
log.debug("adding tags", opts)
local fpath = vim.fn.expand "%"
local bufnr = vim.api.nvim_get_current_buf()
local user_tags = handler_user_args(args)
handle_tags(fpath, bufnr, { "-add-tags", user_tags })
local user_tags = handler_user_args(opts.tags)
handle_tags(fpath, bufnr, opts.range, { "-add-tags", user_tags })
end
-- Removes tags from a struct under the cursor
-- See `:h gopher.nvim-struct-tags`
---@dochide
---@param ... string Tags to add to the struct fields. If not provided, it will use [config.gotag.default_tag]
function struct_tags.remove(...)
local args = { ... }
---@param opts gopher.StructTagInput
function struct_tags.remove(opts)
log.debug("removing tags", opts)
local fpath = vim.fn.expand "%"
local bufnr = vim.api.nvim_get_current_buf()
local user_tags = handler_user_args(args)
handle_tags(fpath, bufnr, { "-remove-tags", user_tags })
local user_tags = handler_user_args(opts.tags)
handle_tags(fpath, bufnr, opts.range, { "-remove-tags", user_tags })
end
-- Removes all tags from a struct under the cursor
@ -132,7 +152,7 @@ end
function struct_tags.clear()
local fpath = vim.fn.expand "%"
local bufnr = vim.api.nvim_get_current_buf()
handle_tags(fpath, bufnr, { "-clear-tags" })
handle_tags(fpath, bufnr, nil, { "-clear-tags" })
end
return struct_tags

View file

@ -11,10 +11,13 @@ end
---@param name string
---@param fn fun(args: table)
---@param nargs? number|"*"|"?"
---@param range? boolean
---@private
local function cmd(name, fn, nargs)
nargs = nargs or 0
vim.api.nvim_create_user_command(name, fn, { nargs = nargs })
local function cmd(name, fn, nargs, range)
vim.api.nvim_create_user_command(name, fn, {
nargs = nargs or 0,
range = range or false,
})
end
cmd("GopherLog", function()
@ -44,12 +47,24 @@ end)
-- :GoTag
cmd("GoTagAdd", function(opts)
require("gopher").tags.add(unpack(opts.fargs))
end, "*")
require("gopher").tags.add {
tags = opts.fargs,
range = (opts.count ~= -1) and {
start = opts.line1,
end_ = opts.line2,
} or nil,
}
end, "*", true)
cmd("GoTagRm", function(opts)
require("gopher").tags.rm(unpack(opts.fargs))
end, "*")
require("gopher").tags.rm {
tags = opts.fargs,
range = (opts.count ~= -1) and {
start = opts.line1,
end_ = opts.line2,
} or nil,
}
end, "*", true)
cmd("GoTagClear", function()
require("gopher").tags.clear()

14
spec/fixtures/tags/add_range_input.go vendored Normal file
View file

@ -0,0 +1,14 @@
package main
type Test struct {
ID int
Name string
Num int64
Cost int
Thingy []string
Testing int
Another struct {
First int
Second string
}
}

14
spec/fixtures/tags/add_range_output.go vendored Normal file
View file

@ -0,0 +1,14 @@
package main
type Test struct {
ID int
Name string `gopher:"name"`
Num int64 `gopher:"num"`
Cost int `gopher:"cost"`
Thingy []string
Testing int
Another struct {
First int
Second string
}
}

View file

@ -0,0 +1,14 @@
package main
type Test struct {
ID int `asdf:"id"`
Name string `asdf:"name"`
Num int64 `asdf:"num"`
Cost int `asdf:"cost"`
Thingy []string `asdf:"thingy"`
Testing int `asdf:"testing"`
Another struct {
First int `asdf:"first"`
Second string `asdf:"second"`
} `asdf:"another"`
}

View file

@ -0,0 +1,14 @@
package main
type Test struct {
ID int `asdf:"id"`
Name string `asdf:"name"`
Num int64
Cost int
Thingy []string
Testing int `asdf:"testing"`
Another struct {
First int `asdf:"first"`
Second string `asdf:"second"`
} `asdf:"another"`
}

View file

@ -78,4 +78,22 @@ struct_tags["should add tags on short declr var"] = function()
t.cleanup(rs)
end
struct_tags["should add tag with range"] = function()
local rs = t.setup_test("tags/add_range", child, { 5, 1 })
child.cmd ".,+2GoTagAdd gopher"
child.cmd "write"
t.eq(t.readfile(rs.tmp), rs.fixtures.output)
t.cleanup(rs)
end
struct_tags["should remove tag with range"] = function()
local rs = t.setup_test("tags/remove_range", child, { 6, 1 })
child.cmd ".,+2GoTagRm asdf"
child.cmd "write"
t.eq(t.readfile(rs.tmp), rs.fixtures.output)
t.cleanup(rs)
end
return T