init commit

pull/1/head
ray-x 3 years ago
commit 1e190d6a0e

@ -0,0 +1,92 @@
# [WIP] go.nvim
A modern golang neovim plugin based on treesitter and nvim-lsp. Written in Lua. Async as much as possible.
PR & Suggestions welcome
## install
add 'ray-x/go.nvim' to your package manager
related binaries will be installed the first time you using it
Add lsp format in your vimrc. You can check my dotfiles for details
```lua
require('go').setup()
```
## code format
nvim-lsp support goimport by default.
```vim
autocmd BufWritePre (InsertLeave?) <buffer> lua vim.lsp.buf.formatting_sync(nil,500)
```
The plugin provides code format, by default is goline + gofumports (stricter version of goimport)
The format tool is a asyn format tool in format.lua
```lua
require("go.format").gofmt()
require("go.format").goimport()
```
## Textobject
Supported by treesitter. TS provided better parse result compared to regular expression.
## Build and test
Provided wrapper for gobulild/test etc
## unit test with gotests
Support table based unit test auto generate, parse current function/method name using treesitter
## Modifytags
modifytags by `modifytags` and treesitter
## GoFmt
nvim-lsp support goimport by default. The plugin provided a new formatter, goline + gofumports (stricter version of
goimport)
## Comments and Doc
Auto doc (to suppress golang-lint warning), generate comments by treesitter parsing result
```go
type GoLintComplaining struct{}
```
```lua
lua.require('go.comment').add_comment() -- or your faviourite key binding and setup placeholder "no more complaint ;P"
```
The code will be:
```go
// GoLintComplaining struct no more complaint ;P
type GoLintComplaining struct{}
```
## LSP
LSP supported by nvim-lsp is good enough for a gopher. If you looking for a better GUI. lspsaga and lsp-utils are
what you are looking for.
## Lint
Supported by LSP, if you need golangci-lint better with ALE
## configuration
lua suggested:
```lua
require('go').setup(cfg = {
goimport='gofumports', -- g:go_nvim_goimport
gofmt = 'gofumpt', --g:go_nvim_gofmt,
max_len = 100, -- g:go_nvim_max_len
transform = false, -- vim.g.go_nvim_tag_transfer check gomodifytags for details
test_template = '', -- default to testify if not set; g:go_nvim_tests_template check gotests for details
test_template_dir = '', -- default to nil if not set; g:go_nvim_tests_template_dir check gotests for details
comment_placeholder = '' , -- vim.g.go_nvim_comment_placeholder your cool placeholder e.g. ﳑ    
verbose = false, -- output loginf in messages
})
```

@ -0,0 +1,5 @@
goimport not stable (failed on 2nd time from time to time)
gomodifytags
goimport: could not import.... auto import by run 'go get' "not in your go.mod" append to gomod
key mappings/nvim commands
GoTests -- add unit test

@ -0,0 +1,39 @@
-- some of commands extracted from gopher.vim
local go = {}
function go.setup(cfg)
vim.g.go_nvim_goimport = cfg.goimport or 'gofumports' -- g:go_nvim_goimport
vim.g.go_nvim_gofmt = cfg.gofmt or 'gofumpt' --g:go_nvim_gofmt,
vim.g.go_nvim_max_len = cfg.max_len or 100 -- g:go_nvim_max_len
vim.g.go_nvim_transform = cfg.transform or false -- vim.g.go_nvim_tag_transfer check gomodifytags for details
vim.g.go_nvim_test_dir = cfg.test_dir or '' -- default to current dir. g:go_nvim_tests_dir check gotests for details
vim.g.go_nvim_comment_placeholder = cfg.comment_placeholder or '' -- vim.g.go_nvim_comment_placeholder your cool placeholder e.g. ﳑ    
vim.g.go_nvim_verbose = cfg.verbose or false -- output loginf in messages
vim.cmd('command Gofmt lua require("go.format").gofmt()')
vim.cmd('command Goimport lua require("go.format").goimport()')
vim.cmd([[command GoBuild :setl makeprg=go\ build | :make]])
vim.cmd([[command GoGenerate :setl makeprg=go\ generate | :make]])
vim.cmd([[command GoRun :setl makeprg=go\ run | :make]])
vim.cmd([[command GoTestFunc :make -run ..]])
vim.cmd([[command GoTest :compiler gotest | :make]])
vim.cmd([[command GoTestCompile setl makeprg=go\ build | :make]])
vim.cmd([[command GoTest setl makeprg=go\ build | :make]])
vim.cmd([[command GoAddTest lua require("go.gotests").fun_test()]])
vim.cmd([[command GoAddExpTest lua require("go.gotests").exported_test()]])
vim.cmd([[command GoAddAllTest lua require("go.gotests").all_test()]])
vim.cmd([[command! -nargs=* GoAddTag lua require("go.tags").add(<f-args>)]])
vim.cmd([[command! -nargs=* GoRmTag lua require("go.tags").rm(<f-args>)]])
vim.cmd([[command GoClearTag lua require("go.tags").clear()]])
vim.cmd([[command GoLint :compiler golangci-lint | :make]])
end
return go

