all repos

gopher.nvim @ b6d3815f9b7db3d5cfd28003f58245ff0b5b3e3c

Minimalistic plugin for Go development
8 files changed, 129 insertions(+), 26 deletions(-)
feat(struct_tags): add range support (#117)

* feat(struct_tags): add range support

* refactor: use `start`, and `end_` naming for ranges
Author: Oleksandr Smirnov ss2316544@gmail.com
Committed by: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2025-08-30 16:58:32 +0300
Change ID: rkvmxqsolnsrnrnkztupsotsupulkpvn
Parent: 8c87952
M lua/gopher/_utils/ts.lua

@@ -65,8 +65,8 @@ end

---@class gopher.TsResult ---@field name string ----@field start_line integer ----@field end_line integer +---@field start integer +---@field end_ integer ---@field is_varstruct boolean ---@param bufnr integer

@@ -95,8 +95,8 @@ local res = get_captures(q, parent_node, bufnr)

assert(res.name ~= nil, "No capture name found") local start_row, _, end_row, _ = parent_node:range() - res["start_line"] = start_row + 1 - res["end_line"] = end_row + 1 + res["start"] = start_row + 1 + res["end_"] = end_row + 1 return res end
M lua/gopher/struct_tags.lua

@@ -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,9 +64,10 @@ "-file", fpath,

"-w", } - if st.is_varstruct then + -- `-struct` and `-line` cannot be combined, setting them separately + if range or st.is_varstruct 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 or st).start, (range or st).end_)) else table.insert(cmd, "-struct") table.insert(cmd, st.name)

@@ -93,7 +105,7 @@

---@param args string[] ---@return string ---@dochide -local function handler_user_args(args) +local function handler_user_tags(args) if #args == 0 then return c.gotag.default_tag end

@@ -102,28 +114,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_tags(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_tags(opts.tags) + handle_tags(fpath, bufnr, opts.range, { "-remove-tags", user_tags }) end -- Removes all tags from a struct under the cursor

@@ -132,7 +146,7 @@ ---@dochide

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
M plugin/gopher.lua

@@ -11,10 +11,13 @@

---@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()
A spec/fixtures/tags/add_range_input.go

@@ -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 + } +}
A spec/fixtures/tags/add_range_output.go

@@ -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 + } +}
A spec/fixtures/tags/remove_range_input.go

@@ -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"` +}
A spec/fixtures/tags/remove_range_output.go

@@ -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"` +}
M spec/integration/struct_tags_test.lua

@@ -78,4 +78,22 @@ t.eq(t.readfile(rs.tmp), rs.fixtures.output)

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