`gonew` with template URL; update `go work`

cleanup sandbox
pull/399/head
ray-x 6 months ago
parent 38f6402fa5
commit f9672fd446

@ -689,6 +689,7 @@ if err != nil {
- GoNew {filename}
Create new go file. It will use template file. e.g. `GoNew ./pkg/string.go` will create string.go with template file
GoNew also support using `gonew` command to create new file with template file [gonew cli](https://go.dev/blog/gonew), e.g `GoNew hello package_name/folder` is same as `gonew golang.org/x/example/hello package_name/folder` if package_name/folder not provided, a hello project will be created in current folder
### ginkgo

@ -468,7 +468,13 @@ return {
end, { nargs = '*' })
create_cmd('GoNew', function(opts)
require('go.template.gonew').new(opts.fargs)
end, { nargs = '*' })
end, {
nargs = '*',
complete = function(_, _, _)
-- return completion candidates as a list-like table
return require('go.template.gonew').complete
end,
})
create_cmd('Ginkgo', function(opts)
require('go.ginkgo').run(opts.fargs)
end, {

@ -27,6 +27,7 @@ local url = {
gomvp = 'github.com/abenz1267/gomvp',
govulncheck = 'golang.org/x/vuln/cmd/govulncheck',
['go-enum'] = 'github.com/abice/go-enum',
gonew = 'golang.org/x/tools/cmd/gonew',
}
local tools = {}
@ -95,6 +96,7 @@ local function go_install_sync(pkg)
end
end
-- async install pkg
local function go_install(pkg)
local u = url[pkg]
if u == nil then

@ -38,7 +38,7 @@ local run = function(cmd, opts, uvopts)
local function update_chunk_fn(err, chunk)
if err then
vim.schedule(function()
vim.notify('error ' .. tostring(err) .. vim.inspect(chunk or ''), vim.log.levels.WARN)
util.error('error ' .. tostring(err) .. vim.inspect(chunk or ''), vim.log.levels.WARN)
end)
end
@ -99,7 +99,14 @@ local run = function(cmd, opts, uvopts)
if uvopts.cwd == '%:h' then
uvopts.cwd = vim.fn.expand(opts.cwd)
end
else
if vim.fn.expand('%:t'):find('go.mod') or vim.fn.expand('%:t'):find('go.work') then
opts.cwd = vim.fn.expand('%:p:h')
end
end
output_buf = ''
output_stderr = ''
handle, _ = uv.spawn(
cmd,
{ stdio = { stdin, stdout, stderr }, cwd = uvopts.cwd, args = job_options.args },
@ -121,31 +128,31 @@ local run = function(cmd, opts, uvopts)
vim.notify(output_stderr)
end)
end
if opts and opts.on_exit then
-- if on_exit hook is on the hook output is what we want to show in loc
-- this avoid show samething in both on_exit and loc
output_buf = opts.on_exit(code, signal, output_buf)
if not output_buf then
return
end
end
if code ~= 0 then
log('failed to run', code, output_buf)
output_buf = output_buf or ''
vim.schedule(function()
vim.notify(
cmd_str .. ' failed exit code ' .. tostring(code) .. output_buf,
vim.log.levels.WARN
)
util.error( cmd_str .. ' failed exit code ' .. tostring(code or 0) .. (output_buf or ''))
end)
end
local combine_output = ''
if output_buf ~= '' or output_stderr ~= '' then
local l = (output_buf or '') .. '\n' .. (output_stderr or '')
l = util.remove_ansi_escape(l)
local lines = vim.split(vim.trim(l), '\n')
lines = util.handle_job_data(lines)
-- some commands may output to stderr instead of stdout
combine_output = (output_buf or '') .. '\n' .. (output_stderr or '')
combine_output = util.remove_ansi_escape(combine_output)
combine_output = vim.trim(combine_output)
end
if opts and opts.on_exit then
local onexit_output = opts.on_exit(code, signal, combine_output)
if not onexit_output then
return
else
combine_output = onexit_output
end
end
if code ~= 0 or signal ~= 0 or output_stderr ~= '' then
local lines = util.handle_job_data(vim.split(combine_output, '\n'))
local locopts = {
title = vim.inspect(cmd),
lines = lines,
@ -153,11 +160,11 @@ local run = function(cmd, opts, uvopts)
if opts.efm then
locopts.efm = opts.efm
end
log(locopts, lines)
log('command finished: ', locopts, lines)
if #lines > 0 then
vim.schedule(function()
vim.fn.setloclist(0, {}, ' ', locopts)
util.quickfix('lopen')
util.info('run lopen to see output')
end)
end
end
@ -168,11 +175,11 @@ local run = function(cmd, opts, uvopts)
uv.read_start(stderr, function(err, data)
if err then
vim.notify('error ' .. tostring(err) .. tostring(data or ''), vim.log.levels.WARN)
util.error(tostring(err) .. tostring(data or ''))
end
if data ~= nil then
log(data)
output_stderr = output_stderr .. util.remove_ansi_escape(tostring(data))
log('stderr read handler', data)
output_stderr = output_stderr .. util.remove_ansi_escape(tostring(data))
end
_GO_NVIM_CFG.on_stderr(err, data)
end)

@ -1,5 +1,13 @@
local tpleval = require('go.template').template_eval
local util = require('go.utils')
local uv = vim.loop or vim.uv
local log = util.log
local go_examples = {
'appengine-hello',
'hello',
'helloserver',
}
local tpl_main = [[
package $(pkg)
@ -22,12 +30,95 @@ func Test$(funname)(t *testing.T) {
}
]]
local current_file = vim.fn.resolve(vim.fn.expand('<sfile>'))
local get_pkg = require('go.package').pkg_from_path
local function handleoutput(output)
-- Pattern to match the expected initialization format and extract the folder name
vim.validate({ output = { output, 'string' } })
local folder_name_pattern = 'initialized .- in (.+)%s*$'
local folder_path = output:match(folder_name_pattern)
if not folder_path then
util.warn('Unable to extract folder name from output or output format is unexpected.')
return
end
log('output: ', output, folder_path)
-- Check if the folder is created
local stat = uv.fs_stat(folder_path)
if stat and stat.type == 'directory' then
-- Change the working directory to the new folder
vim.cmd('cd ' .. vim.fn.fnameescape(folder_path))
local cwd = uv.cwd()
local go_files = vim.fn.globpath(uv.cwd(), '*.go', false, true)
local target_file
-- Prioritize 'hello.go' or 'main.go' if they exist
for _, file in ipairs(go_files) do
if file:match('hello%.go$') or file:match('main%.go$') then
target_file = file
break
end
end
target_file = target_file or go_files[1]
log('generated files', go_files, target_file)
if target_file then
-- Open the file in Neovim
vim.cmd('edit ' .. vim.fn.fnameescape(target_file))
else
util.warn('No .go files found in the directory: ' .. folder_path)
end
else
util.warn('Directory not created or not found: ' .. folder_path)
end
end
-- create go project from go/examples
-- use `gonew` cli tool: gonew srcmod[@version] [dstmod [dir]]
local gonew = function(args)
local urlbase = 'golang.org/x/example/'
local url = urlbase .. args[1]
local cmd = { 'gonew', url }
if args[2] then
table.insert(cmd, args[2])
if args[3] then
table.insert(cmd, args[3])
end
end
local runner = require('go.runner')
local utils = require('go.utils')
util.log(cmd)
local opts = {
on_exit = function(code, signal, data)
log(code, signal, data)
vim.validate({ data = { data, 'string' } }) -- it should be string separated by \n
if code ~= 0 then
util.warn('gonew failed with:' .. vim.inspect(data) .. 'signal ' .. tonumber(signal or 0))
return
end
vim.schedule(function()
utils.info(string.format('% success', vim.inspect(cmd)))
handleoutput(data)
end)
return data
end,
}
if args[3] then
opts.cwd = args[3]
end
runner.run(cmd, opts)
end
local function go_template_create(args)
local filename = args[1] or 'main.go'
local sep = util.sep()
if args[1] and vim.tbl_contains(go_examples, args[1]) then
gonew(args)
return
end
local package_name = get_pkg()
if vim.fn.empty(package_name) == 1 or vim.fn.empty(package_name[1]) == 1 then
package_name = 'main'
@ -61,4 +152,4 @@ local function go_template_create(args)
vim.api.nvim_buf_set_lines(0, 0, -1, true, lines)
end
return { new = go_template_create }
return { new = go_template_create, complete = go_examples }

@ -1,30 +1,29 @@
local runner = require("go.runner")
local utils = require("go.utils")
local runner = require('go.runner')
local utils = require('go.utils')
local M = {}
-- args: tidy or vendor
function M.run(...)
local args = { ... }
local cmd = { "go", "work" }
local cmd = { 'go', 'work' }
cmd = vim.list_extend(cmd, args)
utils.log(cmd)
local opts = {
on_exit = function(code, signal, data)
if code ~= 0 or signal ~= 0 then
utils.warn('impl failed' .. vim.inspect(data))
utils.warn('go work failed' .. vim.inspect(data))
return
end
data = vim.split(data, '\n')
data = utils.handle_job_data(data)
if not data then
return
if data then
vim.schedule(function()
utils.info('gowork success')
end)
end
vim.schedule(function()
utils.info('gowork success')
end)
end,
}
if vim.fn.expand('%:t'):find('go.mod') or vim.fn.expand('%:t'):find('go.work') then
}
if vim.fn.expand('%:t'):find('go.mod') or vim.fn.expand('%:t'):find('go.work') then
opts.cwd = vim.fn.expand('%:p:h')
end
runner.run(cmd, opts)

Loading…
Cancel
Save