refactor: struct tags (#94)
* refactor(struct_tags): finally my hands got to this * feat(struct_tags): trim output * feat(struct_tags): add :GoTagClear * docgen * refactor(struct_tags): error on out-of-bounds * feat(struct_tags): add support for working with multiple tags at the once * test(struct_tags): test both possible inputs * refactor(struct_tags): add type annotation, dont force write * refactor(struct_tags): optimization ig * docs: fix * fixup! refactor(struct_tags): add type annotation, dont force write * task docgen --------- Co-authored-by: Oliver <1571880470@qq.com>
This commit is contained in:
parent
e9f2eef5e7
commit
55bc5787d1
10 changed files with 177 additions and 70 deletions
|
|
@ -129,6 +129,25 @@ Example:
|
||||||
Name string `yaml:name`
|
Name string `yaml:name`
|
||||||
}
|
}
|
||||||
<
|
<
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*struct_tags.add()*
|
||||||
|
`struct_tags.add`({...})
|
||||||
|
tags to a struct under the cursor
|
||||||
|
Parameters ~
|
||||||
|
{...} `(string)` Tags to add to the struct fields. If not provided, it will use [config.gotag.default_tag]
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*struct_tags.remove()*
|
||||||
|
`struct_tags.remove`({...})
|
||||||
|
tags from a struct under the cursor
|
||||||
|
Parameters ~
|
||||||
|
{...} `(string)` Tags to add to the struct fields. If not provided, it will use [config.gotag.default_tag]
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*struct_tags.clear()*
|
||||||
|
`struct_tags.clear`()
|
||||||
|
all tags from a struct under the cursor
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ gopher.comment = require("gopher.comment").comment
|
||||||
gopher.tags = {
|
gopher.tags = {
|
||||||
add = tags.add,
|
add = tags.add,
|
||||||
rm = tags.remove,
|
rm = tags.remove,
|
||||||
|
clear = tags.clear,
|
||||||
}
|
}
|
||||||
|
|
||||||
gopher.test = {
|
gopher.test = {
|
||||||
|
|
|
||||||
|
|
@ -26,90 +26,96 @@
|
||||||
--- }
|
--- }
|
||||||
--- <
|
--- <
|
||||||
|
|
||||||
local ts_utils = require "gopher._utils.ts"
|
local ts = require "gopher._utils.ts"
|
||||||
local r = require "gopher._utils.runner"
|
local r = require "gopher._utils.runner"
|
||||||
local c = require "gopher.config"
|
local c = require "gopher.config"
|
||||||
|
local log = require "gopher._utils.log"
|
||||||
local struct_tags = {}
|
local struct_tags = {}
|
||||||
|
|
||||||
local function modify(...)
|
---@param fpath string
|
||||||
local fpath = vim.fn.expand "%" ---@diagnostic disable-line: missing-parameter
|
---@param bufnr integer
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
---@param user_args string[]
|
||||||
local struct = ts_utils.get_struct_under_cursor(bufnr)
|
---@private
|
||||||
|
local function handle_tags(fpath, bufnr, user_args)
|
||||||
|
local st = ts.get_struct_under_cursor(bufnr)
|
||||||
|
|
||||||
-- set user args for cmd
|
-- stylua: ignore
|
||||||
local cmd_args = {}
|
local cmd = {
|
||||||
local arg = { ... }
|
|
||||||
for _, v in ipairs(arg) do
|
|
||||||
table.insert(cmd_args, v)
|
|
||||||
end
|
|
||||||
|
|
||||||
local rs = r.sync {
|
|
||||||
c.commands.gomodifytags,
|
c.commands.gomodifytags,
|
||||||
"-transform",
|
"-transform", c.gotag.transform,
|
||||||
c.gotag.transform,
|
"-format", "json",
|
||||||
"-format",
|
"-struct", st.name,
|
||||||
"json",
|
"-file", fpath,
|
||||||
"-struct",
|
|
||||||
struct.name,
|
|
||||||
"-w",
|
"-w",
|
||||||
"-file",
|
|
||||||
fpath,
|
|
||||||
unpack(cmd_args),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, v in ipairs(user_args) do
|
||||||
|
table.insert(cmd, v)
|
||||||
|
end
|
||||||
|
|
||||||
|
local rs = r.sync(cmd)
|
||||||
if rs.code ~= 0 then
|
if rs.code ~= 0 then
|
||||||
|
log.error("tags: failed to set tags " .. rs.stderr)
|
||||||
error("failed to set tags " .. rs.stderr)
|
error("failed to set tags " .. rs.stderr)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- decode value
|
local res = vim.json.decode(rs.stdout)
|
||||||
local tagged = vim.json.decode(rs.stdout)
|
|
||||||
if
|
if res["errors"] then
|
||||||
tagged.errors ~= nil
|
log.error("tags: got an error " .. vim.inspect(res))
|
||||||
or tagged.lines == nil
|
error("failed to set tags " .. vim.inspect(res["errors"]))
|
||||||
or tagged["start"] == nil
|
end
|
||||||
or tagged["start"] == 0
|
|
||||||
then
|
for i, v in ipairs(res["lines"]) do
|
||||||
error("failed to set tags " .. vim.inspect(tagged))
|
res["lines"][i] = string.gsub(v, "%s+$", "")
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.api.nvim_buf_set_lines(
|
vim.api.nvim_buf_set_lines(
|
||||||
0,
|
bufnr,
|
||||||
tagged.start - 1,
|
res["start"] - 1,
|
||||||
tagged.start - 1 + #tagged.lines,
|
res["start"] - 1 + #res["lines"],
|
||||||
false,
|
true,
|
||||||
tagged.lines
|
res["lines"]
|
||||||
)
|
)
|
||||||
vim.cmd "write"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- add tags to struct under cursor
|
---@param args string[]
|
||||||
|
---@return string
|
||||||
|
---@private
|
||||||
|
local function handler_user_args(args)
|
||||||
|
if #args == 0 then
|
||||||
|
return c.gotag.default_tag
|
||||||
|
end
|
||||||
|
return table.concat(args, ",")
|
||||||
|
end
|
||||||
|
|
||||||
|
---Adds tags to a struct under the cursor
|
||||||
|
---@param ... string Tags to add to the struct fields. If not provided, it will use [config.gotag.default_tag]
|
||||||
function struct_tags.add(...)
|
function struct_tags.add(...)
|
||||||
local user_tags = { ... }
|
local args = { ... }
|
||||||
if #user_tags == 0 then
|
local fpath = vim.fn.expand "%"
|
||||||
user_tags = { c.gotag.default_tag }
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
end
|
|
||||||
|
|
||||||
local cmd_args = { "-add-tags" }
|
local user_tags = handler_user_args(args)
|
||||||
for _, v in ipairs(user_tags) do
|
handle_tags(fpath, bufnr, { "-add-tags", user_tags })
|
||||||
table.insert(cmd_args, v)
|
|
||||||
end
|
|
||||||
|
|
||||||
modify(unpack(cmd_args))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- remove tags to struct under cursor
|
---Removes tags from a struct under the cursor
|
||||||
|
---@param ... string Tags to add to the struct fields. If not provided, it will use [config.gotag.default_tag]
|
||||||
function struct_tags.remove(...)
|
function struct_tags.remove(...)
|
||||||
local user_tags = { ... }
|
local args = { ... }
|
||||||
if #user_tags == 0 then
|
local fpath = vim.fn.expand "%"
|
||||||
user_tags = { c.gotag.default_tag }
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
end
|
|
||||||
|
|
||||||
local cmd_args = { "-remove-tags" }
|
local user_tags = handler_user_args(args)
|
||||||
for _, v in ipairs(user_tags) do
|
handle_tags(fpath, bufnr, { "-remove-tags", user_tags })
|
||||||
table.insert(cmd_args, v)
|
end
|
||||||
end
|
|
||||||
|
|
||||||
modify(unpack(cmd_args))
|
---Removes all tags from a struct under the cursor
|
||||||
|
function struct_tags.clear()
|
||||||
|
local fpath = vim.fn.expand "%"
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
handle_tags(fpath, bufnr, { "-clear-tags" })
|
||||||
end
|
end
|
||||||
|
|
||||||
return struct_tags
|
return struct_tags
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
command! -nargs=* GoTagAdd :lua require"gopher".tags.add(<f-args>)
|
command! -nargs=* GoTagAdd :lua require"gopher".tags.add(<f-args>)
|
||||||
command! -nargs=* GoTagRm :lua require"gopher".tags.rm(<f-args>)
|
command! -nargs=* GoTagRm :lua require"gopher".tags.rm(<f-args>)
|
||||||
|
command! GoTagClear :lua require"gopher".tags.clear()
|
||||||
command! GoTestAdd :lua require"gopher".test.add()
|
command! GoTestAdd :lua require"gopher".test.add()
|
||||||
command! GoTestsAll :lua require"gopher".test.all()
|
command! GoTestsAll :lua require"gopher".test.all()
|
||||||
command! GoTestsExp :lua require"gopher".test.exported()
|
command! GoTestsExp :lua require"gopher".test.exported()
|
||||||
|
|
|
||||||
11
spec/fixtures/tags/add_many_input.go
vendored
Normal file
11
spec/fixtures/tags/add_many_input.go
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
type Test struct {
|
||||||
|
ID int
|
||||||
|
Name string
|
||||||
|
Num int64
|
||||||
|
Another struct {
|
||||||
|
First int
|
||||||
|
Second string
|
||||||
|
}
|
||||||
|
}
|
||||||
11
spec/fixtures/tags/add_many_output.go
vendored
Normal file
11
spec/fixtures/tags/add_many_output.go
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
type Test struct {
|
||||||
|
ID int `test4:"id" test5:"id" test1:"id" test2:"id"`
|
||||||
|
Name string `test4:"name" test5:"name" test1:"name" test2:"name"`
|
||||||
|
Num int64 `test4:"num" test5:"num" test1:"num" test2:"num"`
|
||||||
|
Another struct {
|
||||||
|
First int `test4:"first" test5:"first" test1:"first" test2:"first"`
|
||||||
|
Second string `test4:"second" test5:"second" test1:"second" test2:"second"`
|
||||||
|
} `test4:"another" test5:"another" test1:"another" test2:"another"`
|
||||||
|
}
|
||||||
11
spec/fixtures/tags/clear_input.go
vendored
Normal file
11
spec/fixtures/tags/clear_input.go
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
type Test struct {
|
||||||
|
ID int `json:"id" yaml:"id" xml:"id" db:"id"`
|
||||||
|
Name string `json:"name" yaml:"name" xml:"name" db:"name"`
|
||||||
|
Num int64 `json:"num" yaml:"num" xml:"num" db:"num"`
|
||||||
|
Another struct {
|
||||||
|
First int `json:"first" yaml:"first" xml:"first" db:"first"`
|
||||||
|
Second string `json:"second" yaml:"second" xml:"second" db:"second"`
|
||||||
|
} `json:"another" yaml:"another" xml:"another" db:"another"`
|
||||||
|
}
|
||||||
11
spec/fixtures/tags/clear_output.go
vendored
Normal file
11
spec/fixtures/tags/clear_output.go
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
type Test struct {
|
||||||
|
ID int
|
||||||
|
Name string
|
||||||
|
Num int64
|
||||||
|
Another struct {
|
||||||
|
First int
|
||||||
|
Second string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,38 +10,74 @@ local T = MiniTest.new_set {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
T["struct_tags"] = MiniTest.new_set {}
|
T["struct_tags"] = MiniTest.new_set {}
|
||||||
T["struct_tags"]["works add"] = function()
|
T["struct_tags"]["should add tag"] = function()
|
||||||
local tmp = t.tmpfile()
|
local tmp = t.tmpfile()
|
||||||
local fixtures = t.get_fixtures "tags/add"
|
local fixtures = t.get_fixtures "tags/add"
|
||||||
t.writefile(tmp, fixtures.input)
|
t.writefile(tmp, fixtures.input)
|
||||||
|
|
||||||
child.cmd("silent edit " .. tmp)
|
child.cmd("silent edit " .. tmp)
|
||||||
child.fn.setpos(".", { child.fn.bufnr "%", 3, 6, 0 })
|
child.fn.setpos(".", { child.fn.bufnr(tmp), 3, 6, 0 })
|
||||||
child.cmd "GoTagAdd json"
|
child.cmd "GoTagAdd json"
|
||||||
|
child.cmd "write"
|
||||||
|
|
||||||
t.eq(t.readfile(tmp), fixtures.output)
|
t.eq(t.readfile(tmp), fixtures.output)
|
||||||
end
|
end
|
||||||
|
|
||||||
T["struct_tags"]["works remove"] = function()
|
T["struct_tags"]["should remove tag"] = function()
|
||||||
local tmp = t.tmpfile()
|
local tmp = t.tmpfile()
|
||||||
local fixtures = t.get_fixtures "tags/remove"
|
local fixtures = t.get_fixtures "tags/remove"
|
||||||
t.writefile(tmp, fixtures.input)
|
t.writefile(tmp, fixtures.input)
|
||||||
|
|
||||||
child.cmd("silent edit " .. tmp)
|
child.cmd("silent edit " .. tmp)
|
||||||
child.fn.setpos(".", { child.fn.bufnr "%", 4, 6, 0 })
|
child.fn.setpos(".", { child.fn.bufnr(tmp), 4, 6, 0 })
|
||||||
child.cmd "GoTagRm json"
|
child.cmd "GoTagRm json"
|
||||||
|
child.cmd "write"
|
||||||
|
|
||||||
t.eq(t.readfile(tmp), fixtures.output)
|
t.eq(t.readfile(tmp), fixtures.output)
|
||||||
end
|
end
|
||||||
|
|
||||||
T["struct_tags"]["works many structs"] = function()
|
T["struct_tags"]["should be able to handle many structs"] = function()
|
||||||
local tmp = t.tmpfile()
|
local tmp = t.tmpfile()
|
||||||
local fixtures = t.get_fixtures "tags/many"
|
local fixtures = t.get_fixtures "tags/many"
|
||||||
t.writefile(tmp, fixtures.input)
|
t.writefile(tmp, fixtures.input)
|
||||||
|
|
||||||
child.cmd("silent edit " .. tmp)
|
child.cmd("silent edit " .. tmp)
|
||||||
child.fn.setpos(".", { child.fn.bufnr "%", 10, 3, 0 })
|
child.fn.setpos(".", { child.fn.bufnr(tmp), 10, 3, 0 })
|
||||||
child.cmd "GoTagAdd testing"
|
child.cmd "GoTagAdd testing"
|
||||||
|
child.cmd "write"
|
||||||
|
|
||||||
|
t.eq(t.readfile(tmp), fixtures.output)
|
||||||
|
end
|
||||||
|
|
||||||
|
T["struct_tags"]["should clear struct"] = function()
|
||||||
|
local tmp = t.tmpfile()
|
||||||
|
local fixtures = t.get_fixtures "tags/clear"
|
||||||
|
t.writefile(tmp, fixtures.input)
|
||||||
|
|
||||||
|
child.cmd("silent edit " .. tmp)
|
||||||
|
child.fn.setpos(".", { child.fn.bufnr(tmp), 3, 1, 0 })
|
||||||
|
child.cmd "GoTagClear"
|
||||||
|
child.cmd "write"
|
||||||
|
|
||||||
|
t.eq(t.readfile(tmp), fixtures.output)
|
||||||
|
end
|
||||||
|
|
||||||
|
T["struct_tags"]["should add more than one tag"] = function()
|
||||||
|
local tmp = t.tmpfile()
|
||||||
|
local fixtures = t.get_fixtures "tags/add_many"
|
||||||
|
t.writefile(tmp, fixtures.input)
|
||||||
|
|
||||||
|
--- with comma, like gomodifytags
|
||||||
|
child.cmd("silent edit " .. tmp)
|
||||||
|
child.fn.setpos(".", { child.fn.bufnr(tmp), 3, 1 })
|
||||||
|
child.cmd "GoTagAdd test4,test5"
|
||||||
|
child.cmd "write"
|
||||||
|
|
||||||
|
-- without comma
|
||||||
|
child.cmd("silent edit " .. tmp)
|
||||||
|
child.fn.setpos(".", { child.fn.bufnr(tmp), 3, 1 })
|
||||||
|
child.cmd "GoTagAdd test1 test2"
|
||||||
|
child.cmd "write"
|
||||||
|
|
||||||
t.eq(t.readfile(tmp), fixtures.output)
|
t.eq(t.readfile(tmp), fixtures.output)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue