diff --git a/doc/gopher.nvim.txt b/doc/gopher.nvim.txt index 9995dd3..9232031 100644 --- a/doc/gopher.nvim.txt +++ b/doc/gopher.nvim.txt @@ -13,6 +13,7 @@ Table of Contents Config ................................................ |gopher.nvim-config| Commands ............................................ |gopher.nvim-commands| Modify struct tags ............................... |gopher.nvim-struct-tags| + json2go .............................................. |gopher.nvim-json2go| Auto implementation of interface methods ................ |gopher.nvim-impl| Generating unit tests boilerplate .................... |gopher.nvim-gotests| Iferr .................................................. |gopher.nvim-iferr| @@ -69,6 +70,7 @@ or use `require("gopher").install_deps()` if you prefer lua api. gotests = "gotests", impl = "impl", iferr = "iferr", + json2go = "json2go", }, ---@class gopher.ConfigGotests gotests = { @@ -96,12 +98,24 @@ or use `require("gopher").install_deps()` if you prefer lua api. ---@type string|nil option = nil, }, + ---@class gopher.ConfigIfErr iferr = { -- choose a custom error message, nil to use default -- e.g: `message = 'fmt.Errorf("failed to %w", err)'` ---@type string|nil message = nil, }, + ---@class gopher.ConfigJson2Go + json2go = { + -- command used to open interactive input. + -- e.g: `split`, `botright split`, `tabnew` + interactive_cmd = "vsplit", + + -- name of autogenerated struct, if nil none, will the default one of json2go. + -- e.g: "MySuperCoolName" + ---@type string|nil + type_name = nil, + }, } < Class ~ @@ -157,6 +171,42 @@ Example: } < +============================================================================== +------------------------------------------------------------------------------ + *gopher.nvim-json2go* + +Convert json to go type annotations. + +Usage ~ + +`:GoJson` opens a temporary buffer where you can paste or write JSON. +Saving the buffer (`:w` or `:wq`) automatically closes it and inserts the +generated Go struct into the original buffer at the cursor position. + +Alternatively, you can pass JSON directly as an argument: +>vim + :GoJson {"name": "Alice", "age": 30} +< +------------------------------------------------------------------------------ + *json2go.transform()* + `json2go.transform`({json_str}) + +Parameters ~ +{json_str} `(string)` Json string that is going to be converted to go type. +Return ~ +`(string)` `(optional)` Go type, or nil if failed. + +------------------------------------------------------------------------------ + *json2go.json2go()* + `json2go.json2go`({json_str}) +Converts json string to go type, and puts result under the cursor. If +[json_str] is nil, will open an interactive prompt (with cmd set in +config). + +Parameters ~ +{json_str} `(optional)` `(string)` + + ============================================================================== ------------------------------------------------------------------------------ *gopher.nvim-impl* diff --git a/lua/gopher/config.lua b/lua/gopher/config.lua index ab99a28..4245989 100644 --- a/lua/gopher/config.lua +++ b/lua/gopher/config.lua @@ -69,12 +69,24 @@ local default_config = { ---@type string|nil option = nil, }, + ---@class gopher.ConfigIfErr iferr = { -- choose a custom error message, nil to use default -- e.g: `message = 'fmt.Errorf("failed to %w", err)'` ---@type string|nil message = nil, }, + ---@class gopher.ConfigJson2Go + json2go = { + -- command used to open interactive input. + -- e.g: `split`, `botright split`, `tabnew` + interactive_cmd = "vsplit", + + -- name of autogenerated struct, if nil none, will the default one of json2go. + -- e.g: "MySuperCoolName" + ---@type string|nil + type_name = nil, + }, } --minidoc_afterlines_end @@ -105,6 +117,7 @@ function config.setup(user_config) vim.validate("commands.gotests", _config.commands.gotests, "string") vim.validate("commands.impl", _config.commands.impl, "string") vim.validate("commands.iferr", _config.commands.iferr, "string") + vim.validate("commands.json2go", _config.commands.json2go, "string") vim.validate("gotests", _config.gotests, "table") vim.validate("gotests.template", _config.gotests.template, "string") vim.validate("gotests.template_dir", _config.gotests.template_dir, { "string", "nil" }) @@ -115,6 +128,8 @@ function config.setup(user_config) vim.validate("gotag.option", _config.gotag.option, { "string", "nil" }) vim.validate("iferr", _config.iferr, "table") vim.validate("iferr.message", _config.iferr.message, { "string", "nil" }) + vim.validate("json2go.installer_timeout", _config.json2go.interactive_cmd, "string") + vim.validate("json2go.type_name", _config.json2go.type_name, { "string", "nil" }) end setmetatable(config, { diff --git a/lua/gopher/json2go.lua b/lua/gopher/json2go.lua index 0fe24f5..40d0e9f 100644 --- a/lua/gopher/json2go.lua +++ b/lua/gopher/json2go.lua @@ -1,9 +1,25 @@ +---@toc_entry json2go +---@tag gopher.nvim-json2go +---@text +--- Convert json to go type annotations. +--- +---@usage +--- `:GoJson` opens a temporary buffer where you can paste or write JSON. +--- Saving the buffer (`:w` or `:wq`) automatically closes it and inserts the +--- generated Go struct into the original buffer at the cursor position. +--- +--- Alternatively, you can pass JSON directly as an argument: +--- >vim +--- :GoJson {"name": "Alice", "age": 30} +--- < + local c = require "gopher.config" local log = require "gopher._utils.log" local u = require "gopher._utils" local r = require "gopher._utils.runner" local json2go = {} +---@dochide ---@param bufnr integer ---@param cpos integer ---@param type_ string @@ -16,10 +32,17 @@ local function apply(bufnr, cpos, type_) vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, lines) end ----@param json_str string ----@return string? +-- Convert json string to go type. +--- +---@param json_str string Json string that is going to be converted to go type. +---@return string? Go type, or nil if failed. function json2go.transform(json_str) - local rs = r.sync({ c.commands.json2go }, { stdin = json_str }) + local cmd = { c.commands.json2go } + if c.json2go.type_name then + table.insert(cmd, "-type", c.json2go.type_name) + end + + local rs = r.sync(cmd, { stdin = json_str }) if rs.code ~= 0 then u.notify("json2go: got this error: " .. rs.stdout, vim.log.levels.ERROR) log.error("json2go: got this error: " .. rs.stdout) @@ -28,13 +51,15 @@ function json2go.transform(json_str) return rs.stdout end +---@dochide +---@param ocpos integer local function interactive(ocpos) local obuf = vim.api.nvim_get_current_buf() local owin = vim.api.nvim_get_current_win() -- setup the input window local buf = vim.api.nvim_create_buf(false, true) - vim.api.nvim_command "vsplit" -- TODO: make it configurable + vim.cmd(c.json2go.interactive_cmd) local win = vim.api.nvim_get_current_win() vim.api.nvim_win_set_buf(win, buf) @@ -89,6 +114,10 @@ local function interactive(ocpos) vim.cmd "startinsert" end +--- Converts json string to go type, and puts result under the cursor. If +--- [json_str] is nil, will open an interactive prompt (with cmd set in +--- config). +--- ---@param json_str? string function json2go.json2go(json_str) local cur_line = vim.api.nvim_win_get_cursor(0)[1] diff --git a/scripts/docgen.lua b/scripts/docgen.lua index 1c66b90..48d906b 100644 --- a/scripts/docgen.lua +++ b/scripts/docgen.lua @@ -12,6 +12,7 @@ local files = { "lua/gopher/config.lua", "plugin/gopher.lua", "lua/gopher/struct_tags.lua", + "lua/gopher/json2go.lua", "lua/gopher/impl.lua", "lua/gopher/gotests.lua", "lua/gopher/iferr.lua",