@ -0,0 +1,64 @@
-- todo
-- for func name(args) rets {}
-- add cmts // name : rets
local comment = {}
local placeholder = vim.g.go_nvim_comment_placeholder or ""
local ulog = require "go.utils".log
local gen_comment = function(row, col)
local comments = nil
local ns = require("go.ts.go").get_package_node_at_pos(row, col)
if ns ~= nil and ns ~= {} then
-- utils.log("parnode" .. vim.inspect(ns))
comments = "// Package " .. ns.name .. " provides " .. ns.name
return comments, ns
end
ns = require("go.ts.go").get_func_method_node_at_pos(row, col)
if ns ~= nil and ns ~= {} then
-- utils.log("parnode" .. vim.inspect(ns))
comments = "// " .. ns.name .. " " .. ns.type
return comments, ns
end
ns = require("go.ts.go").get_struct_node_at_pos(row, col)
if ns ~= nil and ns ~= {} then
comments = "// " .. ns.name .. " " .. ns.type
return comments, ns
end
ns = require("go.ts.go").get_interface_node_at_pos(row, col)
if ns ~= nil and ns ~= {} then
-- utils.log("parnode" .. vim.inspect(ns))
comments = "// " .. ns.name .. " " .. ns.type
return comments, ns
end
return ""
end
local wrap_comment = function(comment_line, ns)
if string.len(comment_line)>0 and placeholder ~= nil and string.len(placeholder)>0 then
return comment_line .. " " .. placeholder, ns
end
return comment_line, ns
end
comment.gen = function(row, col)
if row == nil or col == nil then
row, col = unpack(vim.api.nvim_win_get_cursor(0))
row, col = row + 1, col + 1
end
local c, ns = wrap_comment(gen_comment(row, col))
--ulog(vim.inspect(ns))
row, col = ns.dim.s.r, ns.dim.s.c
ulog("set cursor " .. tostring(row))
vim.api.nvim_win_set_cursor(0, {row, col})
-- insert doc
vim.fn.append(row - 1, c)
-- set curosr
vim.fn.cursor(row, #c+1)
-- enter into insert mode
vim.api.nvim_command('startinsert!')
return c
end
return comment

@ -0,0 +1,78 @@
-- golines A golang formatter that fixes long lines
-- golines + gofumports(stricter gofmt + goimport)
local api = vim.api
local util = require("go.utils")
local max_len = vim.g.go_nvim_max_len and vim.g.go_nvim_max_len or 100
local goimport = vim.g.go_nvim_goimport ~= nil and vim.g.go_nvim_goimport or "gofumports"
local gofmt = vim.g.go_nvim_gofmt ~= nil and vim.g.go_nvim_gofmt or "gofumpt"
local gofmt_args =
vim.g.go_nvim_gofmt_args and vim.g.go_nvim_gofmt_args or
{"--max-len=" .. tostring(max_len), "--base-formatter=" .. gofmt}
local utils = require('go').utils
local goimport_args =
vim.g.go_nvim_goimport_args and vim.g.go_nvim_goimport_args or
{"--max-len=" .. tostring(max_len), "--base-formatter=" .. goimport}
local run = function(args, from_buffer)
if not from_buffer then
table.insert(args, api.nvim_buf_get_name(0))
print('formatting... ' .. api.nvim_buf_get_name(0) .. vim.inspect(args))
end
local old_lines = api.nvim_buf_get_lines(0, 0, -1, true)
table.insert(args, 1, "golines")
local j =
vim.fn.jobstart(
args,
{
on_stdout = function(job_id, data, event)
if not data or #data==1 and data[1] == "" then return end
if not util.check_same(old_lines, data) then
print("updating codes")
api.nvim_buf_set_lines(0, 0, #data, false, data)
api.nvim_command("write")
else
print("already formatted")
end
utils.log("stdout" .. vim.inspect(data))
old_lines = nil
end,
on_stderr = function(job_id, data, event)
print(vim.inspect(data) .. "stderr")
end,
on_exit = function(id, data, event)
-- utils.log(vim.inspect(data) .. "exit")
-- utils.log("current data " .. vim.inspect(new_lines))
old_lines = nil
end,
stdout_buffered = true,
stderr_buffered = true,
}
)
vim.fn.chansend(j, old_lines)
vim.fn.chanclose(j, "stdin")
end
local M = {}
M.gofmt = function(buf)
vim.env.GO_TEST = "gofmt"
buf = buf or false
require("go.install").install(gofmt)
require("go.install").install("golines")
local a = {}
util.copy_array(gofmt_args, a)
run(a, buf)
end
M.goimport = function()
buf = buf or false
require("go.install").install(goimport)
require("go.install").install("golines")
local a = {}
util.copy_array(goimport_args, a)
run(a, buf)
end
return M

@ -0,0 +1,85 @@
-- Table driven tests based on its target source files' function and method signatures.
-- https://github.com/cweill/gotests
local ut = {}
local gotests = "gotests"
local test_dir = vim.g.go_nvim_test_dir or ""
local test_template = vim.go_nvim_test_template or ""
local utils = require("go").utils
local run = function(setup)
print(vim.inspect(setup))
local j =
vim.fn.jobstart(
setup,
{
on_stdout = function(jobid, data, event)
print("unit tests generate " .. vim.inspect(data))
end,
on_stderr = function(_, data, _)
print("failed to generate tests for " .. vim.inspect(setup) .. "error: " .. vim.inspect(data))
end
}
)
end
local add_test = function(args)
require("go.install").install(gotests)
if string.len(test_template) > 1 then
table.insert(args, "-template")
table.insert(args, test_template)
if string.len(test_dir) > 1 then
table.insert(args, "-template_dir")
table.insert(args, test_dir)
end
end
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
row, col = row + 1, col + 1
local ns = require("go.ts.go").get_func_method_node_at_pos(row, col)
if ns == nil or ns == {} then
return
end
utils.log("parnode" .. vim.inspect(ns))
run(args)
end
ut.fun_test = function(parallel)
parallel = parallel or false
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
row, col = row + 1, col + 1
local ns = require("go.ts.go").get_func_method_node_at_pos(row, col)
if ns == nil or ns == {} then
return
end
-- utils.log("parnode" .. vim.inspect(ns))
local funame = ns.name
-- local rs, re = ns.dim.s.r, ns.dim.e.r
local gofile = vim.fn.expand("%")
local args = {gotests, "-w", "-only", funame, gofile}
if parallel then
table.insert(args, "-parallel")
end
add_test(args)
end
ut.all_test = function(parallel)
parallel = parallel or false
local gofile = vim.fn.expand("%")
local args = {gotests, "-all", "-w", gofile}
if parallel then
table.insert(args, "-parallel")
end
add_test(args)
end
ut.exported_test = function(parallel)
parallel = parallel or false
local gofile = vim.fn.expand("%")
local args = {gotests, "-exported", "-w", gofile}
if parallel then
table.insert(args, "-parallel")
end
add_test(args)
end
return ut

@ -0,0 +1,61 @@
local uv = vim.loop
local gopath = vim.fn.expand("$GOPATH")
local gobinpath = gopath .. "/bin/"
local url = {
golines = "segmentio/golines",
gofumpt = "mvdan/gofumpt",
gofumports = "mvdan/gofumpt",
gomodifytags = "fatih/gomodifytags",
gotsts = "cweill/gotests",
}
local function install(bin)
local state = uv.fs_stat(gobinpath .. bin)
if not state then
print("installing " .. bin)
local u = url[bin]
if u == nil then
print("command " .. bin .. " not supported, please update install.lua")
return
end
local setup = {
"go", "get",
u
}
vim.fn.jobstart(
setup,
-- setup.args,
{
on_stdout = function(c, data, name)
print(data)
end
}
)
end
end
local function update(bin)
local u = url[bin]
if u == nil then
print("command " .. bin .. " not supported, please update install.lua")
return
end
local setup = {"go", "get", "-u", u}
vim.fn.jobstart(
setup,
{
on_stdout = function(c, data, name)
print(data)
end
}
)
end
local function install_all()
for key, value in pairs(url) do
install(key)
end
end
return {install = install, update = update, install_all = install_all}

@ -0,0 +1,65 @@
local uv, api = vim.loop, vim.api
local check_same = function(tbl1, tbl2)
if #tbl1 ~= #tbl2 then
return
end
for k, v in ipairs(tbl1) do
if v ~= tbl2[k] then
return true
end
end
return false
end
local run = function(cmd, args, on_stdout, stdin_data, buf)
buf = buf or false
local stdin = uv.new_pipe(false)
local stdout = uv.new_pipe(false)
local stderr = uv.new_pipe(false)
local file = api.nvim_buf_get_name(0)
local handle, pid =
uv.spawn(
cmd,
{
stdio = {stdin, stdout, stderr},
args = args
},
function(code, signal) -- on exit
end
)
uv.read_start(stdout, vim.schedule_wrap(on_stdout))
uv.read_start(
stderr,
function(err, data)
assert(not err, err)
if data then
print("stderr chunk", stderr, data)
end
end
)
if buf then
for i = 1, #stdin_data do
print("sending " .. stdin_data[i])
stdin:write(stdin_data[i])
end
if not stdin:is_closing() then
stdin:close()
end
end
uv.shutdown(
stdin,
function()
uv.close(
handle,
function()
end
)
end
)
end
return {golines_format = golines_format, run = run}

@ -0,0 +1,86 @@
local tags = {}
-- support -add-tags, --add-options, -remove-tags, -remove-options, clear-tags, clear-options
-- for struct and line range
-- gomodifytags -file demo.go -struct Server -add-tags json
-- gomodifytags -file demo.go -struct Server -add-tags json -w
-- gomodifytags -file demo.go -struct Server -add-tags json,xml
-- gomodifytags -file demo.go -struct Server -add-tags json,xml -transform camelcase
-- gomodifytags -file demo.go -line 8,11 -clear-tags xml
local opts = {"-add-tags", "-add-options", "-remove-tags", "-remove-options", "-clear-tags", "-clear-options"}
local gomodify = "gomodifytags"
local transform = vim.g.go_nvim_tag_transfer
tags.modify = function(...)
require("go.install").install(gomodify)
local fname = vim.fn.expand("%") -- %:p:h ? %:p
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
row, col = row + 1, col + 1
local ns = require("go.ts.go").get_struct_node_at_pos(row, col)
if ns == nil or ns == {} then
return
end
-- print("parnode" .. vim.inspect(ns))
local struct_name = ns.name
local rs, re = ns.dim.s.r, ns.dim.e.r
setup = {gomodify, "-format", "json", "-file", fname, "-struct", struct_name, '-w'}
if transform ~= nil then
table.insert(setup.args, "-transform")
table.insert(setup.args, transform)
end
local arg = {...}
for i, v in ipairs(arg) do
table.insert(setup, v)
end
if #arg == 1 and arg[1] ~= "clear-tags" then
table.insert(setup, "json")
end
-- print(vim.inspect(setup))
local j =
vim.fn.jobstart(
setup,
{
on_stdout = function(jobid, data, event)
if not data or #data == 1 and data[1] == "" then
return
end
local tagged = vim.fn.json_decode(data)
-- print(vim.inspect(tagged))
-- print(tagged["start"], tagged["end"], tagged.lines)
if tagged.errors ~= nil or tagged.lines == nil or tagged["start"] == nil or tagged["start"] == 0 then
print("failed to set tags" .. vim.inspect(tagged))
end
vim.api.nvim_buf_set_lines(0, tagged["start"]-1, tagged["start"]-1+#tagged.lines, false, tagged.lines)
vim.cmd("write")
print("wrote " .. tostring(tagged.lines))
end
}
)
end
tags.add = function(...)
local cmd = {"-add-tags"}
local arg = {...}
for _, v in ipairs(arg) do
table.insert(cmd, v)
end
tags.modify(unpack(cmd))
end
tags.rm = function(...)
local cmd = {"-remove-tags"}
local arg = {...}
for _, v in ipairs(arg) do
table.insert(cmd, v)
end
tags.modify(unpack(cmd))
end
tags.clear = function()
local cmd = {"-clear-tags"}
tags.modify(unpack(cmd))
end
return tags

@ -0,0 +1,158 @@
M = {
-- query_struct = "(type_spec name:(type_identifier) @definition.struct type: (struct_type))",
query_package = "(package_clause (package_identifier)@package.name)@package.clause",
query_struct_id = "(type_spec name:(type_identifier) @definition.struct (struct_type))",
query_em_struct_id = "(field_declaration name:(field_identifier) @definition.struct (struct_type))",
query_struct_block = "(type_declaration (type_spec name:(type_identifier) @struct.name type: (struct_type)))@struct.declaration",
query_em_struct_block = "(field_declaration name:(field_identifier)@struct.name type: (struct_type)) @struct.declaration",
query_struct_block_from_id = "((type_spec name:(type_identifier) type: (struct_type)))@block.struct_from_id",
--query_em_struct = "(field_declaration name:(field_identifier) @definition.struct type: (struct_type))",
query_interface_id = [[(type_declaration (type_spec name:(type_identifier) @interface.name type:(interface_type)))@interface.declaration]],
query_interface_method = [[(method_spec name: (field_identifier)@method.name)@interface.method.declaration]],
query_func = "((function_declaration name: (identifier)@function.name) @function.declaration)",
-- query_method = "(method_declaration receiver: (parameter_list (parameter_declaration name:(identifier)@method.receiver.name type:(type_identifier)@method.receiver.type)) name:(field_identifier)@method.name)@method.declaration"
query_method_name = [[(method_declaration
receiver: (parameter_list)@method.receiver
name: (field_identifier)@method.name
body:(block))@method.declaration]],
query_method_void = [[(method_declaration
receiver: (parameter_list
(parameter_declaration
name: (identifier)@method.receiver.name
type: (pointer_type)@method.receiver.type)
)
name: (field_identifier)@method.name
parameters: (parameter_list)@method.parameter
body:(block)
)@method.declaration]],
query_method_multi_ret = [[(method_declaration
receiver: (parameter_list
(parameter_declaration
name: (identifier)@method.receiver.name
type: (pointer_type)@method.receiver.type)
)
name: (field_identifier)@method.name
parameters: (parameter_list)@method.parameter
result: (parameter_list)@method.result
body:(block)
)@method.declaration]],
query_method_single_ret = [[(method_declaration
receiver: (parameter_list
(parameter_declaration
name: (identifier)@method.receiver.name
type: (pointer_type)@method.receiver.type)
)
name: (field_identifier)@method.name
parameters: (parameter_list)@method.parameter
result: (type_identifier)@method.result
body:(block)
)@method.declaration]],
query_tr_method_void = [[(method_declaration
receiver: (parameter_list
(parameter_declaration
name: (identifier)@method.receiver.name
type: (type_identifier)@method.receiver.type)
)
name: (field_identifier)@method.name
parameters: (parameter_list)@method.parameter
body:(block)
)@method.declaration]],
query_tr_method_multi_ret = [[(method_declaration
receiver: (parameter_list
(parameter_declaration
name: (identifier)@method.receiver.name
type: (type_identifier)@method.receiver.type)
)
name: (field_identifier)@method.name
parameters: (parameter_list)@method.parameter
result: (parameter_list)@method.result
body:(block)
)@method.declaration]],
query_tr_method_single_ret = [[(method_declaration
receiver: (parameter_list
(parameter_declaration
name: (identifier)@method.receiver.name
type: (type_identifier)@method.receiver.type)
)
name: (field_identifier)@method.name
parameters: (parameter_list)@method.parameter
result: (type_identifier)@method.result
body:(block)
)@method.declaration]]
}
function get_name_defaults()
return {
["func"] = "function",
["if"] = "if",
["else"] = "else",
["for"] = "for",
}
end
M.get_struct_node_at_pos = function(row, col)
local query = require("go.ts.go").query_struct_block .. " " .. require("go.ts.go").query_em_struct_block
local nodes = require("go.ts.nodes")
local bufn = vim.fn.bufnr("")
local ns = nodes.nodes_at_cursor(query, get_name_defaults(), bufn, row, col)
return ns[#ns]
end
M.get_interface_node_at_pos = function(row, col)
local query = require("go.ts.go").query_interface_id
local nodes = require("go.ts.nodes")
local bufn = vim.fn.bufnr("")
local ns = nodes.nodes_at_cursor(query, get_name_defaults(), bufn, row, col)
return ns[#ns]
end
M.get_interface_method_node_at_pos = function(row, col)
local query = require("go.ts.go").query_interface_method
local nodes = require("go.ts.nodes")
local bufn = vim.fn.bufnr("")
local ns = nodes.nodes_at_cursor(query, get_name_defaults(), bufn, row, col)
return ns[#ns]
end
M.get_func_method_node_at_pos = function(row, col)
local query = require("go.ts.go").query_func .. " " .. require("go.ts.go").query_method_name
-- local query = require("go.ts.go").query_method_name
local nodes = require("go.ts.nodes")
local bufn = vim.fn.bufnr("")
local ns = nodes.nodes_at_cursor(query, get_name_defaults(), bufn, row, col)
if ns == nil then return nil end
return ns[#ns]
end
M.get_package_node_at_pos = function(row, col)
if row > 10 then return end
local query = require("go.ts.go").query_package
-- local query = require("go.ts.go").query_method_name
local nodes = require("go.ts.nodes")
local bufn = vim.fn.bufnr("")
local ns = nodes.nodes_at_cursor(query, get_name_defaults(), bufn, row, col)
if ns == nil then return nil end
return ns[#ns]
end
return M

@ -0,0 +1,240 @@
-- part of the code from polarmutex/contextprint.nvim
local ts_utils = require("nvim-treesitter.ts_utils")
local ts_query = require("nvim-treesitter.query")
local parsers = require("nvim-treesitter.parsers")
local locals = require("nvim-treesitter.locals")
local utils = require("go.ts.utils")
local ulog = require("go.utils").log
local M = {}
-- Array<node_wrapper>
M.intersect_nodes = function(nodes, row, col)
local found = {}
for idx = 1, #nodes do
local node = nodes[idx]
local sRow = node.dim.s.r
local sCol = node.dim.s.c
local eRow = node.dim.e.r
local eCol = node.dim.e.c
if utils.intersects(row, col, sRow, sCol, eRow, eCol) then
table.insert(found, node)
end
end
return found
end
M.count_parents = function(node)
local count = 0
local n = node.declaring_node
while n ~= nil do
n = n:parent()
count = count + 1
end
return count
end
-- @param nodes Array<node_wrapper>
-- perf note. I could memoize some values here...
M.sort_nodes = function(nodes)
table.sort(
nodes,
function(a, b)
return M.count_parents(a) < M.count_parents(b)
end
)
return nodes
end
-- local lang = vim.api.nvim_buf_get_option(bufnr, 'ft')
-- node_wrapper
-- returns [{
-- declaring_node = tsnode
-- dim: {s: {r, c}, e: {r, c}},
-- name: string
-- type: string
-- }]
M.get_nodes = function(query, lang, defaults, bufnr)
bufnr = bufnr or 0
local success, parsed_query =
pcall(
function()
return vim.treesitter.parse_query(lang, query)
end
)
if not success then
return nil
end
local parser = parsers.get_parser(bufnr, lang)
local root = parser:parse()[1]:root()
local start_row, _, end_row, _ = root:range()
-- local n = ts_utils.get_node_at_cursor()
-- local a, b, c, d = ts_utils.get_node_range(n)
local results = {}
for match in ts_query.iter_prepared_matches(parsed_query, root, bufnr, start_row, end_row) do
local sRow, sCol, eRow, eCol
local declaration_node
local type = "nil"
local name = "nil"
locals.recurse_local_nodes(
match,
function(_, node, path)
local idx = string.find(path, ".", 1, true)
local op = string.sub(path, idx + 1, #path)
local a1, b1, c1, d1 = ts_utils.get_node_range(node)
type = string.sub(path, 1, idx - 1)
if name == nil then
name = defaults[type] or "empty"
end
if op == "name" then
name = ts_utils.get_node_text(node)[1]
elseif op == "declaration" then
declaration_node = node
sRow, sCol, eRow, eCol = node:range()
sRow = sRow + 1
eRow = eRow + 1
sCol = sCol + 1
eCol = eCol + 1
end
end
)
if declaration_node ~= nil then
table.insert(
results,
{
declaring_node = declaration_node,
dim = {
s = {r = sRow, c = sCol},
e = {r = eRow, c = eCol}
},
name = name,
type = type
}
)
end
end
return results
end
-- local lang = vim.api.nvim_buf_get_option(bufnr, 'ft')
-- node_wrapper
-- returns {
-- declaring_node = tsnode
-- dim: {s: {r, c}, e: {r, c}},
-- name: string
-- type: string
-- }
M.get_all_nodes = function(query, lang, defaults, bufnr, pos_row, pos_col)
bufnr = bufnr or 0
-- todo a huge number
pos_row = pos_row or 30000
local success, parsed_query =
pcall(
function()
return vim.treesitter.parse_query(lang, query)
end
)
if not success then
return nil
end
local parser = parsers.get_parser(bufnr, lang)
local root = parser:parse()[1]:root()
local start_row, _, end_row, _ = root:range()
-- local n = ts_utils.get_node_at_cursor()
-- local a, b, c, d = ts_utils.get_node_range(n)
-- ulog("node range " .. tostring(a) .. tostring(b) .. tostring(c).. tostring(d))
-- ulog("cru node:" .. vim.inspect(n) .. "text: " .. vim.inspect(ts_utils.get_node_text(n)))
local results = {}
for match in ts_query.iter_prepared_matches(parsed_query, root, bufnr, start_row, end_row) do
local sRow, sCol, eRow, eCol
local declaration_node
local type = ""
local name = ""
local op = ""
local method_receiver = ""
locals.recurse_local_nodes(
match,
function(_, node, path)
--local idx = string.find(path, ".", 1, true)
local idx = string.find(path, ".[^.]*$") -- find last .
op = string.sub(path, idx + 1, #path)
local a1, b1, c1, d1 = ts_utils.get_node_range(node)
local dbg_txt = ts_utils.get_node_text(node, bufnr)[1]
type = string.sub(path, 1, idx - 1)
ulog( "node" .. vim.inspect(node) .. "\n path: " .. path .. " op: " .. op .. " type: " .. type .. "\n txt: " .. dbg_txt .. "\n range: " .. tostring(a1) .. ":" .. tostring(b1) .. " TO " .. tostring(c1) .. ":" .. tostring(d1))
--
-- may not handle complex node
if op == "name" then
-- ulog("node name " .. name)
name = ts_utils.get_node_text(node, bufnr)[1]
elseif op == "declaration" or op == "clause" then
declaration_node = node
sRow, sCol, eRow, eCol = node:range()
sRow = sRow + 1
eRow = eRow + 1
sCol = sCol + 1
eCol = eCol + 1
end
end
)
if declaration_node ~= nil then
-- ulog(name .. " " .. op)
-- ulog(sRow, pos_row)
if sRow > pos_row then
ulog("beyond " .. tostring(pos_row))
break
end
table.insert(
results,
{
declaring_node = declaration_node,
dim = {
s = {r = sRow, c = sCol},
e = {r = eRow, c = eCol}
},
name = name,
operator = op,
type = type
}
)
end
end
-- ulog("total nodes got: " .. tostring(#results))
return results
end
M.nodes_at_cursor = function(query, default, bufnr, row, col)
bufnr = bufnr or vim.api.nvim_get_current_buf()
local ft = vim.api.nvim_buf_get_option(bufnr, "ft")
if row == nil or col == nil then
row, col = unpack(vim.api.nvim_win_get_cursor(0))
row, col = row + 1, col + 1
end
local nodes = M.get_all_nodes(query, ft, default, bufnr, row, col)
if nodes == nil then
print("Unable to find any nodes. Is your query correct?")
return nil
end
nodes = M.sort_nodes(M.intersect_nodes(nodes, row, col))
if nodes == nil or #nodes == 0 then
print("Unable to find any nodes at pos. " .. tostring(row) .. ":" .. tostring(col))
return nil
end
return nodes
end
return M

@ -0,0 +1,19 @@
local M = {}
M.intersects = function(row, col, sRow, sCol, eRow, eCol)
-- print(row, col, sRow, sCol, eRow, eCol)
if sRow > row or eRow < row then
return false
end
if sRow == row and sCol > col then
return false
end
if eRow == row and eCol < col then
return false
end
return true
end
return M

@ -0,0 +1,41 @@
local util = {}
util.check_same = function(tbl1, tbl2)
if #tbl1 ~= #tbl2 then
return
end
for k, v in ipairs(tbl1) do
if v ~= tbl2[k] then
return true
end
end
return false
end
util.copy_array = function(from, to)
for i = 1, #from do
to[i] = from[i]
end
end
util.deepcopy = function (orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[util.deepcopy(orig_key)] = util.deepcopy(orig_value)
end
setmetatable(copy, util.deepcopy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
util.log = function(...)
if vim.g.go_nvim_verbose then
print(...)
end
end
return util

@ -0,0 +1,5 @@
package main
func main() {
fmt.Println("vim-go")
}

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("vim-go")
}

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("vim-go")
}

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("vim-go")
}

@ -0,0 +1,17 @@
package main
type Server struct {
Name string `json:"name"`
ID int `json:"id"`
MyHomeAddress string `json:"my_home_address"`
SubDomains []string `json:"sub_domains"`
Empty string `json:"empty"`
Example int64 `json:"example"`
Example2 string `json:"example_2"`
Bar struct {
Four string `json:"four"`
Five string `json:"five"`
} `json:"bar"`
Lala interface{} `json:"lala"`
} //eos
//eof

@ -0,0 +1,17 @@
package main
type Server struct {
Name string `json:"name,omitempty"`
ID int `json:"id,omitempty"`
MyHomeAddress string `json:"my_home_address,omitempty"`
SubDomains []string `json:"sub_domains,omitempty"`
Empty string `json:"empty,omitempty"`
Example int64 `json:"example,omitempty"`
Example2 string `json:"example_2,omitempty"`
Bar struct {
Four string `json:"four,omitempty"`
Five string `json:"five,omitempty"`
} `json:"bar,omitempty"`
Lala interface{} `json:"lala,omitempty"`
} //eos
//eof

@ -0,0 +1,17 @@
package main
type Server struct {
Name string
ID int
MyHomeAddress string
SubDomains []string
Empty string
Example int64
Example2 string
Bar struct {
Four string
Five string
}
Lala interface{}
} //eos
//eof

@ -0,0 +1,17 @@
package main
type Server struct {
Name string
ID int
MyHomeAddress string
SubDomains []string
Empty string
Example int64
Example2 string
Bar struct {
Four string
Five string
}
Lala interface{}
} //eos
//eof

@ -0,0 +1,17 @@
package main
type Server struct {
Name string `json:"name"`
ID int `json:"id"`
MyHomeAddress string `json:"my_home_address"`
SubDomains []string `json:"sub_domains"`
Empty string `json:"empty"`
Example int64 `json:"example"`
Example2 string `json:"example_2"`
Bar struct {
Four string `json:"four"`
Five string `json:"five"`
} `json:"bar"`
Lala interface{} `json:"lala"`
} //eos
//eof

@ -0,0 +1,48 @@
// https://gobyexample.com/interfaces
//
package main
import (
"fmt"
"math"
)
type Geometry interface {
Area() float64
perim() float64
}
type rect struct {
width, height float64
}
type circle struct {
radius float64
}
func (r rect) Area() float64 {
return r.width * r.height
}
func (r rect) perim() float64 {
return 2*r.width + 2*r.height
}
func (c circle) Area() float64 {
return math.Pi * c.radius * c.radius
}
func (c circle) perim() float64 {
return 2 * math.Pi * c.radius
}
func measure(g Geometry) {
fmt.Println(g)
fmt.Println(g.Area())
fmt.Println(g.perim())
}
func main() {
r := rect{width: 3, height: 4}
c := circle{radius: 5}
measure(r)
measure(c)
}

@ -0,0 +1,99 @@
// code form https://medium.com/backendarmy/linked-lists-in-go-f7a7b27a03b9
// this code is use to test treesiter parser
package main
import "fmt"
type song struct {
name string
artist string
next *song
}
type playlist struct {
name string
head *song
nowPlaying *song
}
func createPlaylist(name string) *playlist {
return &playlist{
name: name,
}
}
func (p *playlist) addSong(name, artist string) error {
s := &song{
name: name,
artist: artist,
}
if p.head == nil {
p.head = s
} else {
currentNode := p.head
for currentNode.next != nil {
currentNode = currentNode.next
}
currentNode.next = s
}
return nil
}
func (p *playlist) showAllSongs() error {
currentNode := p.head
if currentNode == nil {
fmt.Println("Playlist is empty.")
return nil
}
fmt.Printf("%+v\n", *currentNode)
for currentNode.next != nil {
currentNode = currentNode.next
fmt.Printf("%+v\n", *currentNode)
}
return nil
}
func (p *playlist) startPlaying() *song {
p.nowPlaying = p.head
return p.nowPlaying
}
func (p *playlist) nextSong() *song {
p.nowPlaying = p.nowPlaying.next
return p.nowPlaying
}
func (p *playlist) NextSong() *song { // exported
p.nowPlaying = p.nowPlaying.next
return p.nowPlaying
}
func main() {
playlistName := "myplaylist"
myPlaylist := createPlaylist(playlistName)
fmt.Println("Created playlist")
fmt.Println()
fmt.Print("Adding songs to the playlist...\n\n")
myPlaylist.addSong("Ophelia", "The Lumineers")
myPlaylist.addSong("Shape of you", "Ed Sheeran")
myPlaylist.addSong("Stubborn Love", "The Lumineers")
myPlaylist.addSong("Feels", "Calvin Harris")
fmt.Println("Showing all songs in playlist...")
myPlaylist.showAllSongs()
fmt.Println()
myPlaylist.startPlaying()
fmt.Printf("Now playing: %s by %s\n", myPlaylist.nowPlaying.name, myPlaylist.nowPlaying.artist)
fmt.Println()
myPlaylist.nextSong()
fmt.Println("Changing next song...")
fmt.Printf("Now playing: %s by %s\n", myPlaylist.nowPlaying.name, myPlaylist.nowPlaying.artist)
fmt.Println()
myPlaylist.nextSong()
fmt.Println("Changing next song...")
fmt.Printf("Now playing: %s by %s\n", myPlaylist.nowPlaying.name, myPlaylist.nowPlaying.artist)
}

@ -0,0 +1,42 @@
local eq = assert.are.same
local busted = require("plenary/busted")
local cur_dir = vim.fn.expand("%:p:h")
describe(
"should get nodes ",
function()
vim.g.go_nvim_verbose = true
vim.g.go_nvim_comment_placeholder = "go.nvim"
local status = require("plenary.reload").reload_module("go.nvim")
status = require("plenary.reload").reload_module("nvim-treesitter/nvim-treesitter")
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/ts/playlist.go" -- %:p:h ? %:p
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local cmd = "silent exe 'e " .. name .. "'"
vim.cmd(cmd)
local bufn = vim.fn.bufnr("")
it(
"should get struct playlist and generate comments",
function()
vim.fn.setpos(".", {bufn, 20, 14, 0})
local query = require("go.comment").gen(20, 14)
eq("// createPlaylist function go.nvim", query)
end
)
it(
"should get struct playlist and generate comments",
function()
vim.fn.setpos(".", {bufn, 14, 4, 0})
local query = require("go.comment").gen(14, 4)
eq("// playlist struct go.nvim", query)
end
)
end
)

@ -0,0 +1,129 @@
local eq = assert.are.same
local cur_dir = vim.fn.expand("%:p:h")
describe(
"should run gofmt",
function()
--vim.fn.readfile('minimal.vim')
-- vim.fn.writefile(vim.fn.readfile('fixtures/fmt/hello.go'), name)
status = require("plenary.reload").reload_module("go.nvim")
it(
"should run fmt",
function()
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/fmt/hello.go" -- %:p:h ? %:p
print("test:" .. path)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local expected =
vim.fn.join(vim.fn.readfile(cur_dir .. "/lua/tests/fixtures/fmt/hello_golden.go"), "\n")
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
local l = vim.api.nvim_buf_get_lines(0, 0, -1, true)
print("buf read: " .. vim.inspect(l))
vim.bo.filetype = "go"
print("exp:" .. vim.inspect(expected))
print("tmp" .. name)
local gofmt = require("go.format")
gofmt.gofmt()
-- enable the channel response
vim.wait(100, function () end)
local fmt =
vim.fn.join(vim.fn.readfile(name), "\n")
print("fmt" .. fmt)
vim.fn.assert_equal(fmt, expected)
eq(expected, fmt)
local cmd = "bd! ".. name
vim.cmd(cmd)
end
)
it(
"should run fmt sending from buffer",
function()
local name = vim.fn.tempname() .. ".go"
print("tmp:" .. name)
--
local path = cur_dir .. "/lua/tests/fixtures/fmt/hello.go" -- %:p:h ? %:p
print("test:" .. path)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local expected =
vim.fn.join(vim.fn.readfile(cur_dir .. "/lua/tests/fixtures/fmt/hello_golden.go"), "\n")
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
local l = vim.api.nvim_buf_get_lines(0, 0, -1, true)
print("buf read: " .. vim.inspect(l))
vim.bo.filetype = "go"
print("exp:" .. vim.inspect(expected))
print("tmp" .. name)
local gofmt = require("go.format")
gofmt.gofmt(true)
-- enable the channel response
vim.wait(100, function () end)
local fmt =
vim.fn.join(vim.fn.readfile(name), "\n")
print("fmt" .. fmt)
vim.fn.assert_equal(fmt, expected)
eq(expected, fmt)
local cmd = "bd! ".. name
vim.cmd(cmd)
end
)
it(
"should run import from file",
function()
local path = cur_dir .. "/lua/tests/fixtures/fmt/goimports.go" -- %:p:h ? %:p
local expected = vim.fn.join(vim.fn.readfile(cur_dir .. "/lua/tests/fixtures/fmt/goimports_golden.go"), "\n")
local name = vim.fn.tempname() .. ".go"
print(name)
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
local gofmt = require("go.format")
gofmt.goimport()
vim.wait( 100, function() end)
local fmt = vim.fn.join(vim.fn.readfile(name), "\n")
eq(expected, fmt)
cmd = "bd! " .. name
vim.cmd(cmd)
end
)
it(
"should run import from file buffer",
function()
local path = cur_dir .. "/lua/tests/fixtures/fmt/goimports.go" -- %:p:h ? %:p
local expected = vim.fn.join(vim.fn.readfile(cur_dir .. "/lua/tests/fixtures/fmt/goimports_golden.go"), "\n")
local name = vim.fn.tempname() .. ".go"
print(name)
local lines = vim.fn.readfile(path)
local cmd = " silent exe 'e " .. name .. "'"
vim.fn.writefile(lines, name)
vim.cmd(cmd)
print("code write to " .. name)
local gofmt = require("go.format")
gofmt.goimport(true)
vim.wait(
100,
function()
end
)
local fmt = vim.fn.join(vim.fn.readfile(name), "\n")
print(fmt)
eq(expected, fmt)
end
)
end
)

@ -0,0 +1,162 @@
local helpers = {}
local busted = require("plenary/busted")
local eq = assert.are.same
local cur_dir = vim.fn.expand("%:p:h")
local ulog = require('go.utils').log
describe(
"should run gotags",
function()
--vim.fn.readfile('minimal.vim')
-- vim.fn.writefile(vim.fn.readfile('fixtures/fmt/hello.go'), name)
status = require("plenary.reload").reload_module("go.nvim")
it(
"should run add json tags",
function()
--
local name = vim.fn.tempname() .. ".go"
local path = cur_dir .. "/lua/tests/fixtures/tags/add_all_input.go" -- %:p:h ? %:p
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local expected =
vim.fn.join(vim.fn.readfile(cur_dir .. "/lua/tests/fixtures/tags/add_all_golden.go"), "\n")
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
local bufn = vim.fn.bufnr("")
vim.fn.setpos(".", {bufn, 8, 4, 0})
local l = vim.api.nvim_buf_get_lines(0, 0, -1, true)
-- ulog("buf read: " .. vim.inspect(l))
vim.bo.filetype = "go"
-- ulog("exp:" .. vim.inspect(expected))
local gotags = require("go.tags")
gotags.add()
-- enable the channel response
vim.wait(100, function () end)
local fmt =
vim.fn.join(vim.fn.readfile(name), "\n")
-- ulog("tagged file: " .. fmt)
vim.fn.assert_equal(fmt, expected)
eq(expected, fmt)
local cmd = "bd! ".. name
vim.cmd(cmd)
end
)
it(
"should rm json tags",
function()
local name = vim.fn.tempname() .. ".go"
--
local path = cur_dir .. "/lua/tests/fixtures/tags/add_all_golden.go" -- %:p:h ? %:p
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local expected =
vim.fn.join(vim.fn.readfile(cur_dir .. "/lua/tests/fixtures/tags/add_all_input.go"), "\n")
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
local bufn = vim.fn.bufnr("")
vim.fn.setpos(".", {bufn, 8, 4, 0})
local l = vim.api.nvim_buf_get_lines(0, 0, -1, true)
-- ulog("buf read: " .. vim.inspect(l))
vim.bo.filetype = "go"
-- ulog("exp:" .. vim.inspect(expected))
local gotags = require("go.tags")
gotags.rm('json')
-- enable the channel response
vim.wait(100, function () end)
local fmt =
vim.fn.join(vim.fn.readfile(name), "\n")
-- ulog("tagged file: " .. fmt)
vim.fn.assert_equal(fmt, expected)
eq(expected, fmt)
local cmd = "bd! ".. name
vim.cmd(cmd)
end
)
it(
"should run clear json tags by default",
function()
local name = vim.fn.tempname() .. ".go"
--
local path = cur_dir .. "/lua/tests/fixtures/tags/add_all_golden.go" -- %:p:h ? %:p
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local expected =
vim.fn.join(vim.fn.readfile(cur_dir .. "/lua/tests/fixtures/tags/add_all_input.go"), "\n")
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
local bufn = vim.fn.bufnr("")
vim.fn.setpos(".", {bufn, 8, 4, 0})
local l = vim.api.nvim_buf_get_lines(0, 0, -1, true)
-- ulog("buf read: " .. vim.inspect(l))
vim.bo.filetype = "go"
-- ulog("exp:" .. vim.inspect(expected))
local gotags = require("go.tags")
gotags.rm()
-- enable the channel response
vim.wait(100, function () end)
local fmt =
vim.fn.join(vim.fn.readfile(name), "\n")
-- ulog("tagged file: " .. fmt)
vim.fn.assert_equal(fmt, expected)
eq(expected, fmt)
local cmd = "bd! ".. name
vim.cmd(cmd)
end
)
it(
"should clear all tags",
function()
local name = vim.fn.tempname() .. ".go"
--
local path = cur_dir .. "/lua/tests/fixtures/tags/add_all_golden.go" -- %:p:h ? %:p
local lines = vim.fn.readfile(path)
vim.fn.writefile(lines, name)
local expected =
vim.fn.join(vim.fn.readfile(cur_dir .. "/lua/tests/fixtures/tags/add_all_input.go"), "\n")
local cmd = " silent exe 'e " .. name .. "'"
vim.cmd(cmd)
local bufn = vim.fn.bufnr("")
vim.fn.setpos(".", {bufn, 8, 4, 0})
local l = vim.api.nvim_buf_get_lines(0, 0, -1, true)
-- ulog("buf read: " .. vim.inspect(l))
vim.bo.filetype = "go"
-- ulog("exp:" .. vim.inspect(expected))
local gotags = require("go.tags")
gotags.rm()
-- enable the channel response
vim.wait(100, function () end)
local fmt =
vim.fn.join(vim.fn.readfile(name), "\n")
-- ulog("tagged file: " .. fmt)
vim.fn.assert_equal(fmt, expected)
eq(expected, fmt)
local cmd = "bd! ".. name
vim.cmd(cmd)
end
)
end
)

@ -0,0 +1,211 @@
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{}"
}
local default = {
["function"] = "func",
["method"] = "func",
["struct"] = "struct",
["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"`',
"}",
""
}
describe(
"should get nodes ",
function()
vim.cmd([[silent exe 'e tags.go']])
vim.fn.append(0, input)
local bufn = vim.fn.bufnr("")
status = require("plenary.reload").reload_module("go.nvim")
status = require("plenary.reload").reload_module("nvim-treesitter/nvim-treesitter")
vim.g.go_nvim_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
)

@ -0,0 +1,6 @@
set rtp +=.
set rtp +=~/.vim/autoload/plenary.nvim/
runtime! plugin/plenary.vim
lua require("plenary/busted")
lua require("go.nvim")
Loading…
Cancel
Save