First commit for luasnip
Most of the snip code is from this repo shark
and TJ's neovim setup config_manager
and ziontee113

* add luasnip for go

* move command out to a dedicated function

* update ts node spec format

* bugfix alternate file

* Bring in more snippets

* updates for mockery 2.11

* snips for http handler and more

* update doc

* bench test
pull/169/head
rayx 2 years ago committed by GitHub
parent bc25de4d85
commit 104b832ee4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -29,6 +29,8 @@ The plugin covers most features required for a gopher.
- GoCheat get go cheatsheet from [cheat.sh](https://cheat.sh/).
- Smart build tag detection when debug/run tests (e.g. `//go:build integration`)
- Generate mocks with mockgen
- luasnip: you might use friendly-snippets already, you still need to try pure lua snippets with go.nvim out,
checkout [LuaSnip Tutorial](https://www.youtube.com/watch?v=ub0REXjhpmk) and [TJ's Introduction to LuaSnip](https://www.youtube.com/watch?v=Dn800rlPIho)
## Installation
@ -607,6 +609,8 @@ require('go').setup({
-- float term recommand if you use richgo/ginkgo with terminal color
test_efm = false, -- errorfomat for quickfix, default mix mode, set to true will be efm only
luasnip = false, -- enable included luasnip snippets. you can also disable while add lua/snips folder to luasnip load
-- Do not enable this if you already added the path, that will duplicate the entries
})
```

@ -363,6 +363,7 @@ You can setup go.nvim with following options:
test_runner = "go", -- one of {`go`, `richgo`, `dlv`, `ginkgo`}
verbose_tests = true, -- set to add verbose flag to tests
run_in_floaterm = false, -- set to true to run in float window.
luasnip = false, -- set true to enable included luasnip
}
vim:tw=78:ts=8:sts=8:sw=8:ft=help:norl:expandtab

@ -1,7 +1,6 @@
-- some of commands extracted from gopher.vim
local go = {}
local vfn = vim.fn
local create_cmd = vim.api.nvim_create_user_command
-- Keep this in sync with README.md
-- Keep this in sync with doc/go.txt
@ -67,22 +66,12 @@ _GO_NVIM_CFG = {
run_in_floaterm = false, -- set to true to run in float window.
test_efm = false, -- errorfomat for quickfix, default mix mode, set to true will be efm only
luasnip = false, -- enable included luasnip
username = "",
useremail = "",
disable_per_project_cfg = false, -- set to true to disable load script from .gonvim/init.lua
}
local dap_config = function()
vim.cmd([[command! BreakCondition lua require"dap".set_breakpoint(vfn.input("Breakpoint condition: "))]])
vim.cmd([[command! ReplRun lua require"dap".repl.run_last()]])
vim.cmd([[command! ReplToggle lua require"dap".repl.toggle()]])
vim.cmd([[command! ReplOpen lua require"dap".repl.open(), 'split']])
vim.cmd([[command! DapRerun lua require'dap'.disconnect();require'dap'.close();require'dap'.run_last()]])
vim.cmd([[command! DapStop lua require'go.dap'.stop()]])
end
-- TODO: nvim_{add,del}_user_command https://github.com/neovim/neovim/pull/16752
function go.setup(cfg)
@ -92,164 +81,7 @@ function go.setup(cfg)
end
_GO_NVIM_CFG = vim.tbl_extend("force", _GO_NVIM_CFG, cfg)
vim.cmd([[autocmd FileType go setlocal omnifunc=v:lua.vim.lsp.omnifunc]])
vim.cmd([[command! GoMake silent lua require'go.asyncmake'.make()]])
vim.cmd([[command! -nargs=* GoFmt lua require("go.format").gofmt({<f-args>})]])
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.doc_complete GoImport lua require("go.format").goimport(<f-args>)]]
)
vim.cmd([[command! -nargs=* GoGet lua require'go.goget'.run({<f-args>})]])
local gobin = _GO_NVIM_CFG.go
local cmd = string.format([[command! GoGenerate :setl makeprg=%s\ generate | :GoMake]], gobin)
vim.cmd(cmd)
cmd = string.format(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoBuild :setl makeprg=%s\ build | lua require'go.asyncmake'.make(<f-args>)]],
gobin
)
vim.cmd(cmd)
cmd = string.format(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoVet :setl makeprg=%s\ vet | lua require'go.asyncmake'.make(<f-args>)]],
gobin
)
vim.cmd(cmd)
cmd = string.format(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoRun :setl makeprg=%s\ run | lua require'go.asyncmake'.make(<f-args>)]],
gobin
)
vim.cmd(cmd)
vim.cmd([[command! -nargs=* GoStop lua require("go.asyncmake").stopjob(<f-args>)]])
-- if you want to output to quickfix
-- example to running test in split buffer
-- vim.cmd(
-- [[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoTest :setl makeprg=go\ test\ -v\ | lua require'go.runner'.make(<f-args>)]])
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoTest lua require('go.gotest').test(<f-args>)]]
)
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoCoverage lua require'go.coverage'.run(<f-args>)]]
)
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoPkgOutline lua require'go.package'.outline(<f-args>)]]
)
-- vim.cmd([[command! GoTestCompile :setl makeprg=go\ build | :GoMake]])
--print-issued-lines=false
vim.cmd(
[[command! GoLint :setl makeprg=golangci-lint\ run\ --print-issued-lines=false\ --exclude-use-default=false | :GoMake]]
)
vim.cmd([[command! -nargs=* GoProject lua require('go.project').setup(<f-args>)]])
vim.cmd([[command! -nargs=* GoCheat lua require('go.chtsh').run(<f-args>)]])
-- e.g. GoTestFunc unit
vim.cmd([[command! -nargs=* GoTestFunc lua require('go.gotest').test_func(<f-args>)]])
-- e.g. GoTestFile unit
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoTestFile lua require('go.gotest').test_file(<f-args>)]]
)
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoTestPkg lua require('go.gotest').test_package(<f-args>)]]
)
vim.cmd([[command! -nargs=* GoAddTest lua require("go.gotests").fun_test(<f-args>)]])
vim.cmd([[command! -nargs=* GoAddExpTest lua require("go.gotests").exported_test(<f-args>)]])
vim.cmd([[command! -nargs=* GoAddAllTest lua require("go.gotests").all_test(<f-args>)]])
vim.cmd([[command! -nargs=* GoModVendor lua require("go.mod").run('vendor')]])
vim.cmd([[command! -nargs=* GoModInit lua require"go.mod".run('init')]])
vim.cmd([[command! -nargs=* GoEnv lua require"go.env".load_env(<f-args>)]])
vim.cmd([[command! GoCodeLenAct lua require("go.codelens").run_action()]])
vim.cmd([[command! GoCodeAction lua require("go.codeaction").run_action()]])
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.modify_tags_complete GoModifyTag lua require("go.tags").modify(<f-args>)]]
)
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.add_tags_complete GoAddTag lua require("go.tags").add(<f-args>)]]
)
vim.cmd([[command! -nargs=* GoRmTag lua require("go.tags").rm(<f-args>)]])
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.impl_complete GoImpl lua require("go.impl").run(<f-args>)]]
)
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.doc_complete GoDoc lua require'go.godoc'.run('doc', {<f-args>})]]
)
vim.cmd(
[[command! -nargs=+ -complete=custom,v:lua.package.loaded.go.tools_complete GoInstallBinary lua require'go.install'.install(<f-args>)]]
)
vim.cmd(
[[command! -nargs=+ -complete=custom,v:lua.package.loaded.go.tools_complete GoUpdateBinary lua require'go.install'.update(<f-args>)]]
)
vim.cmd([[command! GoInstallBinaries lua require'go.install'.install_all()]])
vim.cmd([[command! GoUpdateBinaries lua require'go.install'.update_all()]])
vim.cmd([[command! GoClearTag lua require("go.tags").clear()]])
vim.cmd([[command! GoCmt lua require("go.comment").gen()]])
vim.cmd([[command! GoRename lua require("go.rename").lsprename()]])
vim.cmd([[command! GoIfErr lua require("go.iferr").run()]])
vim.cmd([[command! GoFillStruct lua require("go.reftool").fillstruct()]])
vim.cmd([[command! GoFillSwitch lua require("go.reftool").fillswitch()]])
vim.cmd([[command! GoFixPlurals lua require("go.fixplurals").fixplurals()]])
vim.cmd([[command! -bang GoAlt lua require"go.alternate".switch("<bang>"=="!", '')]])
vim.cmd([[command! -bang GoAltV lua require"go.alternate".switch("<bang>"=="!", 'vsplit')]])
vim.cmd([[command! -bang GoAltS lua require"go.alternate".switch("<bang>"=="!", 'split')]])
vim.cmd("au FileType go au QuickFixCmdPost [^l]* nested cwindow")
vim.cmd("au FileType go au QuickFixCmdPost l* nested lwindow")
vim.cmd([[command! -bang GoModTidy lua require"go.gopls".tidy()]])
vim.cmd([[command! -bang GoListImports lua print(vim.inspect(require"go.gopls".list_imports()))]])
vim.cmd([[command! -bang GoCallstack lua require"go.guru".callstack(-1)]])
vim.cmd([[command! -bang GoChannel lua require"go.guru".channel_peers(-1)]])
if _GO_NVIM_CFG.dap_debug then
dap_config()
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.dbg_complete GoDebug lua require"go.dap".run(<f-args>)]]
)
vim.cmd([[command! GoCreateLaunch lua require"go.launch".config()]])
vim.cmd([[command! GoBreakSave lua require"go.dap".save_brks()]])
vim.cmd([[command! GoBreakLoad lua require"go.dap".load_brks()]])
vim.cmd([[command! GoDbgConfig lua require"go.launch".config()]])
vim.cmd([[command! GoBreakToggle lua require"go.dap".breakpt()]])
vim.cmd([[command! GoDbgKeys lua require"go.dap".debug_keys()]])
vim.cmd([[command! BreakCondition lua require"dap".set_breakpoint(vfn.input("Breakpoint condition: "))]])
vim.cmd([[command! ReplRun lua require"dap".repl.run_last()]])
vim.cmd([[command! ReplToggle lua require"dap".repl.toggle()]])
vim.cmd([[command! ReplOpen lua require"dap".repl.open(), 'split']])
vim.cmd([[command! DapRerun lua require'dap'.disconnect();require'dap'.close();require'dap'.run_last()]])
vim.cmd([[command! DapUiFloat lua require("dapui").float_element()]])
vim.cmd([[command! DapUiToggle lua require("dapui").toggle()]])
vim.cmd([[command! GoDbgStop lua require'go.dap'.stop(true)]])
vim.cmd([[command! GoDbgContinue lua require'dap'.continue()]])
create_cmd('GoMockGen',
require"go.mockgen".run,
{
nargs = "*",
-- bang = true,
complete = function(ArgLead, CmdLine, CursorPos)
-- return completion candidates as a list-like table
return { '-p', '-d', '-i', '-s'}
end,
})
end
require("go.commands").add_cmds()
require("go.project").load_project()
if _GO_NVIM_CFG.run_in_floaterm then
@ -275,13 +107,22 @@ function go.setup(cfg)
require("go.ts.textobjects").setup()
end
require("go.env").setup()
end
go.doc_complete = require("go.godoc").doc_complete
go.package_complete = require("go.package").complete
if _GO_NVIM_CFG.luasnip then
local ls = require("go.utils").load_plugin("LuaSnip", "luasnip")
if ls then
require("snips.go")
end
end
go.doc_complete = require("go.godoc").doc_complete
go.package_complete = require("go.package").complete
go.dbg_complete = require("go.complete").dbg_complete
go.tools_complete = require("go.complete").tools_complete
go.impl_complete = require("go.complete").impl_complete
go.modify_tags_complete = require("go.complete").modify_tags_complete
go.add_tags_complete = require("go.complete").add_tags_complete
end
go.set_test_runner = function(runner)
-- richgo, go test, richgo, dlv, ginkgo
@ -295,67 +136,4 @@ go.set_test_runner = function(runner)
vim.notify("runner not supported " .. runner, vim.lsp.log_levels.ERROR)
end
-- go.dbg_complete = function(arglead, cmdline, cursorpos)
go.dbg_complete = function(_, _, _)
-- richgo, go test, richgo, dlv, ginkgo
local testopts = { "--help", "--test", "--nearest", "--file", "--package", "--attach", "--stop", "--restart", "--breakpoint", "--tag" }
return table.concat(testopts, "\n")
end
go.tools_complete = function(_, _, _)
local gotools = require("go.install").gotools
table.sort(gotools)
return table.concat(gotools, "\n")
end
go.impl_complete = function(arglead, cmdline, cursorpos)
-- print(table.concat(require("go.impl").complete(arglead, cmdline, cursorpos), "\n"))
return table.concat(require("go.impl").complete(arglead, cmdline, cursorpos), "\n")
-- local testopts = { "test", "nearest", "file", "stop", "restart" }
-- return table.concat(testopts, "\n")
end
go.modify_tags_complete = function(_, _, _)
local opts = {
"-add-tags",
"-add-options",
"-remove-tags",
"-remove-options",
"-clear-tags",
"-clear-options",
}
return table.concat(opts, "\n")
end
-- how to deal complete https://github.com/vim-scripts/marvim/blob/c159856871aa18fa4f3249c6aa312c52f586d1ef/plugin/marvim.vim#L259
-- go.add_tags_complete = function(arglead, line, pos)
go.add_tags_complete = function(arglead, line, _)
-- print("lead: ",arglead, "L", line, "p" )
local transf = { "camelcase", "snakecase", "lispcase", "pascalcase", "titlecase", "keep" }
local ret = {}
if #vim.split(line, "%s+") >= 2 then
if vim.startswith("-transform", arglead) then
return "-transform"
end
table.foreach(transf, function(_, tag)
if vim.startswith(tag, arglead) then
ret[#ret + 1] = tag
end
end)
if #ret > 0 then
return table.concat(ret, "\n")
end
return table.concat(transf, "\n")
end
local opts = {
"json",
"json.yml",
"-transform",
}
return table.concat(opts, "\n")
end
return go

@ -1,16 +1,23 @@
local M = {}
function M.alternate()
function M.is_test_file()
local file = vim.fn.expand('%')
local alt_file = ""
if #file <= 1 then
vim.notify("no buffer name", vim.lsp.log_levels.ERROR)
return
end
local s = string.find(file, "_test%.go$")
local s2 = string.find(file, "%.go$")
if s ~= nil then
local is_test = string.find(file, "_test%.go$")
local is_source = string.find(file, "%.go$")
return file, (not is_test and is_source), is_test
end
function M.alternate()
local file, is_source, is_test = M.is_test_file()
local alt_file = file
if is_test then
alt_file = string.gsub(file, "_test.go", ".go")
elseif s2 ~= nil then
elseif is_source then
alt_file = vim.fn.expand('%:r') .. "_test.go"
else
vim.notify('not a go file', vim.lsp.log_levels.ERROR)

@ -0,0 +1,170 @@
local create_cmd = vim.api.nvim_create_user_command
local dap_config = function()
vim.cmd([[command! BreakCondition lua require"dap".set_breakpoint(vfn.input("Breakpoint condition: "))]])
vim.cmd([[command! ReplRun lua require"dap".repl.run_last()]])
vim.cmd([[command! ReplToggle lua require"dap".repl.toggle()]])
vim.cmd([[command! ReplOpen lua require"dap".repl.open(), 'split']])
vim.cmd([[command! DapRerun lua require'dap'.disconnect();require'dap'.close();require'dap'.run_last()]])
vim.cmd([[command! DapStop lua require'go.dap'.stop()]])
end
return {
add_cmds = function()
vim.cmd([[autocmd FileType go setlocal omnifunc=v:lua.vim.lsp.omnifunc]])
vim.cmd([[command! GoMake silent lua require'go.asyncmake'.make()]])
vim.cmd([[command! -nargs=* GoFmt lua require("go.format").gofmt({<f-args>})]])
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.doc_complete GoImport lua require("go.format").goimport(<f-args>)]]
)
vim.cmd([[command! -nargs=* GoGet lua require'go.goget'.run({<f-args>})]])
local gobin = _GO_NVIM_CFG.go
local cmd = string.format([[command! GoGenerate :setl makeprg=%s\ generate | :GoMake]], gobin)
vim.cmd(cmd)
cmd = string.format(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoBuild :setl makeprg=%s\ build | lua require'go.asyncmake'.make(<f-args>)]],
gobin
)
vim.cmd(cmd)
cmd = string.format(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoVet :setl makeprg=%s\ vet | lua require'go.asyncmake'.make(<f-args>)]],
gobin
)
vim.cmd(cmd)
cmd = string.format(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoRun :setl makeprg=%s\ run | lua require'go.asyncmake'.make(<f-args>)]],
gobin
)
vim.cmd(cmd)
vim.cmd([[command! -nargs=* GoStop lua require("go.asyncmake").stopjob(<f-args>)]])
-- if you want to output to quickfix
-- example to running test in split buffer
-- vim.cmd(
-- [[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoTest :setl makeprg=go\ test\ -v\ | lua require'go.runner'.make(<f-args>)]])
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoTest lua require('go.gotest').test(<f-args>)]]
)
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoCoverage lua require'go.coverage'.run(<f-args>)]]
)
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoPkgOutline lua require'go.package'.outline(<f-args>)]]
)
-- vim.cmd([[command! GoTestCompile :setl makeprg=go\ build | :GoMake]])
--print-issued-lines=false
vim.cmd(
[[command! GoLint :setl makeprg=golangci-lint\ run\ --print-issued-lines=false\ --exclude-use-default=false | :GoMake]]
)
vim.cmd([[command! -nargs=* GoProject lua require('go.project').setup(<f-args>)]])
vim.cmd([[command! -nargs=* GoCheat lua require('go.chtsh').run(<f-args>)]])
-- e.g. GoTestFunc unit
vim.cmd([[command! -nargs=* GoTestFunc lua require('go.gotest').test_func(<f-args>)]])
-- e.g. GoTestFile unit
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoTestFile lua require('go.gotest').test_file(<f-args>)]]
)
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.package_complete GoTestPkg lua require('go.gotest').test_package(<f-args>)]]
)
vim.cmd([[command! -nargs=* GoAddTest lua require("go.gotests").fun_test(<f-args>)]])
vim.cmd([[command! -nargs=* GoAddExpTest lua require("go.gotests").exported_test(<f-args>)]])
vim.cmd([[command! -nargs=* GoAddAllTest lua require("go.gotests").all_test(<f-args>)]])
vim.cmd([[command! -nargs=* GoModVendor lua require("go.mod").run('vendor')]])
vim.cmd([[command! -nargs=* GoModInit lua require"go.mod".run('init')]])
vim.cmd([[command! -nargs=* GoEnv lua require"go.env".load_env(<f-args>)]])
vim.cmd([[command! GoCodeLenAct lua require("go.codelens").run_action()]])
vim.cmd([[command! GoCodeAction lua require("go.codeaction").run_action()]])
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.modify_tags_complete GoModifyTag lua require("go.tags").modify(<f-args>)]]
)
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.add_tags_complete GoAddTag lua require("go.tags").add(<f-args>)]]
)
vim.cmd([[command! -nargs=* GoRmTag lua require("go.tags").rm(<f-args>)]])
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.impl_complete GoImpl lua require("go.impl").run(<f-args>)]]
)
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.doc_complete GoDoc lua require'go.godoc'.run('doc', {<f-args>})]]
)
vim.cmd(
[[command! -nargs=+ -complete=custom,v:lua.package.loaded.go.tools_complete GoInstallBinary lua require'go.install'.install(<f-args>)]]
)
vim.cmd(
[[command! -nargs=+ -complete=custom,v:lua.package.loaded.go.tools_complete GoUpdateBinary lua require'go.install'.update(<f-args>)]]
)
vim.cmd([[command! GoInstallBinaries lua require'go.install'.install_all()]])
vim.cmd([[command! GoUpdateBinaries lua require'go.install'.update_all()]])
vim.cmd([[command! GoClearTag lua require("go.tags").clear()]])
vim.cmd([[command! GoCmt lua require("go.comment").gen()]])
vim.cmd([[command! GoRename lua require("go.rename").lsprename()]])
vim.cmd([[command! GoIfErr lua require("go.iferr").run()]])
vim.cmd([[command! GoFillStruct lua require("go.reftool").fillstruct()]])
vim.cmd([[command! GoFillSwitch lua require("go.reftool").fillswitch()]])
vim.cmd([[command! GoFixPlurals lua require("go.fixplurals").fixplurals()]])
vim.cmd([[command! -bang GoAlt lua require"go.alternate".switch("<bang>"=="!", '')]])
vim.cmd([[command! -bang GoAltV lua require"go.alternate".switch("<bang>"=="!", 'vsplit')]])
vim.cmd([[command! -bang GoAltS lua require"go.alternate".switch("<bang>"=="!", 'split')]])
vim.cmd("au FileType go au QuickFixCmdPost [^l]* nested cwindow")
vim.cmd("au FileType go au QuickFixCmdPost l* nested lwindow")
vim.cmd([[command! -bang GoModTidy lua require"go.gopls".tidy()]])
vim.cmd([[command! -bang GoListImports lua print(vim.inspect(require"go.gopls".list_imports()))]])
vim.cmd([[command! -bang GoCallstack lua require"go.guru".callstack(-1)]])
vim.cmd([[command! -bang GoChannel lua require"go.guru".channel_peers(-1)]])
if _GO_NVIM_CFG.dap_debug then
dap_config()
vim.cmd(
[[command! -nargs=* -complete=custom,v:lua.package.loaded.go.dbg_complete GoDebug lua require"go.dap".run(<f-args>)]]
)
vim.cmd([[command! GoCreateLaunch lua require"go.launch".config()]])
vim.cmd([[command! GoBreakSave lua require"go.dap".save_brks()]])
vim.cmd([[command! GoBreakLoad lua require"go.dap".load_brks()]])
vim.cmd([[command! GoDbgConfig lua require"go.launch".config()]])
vim.cmd([[command! GoBreakToggle lua require"go.dap".breakpt()]])
vim.cmd([[command! GoDbgKeys lua require"go.dap".debug_keys()]])
vim.cmd([[command! BreakCondition lua require"dap".set_breakpoint(vfn.input("Breakpoint condition: "))]])
vim.cmd([[command! ReplRun lua require"dap".repl.run_last()]])
vim.cmd([[command! ReplToggle lua require"dap".repl.toggle()]])
vim.cmd([[command! ReplOpen lua require"dap".repl.open(), 'split']])
vim.cmd([[command! DapRerun lua require'dap'.disconnect();require'dap'.close();require'dap'.run_last()]])
vim.cmd([[command! DapUiFloat lua require("dapui").float_element()]])
vim.cmd([[command! DapUiToggle lua require("dapui").toggle()]])
vim.cmd([[command! GoDbgStop lua require'go.dap'.stop(true)]])
vim.cmd([[command! GoDbgContinue lua require'dap'.continue()]])
create_cmd("GoMockGen", require("go.mockgen").run, {
nargs = "*",
-- bang = true,
complete = function(ArgLead, CmdLine, CursorPos)
-- return completion candidates as a list-like table
return { "-p", "-d", "-i", "-s" }
end,
})
end
end,
}

@ -0,0 +1,77 @@
local go = {}
-- go.dbg_complete = function(arglead, cmdline, cursorpos)
go.dbg_complete = function(_, _, _)
-- richgo, go test, richgo, dlv, ginkgo
local testopts = {
"--help",
"--test",
"--nearest",
"--file",
"--package",
"--attach",
"--stop",
"--restart",
"--breakpoint",
"--tag",
}
return table.concat(testopts, "\n")
end
go.tools_complete = function(_, _, _)
local gotools = require("go.install").gotools
table.sort(gotools)
return table.concat(gotools, "\n")
end
go.impl_complete = function(arglead, cmdline, cursorpos)
-- print(table.concat(require("go.impl").complete(arglead, cmdline, cursorpos), "\n"))
return table.concat(require("go.impl").complete(arglead, cmdline, cursorpos), "\n")
-- local testopts = { "test", "nearest", "file", "stop", "restart" }
-- return table.concat(testopts, "\n")
end
go.modify_tags_complete = function(_, _, _)
local opts = {
"-add-tags",
"-add-options",
"-remove-tags",
"-remove-options",
"-clear-tags",
"-clear-options",
}
return table.concat(opts, "\n")
end
-- how to deal complete https://github.com/vim-scripts/marvim/blob/c159856871aa18fa4f3249c6aa312c52f586d1ef/plugin/marvim.vim#L259
-- go.add_tags_complete = function(arglead, line, pos)
go.add_tags_complete = function(arglead, line, _)
-- print("lead: ",arglead, "L", line, "p" )
local transf = { "camelcase", "snakecase", "lispcase", "pascalcase", "titlecase", "keep" }
local ret = {}
if #vim.split(line, "%s+") >= 2 then
if vim.startswith("-transform", arglead) then
return "-transform"
end
table.foreach(transf, function(_, tag)
if vim.startswith(tag, arglead) then
ret[#ret + 1] = tag
end
end)
if #ret > 0 then
return table.concat(ret, "\n")
end
return table.concat(transf, "\n")
end
local opts = {
"json",
"json.yml",
"-transform",
}
return table.concat(opts, "\n")
end
return go

@ -0,0 +1,243 @@
-- first version: from https://github.com/arsham/shark
local ls = require("luasnip")
local fmt = require("luasnip.extras.fmt").fmt
local ok, ts_utils = pcall(require, "nvim-treesitter.ts_utils")
if not ok then
require("packer").loader("nvim-treesitter")
ts_utils = require("nvim-treesitter.ts_utils")
end
local ts_locals = require("nvim-treesitter.locals")
local rep = require("luasnip.extras").rep
local ai = require("luasnip.nodes.absolute_indexer")
local M = {}
M.go_err_snippet = function(args, _, _, spec)
local err_name = args[1][1]
local index = spec and spec.index or nil
local msg = spec and spec[1] or ""
if spec and spec[2] then
err_name = err_name .. spec[2]
end
return ls.sn(index, {
ls.c(1, {
ls.sn(nil, fmt('errors.Wrap({}, "{}")', { ls.t(err_name), ls.i(1, msg) })),
ls.sn(nil, fmt('errors.Wrapf({}, "{}", {})', { ls.t(err_name), ls.i(1, msg), ls.i(2) })),
ls.sn(
nil,
fmt('internal.GrpcError({},\n\t\tcodes.{}, "{}", "{}", {})', {
ls.t(err_name),
ls.i(1, "Internal"),
ls.i(2, "Description"),
ls.i(3, "Field"),
ls.i(4, "fields"),
})
),
ls.t(err_name),
}),
})
end
---Transform makes a node from the given text.
local function transform(text, info)
local string_sn = function(template, default)
info.index = info.index + 1
return ls.sn(info.index, fmt(template, ls.i(1, default)))
end
local new_sn = function(default)
return string_sn("{}", default)
end
-- cutting the name if exists.
if text:find([[^[^\[]*string$]]) then
text = "string"
elseif text:find("^[^%[]*map%[[^%]]+") then
text = "map"
elseif text:find("%[%]") then
text = "slice"
elseif text:find([[ ?chan +[%a%d]+]]) then
return ls.t("nil")
end
-- separating the type from the name if exists.
local type = text:match([[^[%a%d]+ ([%a%d]+)$]])
if type then
text = type
end
if text == "int" or text == "int64" or text == "int32" then
return new_sn("0")
elseif text == "float32" or text == "float64" then
return new_sn("0")
elseif text == "error" then
if not info then
return ls.t("err")
end
info.index = info.index + 1
return M.go_err_snippet({ { info.err_name } }, nil, nil, { index = info.index })
elseif text == "bool" then
info.index = info.index + 1
return ls.c(info.index, { ls.i(1, "false"), ls.i(2, "true") })
elseif text == "string" then
return string_sn('"{}"', "")
elseif text == "map" or text == "slice" then
return ls.t("nil")
elseif string.find(text, "*", 1, true) then
return new_sn("nil")
end
text = text:match("[^ ]+$")
if text == "context.Context" then
text = "context.Background()"
else
-- when the type is concrete
text = text .. "{}"
end
return ls.t(text)
end
local get_node_text = vim.treesitter.query.get_node_text
local handlers = {
parameter_list = function(node, info)
local result = {}
local count = node:named_child_count()
for idx = 0, count - 1 do
table.insert(result, transform(get_node_text(node:named_child(idx), 0), info))
if idx ~= count - 1 then
table.insert(result, ls.t({ ", " }))
end
end
return result
end,
type_identifier = function(node, info)
local text = get_node_text(node, 0)
return { transform(text, info) }
end,
}
local query_is_set = false
local function set_query()
if query_is_set then
return
end
query_is_set = true
vim.treesitter.set_query(
"go",
"LuaSnip_Result",
[[
[
(method_declaration result: (_) @id)
(function_declaration result: (_) @id)
(func_literal result: (_) @id)
]
]]
)
end
local function return_value_nodes(info)
set_query()
local cursor_node = ts_utils.get_node_at_cursor()
local scope_tree = ts_locals.get_scope_tree(cursor_node, 0)
local function_node
for _, scope in ipairs(scope_tree) do
if
scope:type() == "function_declaration"
or scope:type() == "method_declaration"
or scope:type() == "func_literal"
then
function_node = scope
break
end
end
if not function_node then
return
end
local query = vim.treesitter.get_query("go", "LuaSnip_Result")
for _, node in query:iter_captures(function_node, 0) do
if handlers[node:type()] then
return handlers[node:type()](node, info)
end
end
return ls.t({ "" })
end
local is_in_function = require("go.ts.go").in_func()
---Transforms the given arguments into nodes wrapped in a snippet node.
M.make_return_nodes = function(args)
local info = { index = 0, err_name = args[1][1] }
return ls.sn(nil, return_value_nodes(info))
end
---Runs the command in shell.
-- @param command string
-- @return table
M.shell = require("go.utils").run_command
M.last_lua_module_section = function(args)
local text = args[1][1] or ""
local split = vim.split(text, ".", { plain = true })
local options = {}
for len = 0, #split - 1 do
local node = ls.t(table.concat(vim.list_slice(split, #split - len, #split), "_"))
table.insert(options, node)
end
return ls.sn(nil, {
ls.c(1, options),
})
end
function M.is_in_test_file()
local filename = vim.fn.expand("%:p")
return vim.endswith(filename, "_test.go")
end
function M.is_in_test_function()
return M.is_in_test_file() and is_in_function()
end
M.create_t_run = function(args)
return ls.sn(1, {
ls.c(1, {
ls.t({ "" }),
ls.sn(
nil,
fmt('\tt.Run("{}", {}{})\n{}', {
ls.i(1, "Case"),
ls.t(args[1]),
rep(1),
ls.d(2, M.create_t_run, ai[1]),
})
),
}),
})
end
M.mirror_t_run_funcs = function(args)
local strs = {}
for _, v in ipairs(args[1]) do
local name = v:match('^%s*t%.Run%s*%(%s*".*", (.*)%)')
if name then
local node = string.format("func %s(t *testing.T) {{\n\tt.Parallel()\n}}\n\n", name)
table.insert(strs, node)
end
end
local str = table.concat(strs, "")
if #str == 0 then
return ls.sn(1, ls.t(""))
end
return ls.sn(1, fmt(str, {}))
end
return M

@ -190,4 +190,24 @@ M.get_package_node_at_pos = function(row, col, bufnr)
end
end
function M.in_func()
local ok, ts_utils = pcall(require, "nvim-treesitter.ts_utils")
if not ok then
return false
end
local current_node = ts_utils.get_node_at_cursor()
if not current_node then
return false
end
local expr = current_node
while expr do
if expr:type() == "function_declaration" or expr:type() == "method_declaration" then
return true
end
expr = expr:parent()
end
return false
end
return M

@ -245,4 +245,20 @@ M.nodes_at_cursor = function(query, default, bufnr, row, col)
return nodes
end
function M.inside_function()
local current_node = ts_utils.get_node_at_cursor()
if not current_node then
return false
end
local expr = current_node
while expr do
if expr:type() == "function_declaration" or expr:type() == "method_declaration" then
return true
end
expr = expr:parent()
end
return false
end
return M

@ -368,7 +368,7 @@ function util.load_plugin(name, modulename)
has, plugin = pcall(require, modulename)
if not has then
util.info("plugin " .. name .. " not loaded ")
util.info("plugin " .. name .. " module " .. modulename .. " not loaded ")
return nil
end
return plugin
@ -675,4 +675,35 @@ function util.get_build_tags(buf)
return tags
end
end
-- a uuid
function util.uuid()
math.randomseed(tonumber(tostring(os.time()):reverse():sub(1, 9)))
local random = math.random
local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
return string.gsub(template, '[xy]', function (c)
local v = (c == 'x') and random(0, 0xf) or random(8, 0xb)
return string.format('%x', v)
end)
end
function util.lorem()
return "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum"
end
function util.random_words(len)
local str = util.lorem()
local words = fn.split(str, " ")
str = ""
for i = 1, len do
str = str .. " " .. words[math.random(#words)]
end
return str
end
function util.run_command(cmd, ...)
local result = fn.systemlist(cmd, ...)
return result
end
return util

@ -0,0 +1,423 @@
-- the snip leverage lots of setup/snip from https://github.com/arsham/shark/blob/master/lua/settings/luasnip/go.lua
-- LuaSnip by L3MON4D3
-- Also thanks TJ and ziontee113 for the great luasnip tutorial
local ls = require("luasnip")
local fmt = require("luasnip.extras.fmt").fmt
local fmta = require("luasnip.extras.fmt").fmta
local rep = require("luasnip.extras").rep
local ai = require("luasnip.nodes.absolute_indexer")
local partial = require("luasnip.extras").partial
local snips = require("go.snips")
local log = require("go.utils").log
local in_test_fn = {
show_condition = snips.in_test_function,
condition = snips.in_test_function,
}
local in_test_file = {
show_condition = snips.in_test_file_fn,
condition = snips.in_test_file_fn,
}
local in_fn = {
show_condition = snips.in_function,
condition = snips.in_function,
}
local not_in_fn = {
show_condition = snips.in_func,
condition = snips.in_func,
}
-- stylua: ignore start
local snippets = {
-- Main
ls.s(
{ trig = "main", name = "Main", dscr = "Create a main function" },
fmta("func main() {\n\t<>\n}", ls.i(0)),
not_in_fn
),
-- If call error
ls.s(
{ trig = "ifc", name = "if call", dscr = "Call a function and check the error" },
fmt(
[[
{val}, {err1} := {func}({args})
if {err2} != nil {{
return {err3}
}}
{finally}
]], {
val = ls.i(1, { "val" }),
err1 = ls.i(2, { "err" }),
func = ls.i(3, { "func" }),
args = ls.i(4),
err2 = rep(2),
err3 = ls.d(5, snips.make_return_nodes, { 2 }),
finally = ls.i(0),
}),
snips.in_fn
),
-- if err:=call(); err != nil { return err }
ls.s(
{ trig = "ifce", name = "if call err inline", dscr = "Call a function and check the error inline" },
fmt(
[[
if {err1} := {func}({args}); {err2} != nil {{
return {err3}
}}
{finally}
]], {
err1 = ls.i(1, { "err" }),
func = ls.i(2, { "func" }),
args = ls.i(3, { "args" }),
err2 = rep(1),
err3 = ls.d(4, snips.make_return_nodes, { 1 }),
finally = ls.i(0),
}),
snips.in_fn
),
-- Function
ls.s(
{ trig = "fn", name = "Function", dscr = "Create a function or a method" },
fmt(
[[
// {name1} {desc}
func {rec}{name2}({args}) {ret} {{
{finally}
}}
]], {
name1 = rep(2),
desc = ls.i(5, "description"),
rec = ls.c(1, {
ls.t(""),
ls.sn(nil, fmt("({} {}) ", {
ls.i(1, "r"),
ls.i(2, "receiver"),
})),
}),
name2 = ls.i(2, "Name"),
args = ls.i(3),
ret = ls.c(4, {
ls.i(1, "error"),
ls.sn(nil, fmt("({}, {}) ", {
ls.i(1, "ret"),
ls.i(2, "error"),
})),
}),
finally = ls.i(0),
}),
not_in_fn
),
-- If error
ls.s(
{ trig = "ife", name = "If error, choose me!", dscr = "If error, return wrapped with dynamic node" },
fmt("if {} != nil {{\n\treturn {}\n}}\n{}", {
ls.i(1, "err"),
ls.d(2, snips.make_return_nodes, { 1 }, { user_args = { { "a1", "a2" } } }),
ls.i(0),
}),
in_fn
),
-- errors.Wrap
ls.s(
{ trig = "erw", dscr = "errors.Wrap" },
fmt([[errors.Wrap({}, "{}")]], {
ls.i(1, "err"),
ls.i(2, "failed to"),
})
),
-- errors.Wrapf
ls.s(
{ trig = "erwf", dscr = "errors.Wrapf" },
fmt([[errors.Wrapf({}, "{}", {})]], {
ls.i(1, "err"),
ls.i(2, "failed %v"),
ls.i(3, "args"),
})
),
-- for select
ls.s(
{ trig = "fsel", dscr = "for select" },
fmt([[
for {{
select {{
case {} <- {}:
{}
default:
{}
}}
}}
]], {
ls.i(1, {ls.i(1, "ch"), ls.i(2, "ch := ")}),
ls.i(2, "ch"),
ls.i(3, "break"),
ls.i(0, ""),
})
),
-- type switch
ls.s(
{ trig = "tysw", dscr = "type switch" },
fmt([[
switch {} := {}.(type) {{
case {}:
{}
default:
{}
}}
]], {
ls.i(1, "v"),
ls.i(2, "i"),
ls.i(3, "int"),
ls.i(4, 'fmt.Println("int")'),
ls.i(0, ""),
})
),
-- fmt.Sprintf
ls.s(
{ trig = "spn", dscr = "fmt.Sprintf" },
fmt([[fmt.Sprintf("{}%{}", {})]], {
ls.i(1, "msg "),
ls.i(2, "+v"),
ls.i(2, "arg"),
})
),
-- build tags
ls.s(
{ trig = "//tag", dscr = "// +build tags" },
fmt([[// +build:{}{}]], {
ls.i(1, "integration"),
ls.i(2, ",unit"),
})
),
-- Nolint
ls.s(
{ trig = "nolt", dscr = "ignore linter" },
fmt([[// nolint:{}{}]], {
ls.i(1, "funlen"),
ls.i(2, ",cyclop"),
})
),
-- defer recover
ls.s(
{ trig = "dfr", dscr = "defer recover" },
fmt(
[[
defer func() {{
if err := recover(); err != nil {{
{}
}}
}}()]], {
ls.i(1, ""),
})
),
-- Allocate Slices and Maps
ls.s(
{ trig = "mk", name = "Make", dscr = "Allocate map or slice" },
fmt("{} {}= make({})\n{}", {
ls.i(1, "name"),
ls.i(2),
ls.c(3, {
fmt("[]{}, {}", { ls.r(1, "type"), ls.i(2, "len") }),
fmt("[]{}, 0, {}", { ls.r(1, "type"), ls.i(2, "len") }),
fmt("map[{}]{}, {}", { ls.r(1, "type"), ls.i(2, "values"), ls.i(3, "len") }),
}, {
stored = { -- FIXME: the default value is not set.
type = ls.i(1, "type"),
},
}),
ls.i(0),
}),
in_fn
),
-- Test Cases
ls.s(
{ trig = "tcs", dscr = "create test cases for testing" },
fmta(
[[
tcs := map[string]struct {
<>
} {
// Test cases here
}
for name, tc := range tcs {
tc := tc
t.Run(name, func(t *testing.T) {
<>
})
}
]],
{ ls.i(1), ls.i(2) }
),
in_test_fn
),
-- gRPC Error
ls.s(
{ trig = "gerr", dscr = "Return an instrumented gRPC error" },
fmt('internal.GrpcError({},\n\tcodes.{}, "{}", "{}", {})', {
ls.i(1, "err"),
ls.i(2, "Internal"),
ls.i(3, "Description"),
ls.i(4, "Field"),
ls.i(5, "fields"),
}),
in_fn
),
ls.s(
{ trig = "hf", name = "http.HandlerFunc", dscr = "http handler" },
fmt( [[
func {}(w http.ResponseWriter, r *http.Request) {{
{}
}}
]], {
ls.i(1, "handler"),
ls.i(2, [[fmt.Fprintf(w, "hello world")"]]),
})
),
-- deep equal
ls.s(
{ trig = "deq", name = "reflect Deep equal", dscr = "Compare with deep equal and print error" },
fmt([[
if !reflect.DeepEqual({}, {}) {{
_, file, line, _ := runtime.Caller(0)
fmt.Printf("%s:%d:\n\n\texp: %#v\n\n\tgot: %#v\n\n", filepath.Base(file), line, {}, {})
t.FailNow()
}}]] , {
ls.i(1, "expected"),
ls.i(2, "got"),
rep(1),
rep(2),
}),
in_test_fn
),
-- Create Mocks
ls.s(
{ trig = "mock", name = "Mocks create", dscr = "Create a mock with NewFactory" },
fmt("{} := &mocks.{}({})", {
ls.i(1, "m"),
ls.i(2, "NewFactory"),
ls.i(3, "t"),
}),
in_test_fn
),
-- Http request with defer close
ls.s(
{ trig = 'hreq', name = "http request with defer close", dscr = "create a http request with defer body close" },
fmt([[
{}, {} := http.{}("http://{}:" + {} + "/{}")
if {} != nil {{
log.Fatalln({})
}}
_ = {}.Body.Close()
]], {
ls.i(1, "resp"),
ls.i(2, "err"),
ls.c(3, {ls.i(1, "Get"), ls.i(2, "Post"), ls.i(3, "Patch")}),
ls.i(4, "localhost"),
ls.i(5, [["8080"]]),
ls.i(6, "path"),
rep(2),
rep(2),
rep(1),
}
),
in_test_fn
),
-- Go CMP
ls.s(
{ trig = "gocmp", dscr = "Create an if block comparing with cmp.Diff" },
fmt(
[[
if diff := cmp.Diff({}, {}); diff != "" {{
t.Errorf("(-want +got):\\n%s", diff)
}}
]], {
ls.i(1, "want"),
ls.i(2, "got"),
}),
in_test_fn
),
-- Require NoError
ls.s(
{ trig = "noerr", name = "Require No Error", dscr = "Add a require.NoError call" },
ls.c(1, {
ls.sn(nil, fmt("require.NoError(t, {})", { ls.i(1, "err") })),
ls.sn(nil, fmt('require.NoError(t, {}, "{}")', { ls.i(1, "err"), ls.i(2) })),
ls.sn(nil, fmt('require.NoErrorf(t, {}, "{}", {})', { ls.i(1, "err"), ls.i(2), ls.i(3) })),
}),
in_test_fn
),
-- Assert equal
ls.s(
{ trig = "aeq", name = "Assert Equal", dscr = "Add assert.Equal" },
ls.c(1, {
ls.sn(nil, fmt('assert.Equal(t, {}, {})', { ls.i(1, "got"), ls.i(2, "want") })),
ls.sn(nil, fmt('assert.Equalf(t, {}, {}, "{}", {})', { ls.i(1, "got"), ls.i(2, "want"), ls.i(3, "got %v not equal to want"), ls.i(4, "got") })),
}),
in_test_fn
),
-- Subtests
ls.s(
{ trig = "test", name = "Test & Subtest", dscr = "Create subtests and their function stubs" },
fmta("func <>(t *testing.T) {\n<>\n}\n\n <>", {
ls.i(1),
ls.d(2, snips.create_t_run, ai({ 1 })),
ls.d(3, snips.mirror_t_run_funcs, ai({ 2 })),
}),
in_test_file
),
-- bench test
ls.s(
{ trig = "bench", name = "bench test cases ", dscr = "Create benchmark test" },
fmt([[
func Benchmark{}(b *testing.B) {{
for i := 0; i < b.N; i++ {{
{}({})
}}
}}]]
, {
ls.i(1, "MethodName"),
rep(1),
ls.i(2, "args")
}),
in_test_file
),
-- Stringer
ls.s(
{ trig = "strigner", name = "Stringer", dscr = "Create a stringer go:generate" },
fmt("//go:generate stringer -type={} -output={}_string.go", {
ls.i(1, "Type"),
partial(vim.fn.expand, "%:t:r"),
})
),
}
log('creating snippet')
ls.add_snippets("go", snippets)
-- stylua: ignore end

@ -1,195 +1,174 @@
local eq = assert.are.same
local input = {
"package a", "", "type x struct {", "\tFoo int", "\tbar int", "\ty struct {", "\t\tFoo int",
"\t\tbar int", "\t}", "}", "type z struct{}"
"package a",
"",
"type x struct {",
"\tFoo int",
"\tbar int",
"\ty struct {",
"\t\tFoo int",
"\t\tbar int",
"\t}",
"}",
"type z struct{}",
}
local default = {
["function"] = "func",
["method"] = "func",
["struct"] = "struct",
["interface"] = "interface"
["interface"] = "interface",
}
local output_inner = {
"package a", "", "type x struct {", '\tFoo int `xx:"foo"`', '\tbar int `xx:"bar"`', "y struct {",
'\t\tFoo int `xx:"foo"`', '\t\tbar int `xx:"bar"`', "}", ""
"package a",
"",
"type x struct {",
'\tFoo int `xx:"foo"`',
'\tbar int `xx:"bar"`',
"y struct {",
'\t\tFoo int `xx:"foo"`',
'\t\tbar int `xx:"bar"`',
"}",
"",
}
describe(
"should get nodes ",
function()
vim.cmd([[silent exe 'e tags.go']])
vim.fn.append(0, input)
vim.cmd([[w]])
local bufn = vim.fn.bufnr("")
status = require("plenary.reload").reload_module("go.nvim")
status = require("plenary.reload").reload_module("nvim-treesitter/nvim-treesitter")
_GO_NVIM_CFG.verbose = true
local cur_dir = vim.fn.expand("%:p:h")
local nodes = require("go.ts.nodes")
it(
"get all nodes should get struct x",
function()
vim.fn.setpos(".", {bufn, 4, 1, 0})
local query = require("go.ts.go").query_struct_block
local ns = nodes.get_all_nodes(query, "go", default, bufn)
eq("x", ns[1].name)
end
)
it(
"it should get struct y",
function()
vim.fn.setpos(".", {bufn, 8, 1, 0})
local query = require("go.ts.go").query_struct_block .. require("go.ts.go").query_em_struct_block
-- local query = require('go.ts.go').query_em_struct
local ns = nodes.get_all_nodes(query, "go", default, bufn)
eq("y", ns[2].name)
end
)
it(
"node at cursor should get struct x",
function()
vim.fn.setpos(".", {bufn, 4, 1, 0})
local query = require("go.ts.go").query_struct_block
local ns = nodes.nodes_at_cursor(query, default, bufn)
eq("x", ns[1].name)
end
)
it(
"it should get struct y",
function()
vim.fn.setpos(".", {bufn, 8, 1, 0})
local query = require("go.ts.go").query_struct_block .. require("go.ts.go").query_em_struct_block
-- local query = require('go.ts.go').query_em_struct
local ns = nodes.nodes_at_cursor(query, default, bufn)
eq("y", ns[#ns].name)
end
)
it(
"struct at pos should get struct y",
function()
vim.fn.setpos(".", {bufn, 8, 4, 0})
local ns = require("go.ts.go").get_struct_node_at_pos(8, 1)
print(vim.inspect(ns))
eq("y", ns.name)
end
)
it(
"should get function name",
function()
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/ts/playlist.go" -- %:p:h ? %:p
print("test:" .. path)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", {bufn, 21, 5, 0})
local ns = require("go.ts.go").get_func_method_node_at_pos(21, 5)
print(vim.inspect(ns))
eq("createPlaylist", ns.name)
end
)
it(
"should get method (with par list) name",
function()
local path = cur_dir .. "/lua/tests/fixtures/ts/playlist.go" -- %:p:h ? %:p
print("test:" .. path)
local cmd = " silent exe 'e " .. path .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", {bufn, 33, 21, 0})
local ns = require("go.ts.go").get_func_method_node_at_pos(33, 21)
print(vim.inspect(ns))
eq("addSong", ns.name)
end
)
it(
"should get method (no par) name",
function()
local path = cur_dir .. "/lua/tests/fixtures/ts/playlist.go" -- %:p:h ? %:p
print("test:" .. path)
local cmd = " silent exe 'e " .. path .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", {bufn, 48, 3, 0})
local ns = require("go.ts.go").get_func_method_node_at_pos(48, 3)
print(vim.inspect(ns))
eq("showAllSongs", ns.name)
end
)
it(
"should get interface name",
function()
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/ts/interfaces.go" -- %:p:h ? %:p
print("test:" .. path)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", {bufn, 11, 6, 0})
local ns = require("go.ts.go").get_interface_node_at_pos(11, 6)
print(vim.inspect(ns))
eq("Geometry", ns.name)
end
)
it(
"should get interface method name",
function()
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/ts/interfaces.go" -- %:p:h ? %:p
print("test:" .. path)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", {bufn, 11, 5, 0})
local ns = require("go.ts.go").get_interface_method_node_at_pos(11, 5)
print(vim.inspect(ns))
eq("Area", ns.name)
end
)
it(
"should get package name",
function()
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/ts/interfaces.go" -- %:p:h ? %:p
print("test:" .. path)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", {bufn, 3, 5, 0})
local ns = require("go.ts.go").get_package_node_at_pos(3, 5)
print(vim.inspect(ns))
eq("main", ns.name)
end
)
it(
"should get package name",
function()
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/ts/interfaces.go" -- %:p:h ? %:p
print("test:" .. path)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", {bufn, 3, 1, 0})
local ns = require("go.ts.go").get_package_node_at_pos(3, 1)
print(vim.inspect(ns))
eq("main", ns.name)
end
)
end
)
describe("should get nodes ", function()
vim.cmd([[silent exe 'e tags.go']])
vim.fn.append(0, input)
vim.cmd([[w]])
local bufn = vim.fn.bufnr("")
status = require("plenary.reload").reload_module("go.nvim")
status = require("plenary.reload").reload_module("nvim-treesitter/nvim-treesitter")
_GO_NVIM_CFG.verbose = true
local cur_dir = vim.fn.expand("%:p:h")
local nodes = require("go.ts.nodes")
it("get all nodes should get struct x", function()
vim.fn.setpos(".", { bufn, 4, 1, 0 })
local query = require("go.ts.go").query_struct_block
local ns = nodes.get_all_nodes(query, "go", default, bufn)
eq("x", ns[1].name)
end)
it("it should get struct y", function()
vim.fn.setpos(".", { bufn, 8, 1, 0 })
local query = require("go.ts.go").query_struct_block .. require("go.ts.go").query_em_struct_block
-- local query = require('go.ts.go').query_em_struct
local ns = nodes.get_all_nodes(query, "go", default, bufn)
eq("y", ns[2].name)
end)
it("node at cursor should get struct x", function()
vim.fn.setpos(".", { bufn, 4, 1, 0 })
local query = require("go.ts.go").query_struct_block
local ns = nodes.nodes_at_cursor(query, default, bufn)
print(vim.inspect(ns))
eq("x", ns[1].name)
end)
it("it should get struct y", function()
vim.fn.setpos(".", { bufn, 8, 1, 0 })
local query = require("go.ts.go").query_struct_block .. require("go.ts.go").query_em_struct_block
-- local query = require('go.ts.go').query_em_struct
local ns = nodes.nodes_at_cursor(query, default, bufn)
eq("y", ns[#ns].name)
end)
it("struct at pos should get struct y", function()
vim.fn.setpos(".", { bufn, 8, 4, 0 })
local ns = require("go.ts.go").get_struct_node_at_pos(8, 1)
print(vim.inspect(ns))
eq("y", ns.name)
end)
it("should get function name", function()
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/ts/playlist.go" -- %:p:h ? %:p
print("test:" .. path)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", { bufn, 21, 5, 0 })
local ns = require("go.ts.go").get_func_method_node_at_pos(21, 5)
print(vim.inspect(ns))
eq("createPlaylist", ns.name)
end)
it("should get method (with par list) name", function()
local path = cur_dir .. "/lua/tests/fixtures/ts/playlist.go" -- %:p:h ? %:p
print("test:" .. path)
local cmd = " silent exe 'e " .. path .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", { bufn, 33, 21, 0 })
local ns = require("go.ts.go").get_func_method_node_at_pos(33, 21)
print(vim.inspect(ns))
eq("addSong", ns.name)
end)
it("should get method (no par) name", function()
local path = cur_dir .. "/lua/tests/fixtures/ts/playlist.go" -- %:p:h ? %:p
print("test:" .. path)
local cmd = " silent exe 'e " .. path .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", { bufn, 48, 3, 0 })
local ns = require("go.ts.go").get_func_method_node_at_pos(48, 3)
print(vim.inspect(ns))
eq("showAllSongs", ns.name)
end)
it("should get interface name", function()
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/ts/interfaces.go" -- %:p:h ? %:p
print("test:" .. path)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", { bufn, 11, 6, 0 })
local ns = require("go.ts.go").get_interface_node_at_pos(11, 6)
print(vim.inspect(ns))
eq("Geometry", ns.name)
end)
it("should get interface method name", function()
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/ts/interfaces.go" -- %:p:h ? %:p
print("test:" .. path)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", { bufn, 11, 5, 0 })
local ns = require("go.ts.go").get_interface_method_node_at_pos(11, 5)
print(vim.inspect(ns))
eq("Area", ns.name)
end)
it("should get package name", function()
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/ts/interfaces.go" -- %:p:h ? %:p
print("test:" .. path)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", { bufn, 3, 5, 0 })
local ns = require("go.ts.go").get_package_node_at_pos(3, 5)
print(vim.inspect(ns))
eq("main", ns.name)
end)
it("should get package name", function()
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/ts/interfaces.go" -- %:p:h ? %:p
print("test:" .. path)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
vim.fn.setpos(".", { bufn, 3, 1, 0 })
local ns = require("go.ts.go").get_package_node_at_pos(3, 1)
print(vim.inspect(ns))
eq("main", ns.name)
end)
end)

@ -1,14 +0,0 @@
let s:cpo_save = &cpo
set cpo&vim
" CompilerSet errorformat =%-G#\ %.%# " Ignore lines beginning with '#' ('# command-line-arguments' line sometimes appears?)
" CompilerSet errorformat+=%-G%.%#panic:\ %m " Ignore lines containing 'panic: message'
" CompilerSet errorformat+=%Ecan\'t\ load\ package:\ %m " Start of multiline error string is 'can\'t load package'
" CompilerSet errorformat+=%A%\\%%(%[%^:]%\\+:\ %\\)%\\?%f:%l:%c:\ %m " Start of multiline unspecified string is 'filename:linenumber:columnnumber:'
" CompilerSet errorformat+=%A%\\%%(%[%^:]%\\+:\ %\\)%\\?%f:%l:\ %m " Start of multiline unspecified string is 'filename:linenumber:'
" CompilerSet errorformat+=%C%*\\s%m " Continuation of multiline error message is indented
" CompilerSet errorformat+=%-G%.%# " All lines not matching any of the above patterns are ignored
"
let &cpo = s:cpo_save
unlet s:cpo_save

@ -0,0 +1,16 @@
(
(const_spec
name: (identifier) @_id
value: (expression_list (raw_string_literal) @sql))
(#contains? @_id "Query")
)
((composite_literal
type: (type_identifier) @_type
body: (literal_value
(keyed_element
(literal_element) @_key
(literal_element) @lua)))
(#eq? @_key "overrideScript")
(#eq? @_type "generatorTestCase"))
Loading…
Cancel
Save