diff --git a/README.md b/README.md
index 53664d833..2ed5d219d 100644
--- a/README.md
+++ b/README.md
@@ -372,9 +372,13 @@ Show go doc for api in neovim floating window. e.g. `GoDoc fmt.Println`
If no argument provided, fallback to lsp.hover()
+## GoDocBrowser
+
+Similar to GoDoc, but open the browser with the doc link. If no argument provided, open doc for current function/package
+
## GoPkgOutline
-A symbole outline for all symbols (var, const, func, struct, interface etc) inside a package You can still use navigator
+A symbol outline for all symbols (var, const, func, struct, interface etc) inside a package You can still use navigator
or sidebar plugins (e.g. vista, symbols-outline) to check outline within a file. But it is more useful for go to check
the symbols in a package, as those symbols are visuals inside package, also the method can be defined in different
source file.
@@ -385,6 +389,11 @@ package If guihua not installed fallback to loclist
+## GoPkgSymbols
+
+A symbol outline for all symbols (var, const, func, struct, interface etc) inside current package
+
+
## Modifytags
Modify struct tags by [`gomodifytags`](https://github.com/fatih/gomodifytags) and treesitter
diff --git a/doc/go.txt b/doc/go.txt
index 71a5bac73..bc5dc2cb5 100644
--- a/doc/go.txt
+++ b/doc/go.txt
@@ -339,6 +339,10 @@ COMMANDS *go-nvim-commands*
options: -f (floating win), -p package_name
default options: sidepanel, current package in vim buffer
+:GoPkgSymbols *:GoPkgSymbols*
+ show symbols inside current package in side panel/loclist
+ options: none
+
:GoImplements {options} *:GoImplements*
GoImplements calls vim.lsp.buf.implementation
diff --git a/lua/go/commands.lua b/lua/go/commands.lua
index 0ea2e1cf3..71708fed1 100644
--- a/lua/go/commands.lua
+++ b/lua/go/commands.lua
@@ -247,6 +247,24 @@ return {
nargs = '*',
})
+ create_cmd('GoPkgSymbols', function(opts)
+ require('go.package').symbols()
+ end, {
+ complete = function(a, l)
+ -- return package.loaded.go.package_complete(a, l)
+ return ''
+ end,
+ nargs = '*',
+ })
+ create_cmd('GoGCDetails', function(opts)
+ require('go.gopls').gc_details(unpack(opts.fargs))
+ end, {
+ complete = function(a, l)
+ return package.loaded.go.package_complete(a, l)
+ end,
+ nargs = '*',
+ })
+
local lint_cfg = _GO_NVIM_CFG.golangci_lint or { default = 'standard' }
local default = [[\ --default=]] .. lint_cfg.default
local disable = lint_cfg.disable or {}
diff --git a/lua/go/gopls.lua b/lua/go/gopls.lua
index 2a5c82943..0af5e8055 100644
--- a/lua/go/gopls.lua
+++ b/lua/go/gopls.lua
@@ -113,6 +113,7 @@ for _, gopls_cmd in ipairs(gopls_cmds) do
local gopls_cmd_name = string.sub(gopls_cmd, #'gopls.' + 1)
cmds[gopls_cmd_name] = function(arg, callback)
-- get gopls client
+ log(arg)
local b = vim.api.nvim_get_current_buf()
local clients = vim.lsp.get_clients({ bufnr = b })
@@ -135,8 +136,19 @@ for _, gopls_cmd in ipairs(gopls_cmds) do
arguments[1].URIs = { uri }
arguments[1].URI = nil
end
- arguments = { vim.tbl_extend('keep', arguments[1], arg or {}) }
+ local behavior = 'keep'
+ if arg.behavior then
+ behavior = arg.behavior
+ arg.behavior = nil
+ end
+ if behavior == 'replace' then
+ arg.behavior = nil
+ arguments = arg
+ else
+ arguments = { vim.tbl_extend(behavior, arguments[1], arg or {}) }
+ end
+ log('arguments', arguments)
log(gopls_cmd_name, arguments)
if vim.tbl_contains(gopls_with_result, gopls_cmd) then
local resp = gopls.request_sync('workspace/executeCommand', {
@@ -206,6 +218,18 @@ M.change_signature = function()
cmds.change_signature(lsp_params)
end
+M.gc_details = function(args)
+ local uri = vim.uri_from_bufnr(0)
+ if args ~= nil then
+ args.URI = args[1]
+ end
+ local lsp_params = {
+ URI = args.URI,
+ behavior = 'replace',
+ }
+ cmds.gc_details(lsp_params)
+end
+
M.list_imports = function(path)
path = path or vim.fn.expand('%:p')
local resp = cmds.list_imports({
@@ -242,8 +266,9 @@ M.list_pkgs = function()
return pkgs
end
-M.package_symbols = function()
- cmds.package_symbols()
+M.package_symbols = function(pkg, render)
+ -- not sure how to add pkg info, leave it empty for now
+ cmds.package_symbols({}, render)
end
M.tidy = function()
@@ -360,6 +385,7 @@ local function get_build_flags()
return nil
end
end
+
local range_format = 'textDocument/rangeFormatting'
local formatting = 'textDocument/formatting'
-- https://cs.opensource.google/go/x/tools/+/master:gopls/internal/protocol/semtok/semtok.go
diff --git a/lua/go/package.lua b/lua/go/package.lua
index 409e345ef..8296dbac4 100644
--- a/lua/go/package.lua
+++ b/lua/go/package.lua
@@ -9,7 +9,7 @@ local pkgs = {}
local complete = function(sep)
log('complete', sep)
sep = sep or '\n'
- local ok, l = golist { util.all_pkgs() }
+ local ok, l = golist({ util.all_pkgs() })
if not ok then
log('Failed to find all packages for current module/project.')
return
@@ -47,7 +47,7 @@ local complete = function(sep)
end
local all_pkgs = function()
- local ok, l = golist { util.all_pkgs() }
+ local ok, l = golist({ util.all_pkgs() })
if not ok then
log('Failed to find all packages for current module/project.')
end
@@ -160,47 +160,39 @@ local show_panel = function(result, pkg, rerender)
end
end
- vim.lsp.buf_request(
- 0,
- 'workspace/symbol',
- { query = "'" .. n.symbol },
- function(e, lsp_result, ctx)
- local filtered = {}
- for _, r in pairs(lsp_result) do
- local container = r.containerName
- if pkg == container and r.name == n.symbol then
- table.insert(filtered, r)
- end
- end
- log('filtered', filtered)
- if #filtered == 0 then
- log('nothing found fallback to result', pkg, n.symbol)
- filtered = lsp_result
+ vim.lsp.buf_request(0, 'workspace/symbol', { query = "'" .. n.symbol }, function(e, lsp_result, ctx)
+ local filtered = {}
+ for _, r in pairs(lsp_result) do
+ local container = r.containerName
+ if pkg == container and r.name == n.symbol then
+ table.insert(filtered, r)
end
+ end
+ log('filtered', filtered)
+ if #filtered == 0 then
+ log('nothing found fallback to result', pkg, n.symbol)
+ filtered = lsp_result
+ end
- if vfn.empty(filtered) == 1 then
- log(e, lsp_result, ctx)
- vim.notify('no symbol found for ' .. vim.inspect(pkg))
- return false
- end
- if #filtered == 1 then
- -- jump to pos
- local loc = filtered[1].location
- local buf = vim.uri_to_bufnr(loc.uri)
- vfn.bufload(buf)
- api.nvim_set_current_win(cur_win)
- api.nvim_set_current_buf(buf)
- api.nvim_win_set_buf(cur_win, buf)
- api.nvim_win_set_cursor(
- cur_win,
- { loc.range.start.line + 1, loc.range.start.character }
- )
- else
- -- lets just call workspace/symbol handler
- vim.lsp.handlers['workspace/symbol'](e, filtered, ctx)
- end
+ if vfn.empty(filtered) == 1 then
+ log(e, lsp_result, ctx)
+ vim.notify('no symbol found for ' .. vim.inspect(pkg))
+ return false
end
- )
+ if #filtered == 1 then
+ -- jump to pos
+ local loc = filtered[1].location
+ local buf = vim.uri_to_bufnr(loc.uri)
+ vfn.bufload(buf)
+ api.nvim_set_current_win(cur_win)
+ api.nvim_set_current_buf(buf)
+ api.nvim_win_set_buf(cur_win, buf)
+ api.nvim_win_set_cursor(cur_win, { loc.range.start.line + 1, loc.range.start.character })
+ else
+ -- lets just call workspace/symbol handler
+ vim.lsp.handlers['workspace/symbol'](e, filtered, ctx)
+ end
+ end)
-- vim.lsp.buf.workspace_symbol("'" .. n.symbol)
return n.symbol
end,
@@ -218,6 +210,73 @@ local show_panel = function(result, pkg, rerender)
os.remove(fname)
end
+local show_pkg_panel = function(result, pkg, rerender)
+ local gopls = require('go.gopls')
+ gopls.package_symbols({}, function(result)
+ -- log('gopls package symbols', result)
+ if not result or vim.tbl_isempty(result) or vim.tbl_isempty(result.Symbols) then
+ vim.notify('no symbols found')
+ return
+ end
+ local files = result.Files
+ local items = {}
+ local kinds = require('guihua.lspkind').symbol_kind
+ for i = 1, #result.Symbols do
+ item = result.Symbols[i]
+ -- items[i].node_text = items[i].detail
+ item.uri =files[(item.file or 0) + 1]
+ item.filename = vim.uri_to_fname(item.uri)
+ item.kind = kinds(item.kind)
+ item.text = item.kind .. item.name
+ item.lnum = item.range.start.line + 1
+
+ table.insert(items, item)
+ if item.children then
+ local prefix = ' ┊ '
+ for j = 1, #item.children do
+ -- if j == 1 then
+ -- prefix = ' '
+ -- else
+ -- prefix = ' '
+ -- end
+ local child = item.children[j]
+ child.lnum = child.range.start.line + 1
+ child.uri = files[(child.file or 0) + 1]
+ child.filename = vim.uri_to_fname(child.uri)
+ child.kind = kinds(child.kind)
+ child.text = prefix .. child.kind .. child.name
+ table.insert(items, child)
+ end
+ end
+ end
+ log('gopls package symbols', items[1])
+ log('gopls package symbols', items[2])
+ log('gopls package symbols', items[3])
+
+ local panel = require('guihua.panel')
+ local log = require('guihua.log').info
+ local p = panel:new({
+ header = ' ' .. result.PackageName .. ' ',
+ render = function(bufnr)
+ log('render for ', bufnr)
+ return items
+ end,
+ -- override format function
+ -- format = function(item)
+ -- return item.indent .. '>' .. item.node_text
+ -- end
+ })
+ log(p)
+ p:open(true)
+ end)
+end
+
+local gopls_pkg_symbols = function()
+ local gopls = require('go.gopls')
+
+end
+
+
local pkg_info = {}
-- get package info
local function handle_data_out(_, data, ev)
@@ -283,6 +342,42 @@ local gen_pkg_info = function(cmd, pkg, arg, rerender)
})
end
+local function symbols_to_items(result)
+ local locations = {}
+ result = result or {}
+ log(#result)
+ for i = 1, #result do
+ local item = result[i].location
+ if item ~= nil and item.range ~= nil then
+ item.kind = result[i].kind
+
+ local kind
+ item.name = result[i].name -- symbol name
+ item.text = result[i].name
+ if kind ~= nil then
+ item.text = kind .. ': ' .. item.text
+ end
+ if not item.filename then
+ item.filename = vim.uri_to_fname(item.uri)
+ end
+ item.display_filename = item.filename:gsub(cwd .. path_sep, path_cur, 1)
+ if item.range == nil or item.range.start == nil then
+ log('range not set', result[i], item)
+ end
+ item.lnum = item.range.start.line + 1
+
+ if item.containerName ~= nil then
+ item.text = ' ' .. item.containerName .. item.text
+ end
+ table.insert(locations, item)
+ end
+ end
+ -- log(locations[1])
+ return locations
+end
+
+
+
outline = function(...)
-- log(debug.traceback())
local arg = select(1, ...)
@@ -360,6 +455,7 @@ return {
all_pkgs2 = all_pkgs2,
pkg_from_path = pkg_from_path,
outline = outline,
+ symbols = show_pkg_panel,
}
--[[