[mirror] Make your go dev experience better github.com/olexsmir/gopher.nvim
neovim golang
at main 4.0 kB view raw
1---@toc_entry json2go 2---@tag gopher.nvim-json2go 3---@text 4--- Convert json to go type annotations. 5--- 6---@usage 7--- `:GoJson` opens a temporary buffer where you can paste or write JSON. 8--- Saving the buffer (`:w` or `:wq`) automatically closes it and inserts the 9--- generated Go struct into the original buffer at the cursor position. 10--- 11--- Alternatively, you can pass JSON directly as an argument: 12--- >vim 13--- :GoJson {"name": "Alice", "age": 30} 14--- < 15 16local c = require "gopher.config" 17local log = require "gopher._utils.log" 18local u = require "gopher._utils" 19local r = require "gopher._utils.runner" 20local json2go = {} 21 22---@dochide 23---@param bufnr integer 24---@param cpos integer 25---@param type_ string 26local function apply(bufnr, cpos, type_) 27 local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) 28 local input_lines = u.remove_empty_lines(vim.split(type_, "\n")) 29 for i, line in pairs(input_lines) do 30 table.insert(lines, cpos + i, line) 31 end 32 vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, lines) 33end 34 35-- Convert json string to go type. 36--- 37---@param json_str string Json string that is going to be converted to go type. 38---@return string? Go type, or nil if failed. 39function json2go.transform(json_str) 40 local cmd = { c.commands.json2go } 41 if c.json2go.type_name then 42 table.insert(cmd, "-type", c.json2go.type_name) 43 end 44 45 local rs = r.sync(cmd, { stdin = json_str }) 46 if rs.code ~= 0 then 47 u.notify("json2go: got this error: " .. rs.stdout, vim.log.levels.ERROR) 48 log.error("json2go: got this error: " .. rs.stdout) 49 return 50 end 51 return rs.stdout 52end 53 54---@dochide 55---@param ocpos integer 56local function interactive(ocpos) 57 local obuf = vim.api.nvim_get_current_buf() 58 local owin = vim.api.nvim_get_current_win() 59 60 -- setup the input window 61 local buf = vim.api.nvim_create_buf(false, true) 62 vim.cmd(c.json2go.interactive_cmd) 63 64 local win = vim.api.nvim_get_current_win() 65 vim.api.nvim_win_set_buf(win, buf) 66 vim.api.nvim_buf_set_name(buf, "[GoJson input]") 67 vim.api.nvim_set_option_value("filetype", "jsonc", { buf = buf }) 68 vim.api.nvim_set_option_value("buftype", "acwrite", { buf = buf }) 69 vim.api.nvim_set_option_value("swapfile", false, { buf = buf }) 70 vim.api.nvim_set_option_value("bufhidden", "delete", { buf = buf }) 71 vim.api.nvim_buf_set_lines(buf, 0, -1, false, { 72 "// Write your json here.", 73 "// Writing and quitting (:wq), will generate go struct under the cursor.", 74 "", 75 "", 76 }) 77 78 vim.api.nvim_create_autocmd("BufLeave", { buffer = buf, command = "stopinsert" }) 79 vim.api.nvim_create_autocmd("BufWriteCmd", { 80 buffer = buf, 81 once = true, 82 callback = function() 83 local input = vim.api.nvim_buf_get_lines(buf, 0, -1, true) 84 local inp = table.concat( 85 vim 86 .iter(input) 87 :filter(function(line) 88 local found = string.find(line, "^//.*") 89 return (not found) or (line == "") 90 end) 91 :totable(), 92 "\n" 93 ) 94 95 local go_type = json2go.transform(inp) 96 if not go_type then 97 error "cound't convert json to go type" 98 end 99 100 vim.api.nvim_set_option_value("modified", false, { buf = buf }) 101 apply(obuf, ocpos, go_type) 102 103 vim.api.nvim_set_current_win(owin) 104 vim.api.nvim_win_set_cursor(owin, { ocpos + 1, 0 }) 105 106 vim.schedule(function() 107 pcall(vim.api.nvim_win_close, win, true) 108 pcall(vim.api.nvim_buf_delete, buf, {}) 109 end) 110 end, 111 }) 112 113 vim.cmd "normal! G" 114 vim.cmd "startinsert" 115end 116 117--- Converts json string to go type, and puts result under the cursor. If 118--- [json_str] is nil, will open an interactive prompt (with cmd set in 119--- config). 120--- 121---@param json_str? string 122function json2go.json2go(json_str) 123 local cur_line = vim.api.nvim_win_get_cursor(0)[1] 124 if not json_str then 125 interactive(cur_line) 126 return 127 end 128 129 local go_type = json2go.transform(json_str) 130 if not go_type then 131 error "cound't convert json to go type" 132 end 133 134 apply(0, cur_line, go_type) 135end 136 137return json2go