feat(strct-tags): add support for tag options (#126)

* feat(struct_tags): add options support

* refactor(struct-tags): give input field better name

* feat(struct-tag): add default option

* refactor: make it work on neovim version below 0.12

* chore(struct-tags): update the demo

* refactor: unite struct_tags util with main logic
This commit is contained in:
Oleksandr Smirnov 2025-10-30 12:25:42 +02:00
parent 0de1892ca9
commit 7a18d9f7bd
No known key found for this signature in database
19 changed files with 301 additions and 15 deletions

View file

@ -50,4 +50,23 @@ function utils.indent(line, indent)
return string.rep(char, indent)
end
---@generic T
---@param tbl T[]
---@return T[]
function utils.list_unique(tbl)
if vim.fn.has "nvim-0.12" == 1 then
return vim.list.unique(tbl)
end
for i = #tbl, 1, -1 do
for j = 1, i - 1 do
if tbl[i] == tbl[j] then
table.remove(tbl, i)
break
end
end
end
return tbl
end
return utils

View file

@ -61,6 +61,10 @@ local default_config = {
-- default tags to add to struct fields
default_tag = "json",
-- default tag option added struct fields, set to nil to disable
---@type string|nil
option = nil,
},
iferr = {
-- choose a custom error message
@ -105,6 +109,7 @@ function config.setup(user_config)
vim.validate("gotag", _config.gotag, "table")
vim.validate("gotag.transform", _config.gotag.transform, "string")
vim.validate("gotag.default_tag", _config.gotag.default_tag, "string")
vim.validate("gotag.option", _config.gotag.option, { "string", "nil" })
vim.validate("iferr", _config.iferr, "table")
vim.validate("iferr.message", _config.iferr.message, { "string", "nil" })
end

View file

@ -9,6 +9,9 @@
--- 2. Run `:GoTagAdd json` to add json tags to struct fields
--- 3. Run `:GoTagRm json` to remove json tags to struct fields
---
--- If you want to add/remove tag with options, you can use `json=omitempty` (where json is tag, and omitempty is its option).
--- Example: `:GoTagAdd xml json=omitempty`
---
--- To clear all tags from struct run: `:GoTagClear`
---
--- NOTE: if you dont specify the tag it will use `json` as default
@ -39,7 +42,7 @@ local struct_tags = {}
---@dochide
---@class gopher.StructTagInput
---@field tags string[] User provided tags
---@field input string[] User provided tags
---@field range? gopher.StructTagRange (optional)
---@dochide
@ -102,18 +105,53 @@ local function handle_tags(fpath, bufnr, range, user_args)
)
end
---@param args string[]
---@return string
---@dochide
local function handler_user_tags(args)
if #args == 0 then
return c.gotag.default_tag
---@param option string
local function option_to_tag(option)
return option:match "^(.-)="
end
---@dochide
---@param args string[]
local function unwrap_if_needed(args)
local out = {}
for _, v in pairs(args) do
for _, p in pairs(vim.split(v, ",")) do
table.insert(out, p)
end
end
return table.concat(args, ",")
return out
end
---@dochide
---@class gopher.StructTagsArgs
---@field tags string
---@field options string
---@dochide
---@param args string[]
---@return gopher.StructTagsArgs
function struct_tags.parse_args(args)
args = unwrap_if_needed(args)
local tags, options = {}, {}
for _, v in pairs(args) do
if string.find(v, "=") then
table.insert(options, v)
table.insert(tags, option_to_tag(v))
else
table.insert(tags, v)
end
end
return {
tags = table.concat(u.list_unique(tags), ","),
options = table.concat(u.list_unique(options), ","),
}
end
-- Adds tags to a struct under the cursor
-- See |gopher.nvim-struct-tags|
-- See `:h gopher.nvim-struct-tags`
---@param opts gopher.StructTagInput
---@dochide
function struct_tags.add(opts)
@ -122,8 +160,13 @@ function struct_tags.add(opts)
local fpath = vim.fn.expand "%"
local bufnr = vim.api.nvim_get_current_buf()
local user_tags = handler_user_tags(opts.tags)
handle_tags(fpath, bufnr, opts.range, { "-add-tags", user_tags })
local user_args = struct_tags.parse_args(opts.input)
handle_tags(fpath, bufnr, opts.range, {
"-add-tags",
(user_args.tags ~= "") and user_args.tags or c.gotag.default_tag,
(user_args.options ~= "" or c.gotag.option) and "-add-options" or nil,
(user_args.options ~= "") and user_args.options or c.gotag.option,
})
end
-- Removes tags from a struct under the cursor
@ -136,8 +179,13 @@ function struct_tags.remove(opts)
local fpath = vim.fn.expand "%"
local bufnr = vim.api.nvim_get_current_buf()
local user_tags = handler_user_tags(opts.tags)
handle_tags(fpath, bufnr, opts.range, { "-remove-tags", user_tags })
local user_args = struct_tags.parse_args(opts.input)
handle_tags(fpath, bufnr, opts.range, {
"-remove-tags",
(user_args.tags ~= "") and user_args.tags or c.gotag.default_tag,
(user_args.options ~= "" or c.gotag.option ~= nil) and "-remove-options" or nil,
(user_args.options ~= "") and user_args.options or c.gotag.option,
})
end
-- Removes all tags from a struct under the cursor