diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a31d32c7..397eed397 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,10 +18,6 @@ jobs: url: https://github.com/neovim/neovim/releases/download/stable/nvim-linux-x86_64.tar.gz manager: sudo snap packages: go - - os: ubuntu-22.04 - url: https://github.com/neovim/neovim/releases/download/v0.10.4/nvim-linux-x86_64.tar.gz - manager: sudo snap - packages: go steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 @@ -51,10 +47,15 @@ jobs: mkdir -p ~/.local/share/nvim/site/pack/vendor/start git clone --depth 1 https://github.com/nvim-lua/plenary.nvim ~/.local/share/nvim/site/pack/vendor/start/plenary.nvim git clone --depth 1 https://github.com/neovim/nvim-lspconfig ~/.local/share/nvim/site/pack/vendor/start/nvim-lspconfig - git clone --depth 1 https://github.com/nvim-treesitter/nvim-treesitter ~/.local/share/nvim/site/pack/vendor/start/nvim-treesitter + git clone --depth 1 -b main https://github.com/nvim-treesitter/nvim-treesitter ~/.local/share/nvim/site/pack/vendor/start/nvim-treesitter + git clone --depth 1 https://github.com/ray-x/guihua.lua ~/.local/share/nvim/site/pack/vendor/start/guihua.lua ln -s $(pwd) ~/.local/share/nvim/site/pack/vendor/start + - name: Compile parsers + run: | + export PATH="${PWD}/_neovim/bin:${PATH}" + nvim -l lua/tests/install-parsers.lua --max-jobs=2 - name: Run tests run: | export PATH="${PWD}/_neovim/bin:${PATH}" - nvim --headless -u lua/tests/minimal.vim -i NONE -c "TSInstallSync go" -c "q" + nvim --headless -u lua/tests/minimal.lua -i NONE -c "TSInstall go" -c "q" make test diff --git a/Makefile b/Makefile index ed9730441..fe4647bec 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,26 @@ PACKER_DIR = ~/.local/share/nvim/site/pack/vendor/start test: - nvim --headless --noplugin -u lua/tests/minimal.vim -c "PlenaryBustedDirectory lua/tests/ {minimal_init = 'lua/tests/minimal.vim'}" + nvim --headless --noplugin -u lua/tests/minimal.lua -c "PlenaryBustedDirectory lua/tests/ {minimal_init = 'lua/tests/minimal.lua'}" localfailed: localtestsetup - nvim --headless --noplugin -u lua/tests/init.vim -c "PlenaryBustedDirectory lua/tests/failed {minimal_init = 'lua/tests/init.vim'}" + nvim --headless --noplugin -u lua/tests/init.lua -c "PlenaryBustedDirectory lua/tests/failed {minimal_init = 'lua/tests/init.lua'}" localtest: localtestsetup - nvim --headless --noplugin -u lua/tests/init.vim -c "PlenaryBustedDirectory lua/tests/ {minimal_init = 'lua/tests/init.vim'}" + nvim --headless --noplugin -u lua/tests/init.lua -c "PlenaryBustedDirectory lua/tests/ {minimal_init = 'lua/tests/init.lua'}" localtestfile: localtestsetup - nvim --headless --noplugin -u lua/tests/init.vim -c "PlenaryBustedFile lua/tests/go_test_spec.lua" + nvim --headless --noplugin -u lua/tests/init.lua -c "PlenaryBustedFile lua/tests/go_test_spec.lua" +localtestts: localtestsetup + nvim --headless --noplugin -u lua/tests/init.lua -c "PlenaryBustedFile lua/tests/go_ts_node_spec.lua" +localtesttag: localtestsetup + nvim --headless --noplugin -u lua/tests/init.lua -c "PlenaryBustedFile lua/tests/go_tags_spec.lua" localtestmod: localtestsetup - nvim --headless --noplugin -u lua/tests/init.vim -c "PlenaryBustedFile lua/tests/go_module_spec.lua" + nvim --headless --noplugin -u lua/tests/init.lua -c "PlenaryBustedFile lua/tests/go_module_spec.lua" +localtestfix: localtestsetup + nvim --headless --noplugin -u lua/tests/init.lua -c "PlenaryBustedFile lua/tests/go_fixplurals_spec.lua" + +localtestgoplsfill: localtestsetup + nvim --headless --noplugin -u lua/tests/init.lua -c "PlenaryBustedFile lua/tests/go_fillstruct_spec.lua" +localtestgoplsimport: localtestsetup + nvim --headless --noplugin -u lua/tests/init.lua -c "PlenaryBustedFile lua/tests/go_gopls_imports_spec.lua" lint: luacheck lua/go clean: @@ -25,12 +36,12 @@ localtestsetup: @test -d $(PACKER_DIR)/nvim-lspconfig ||\ git clone --depth 1 https://github.com/neovim/nvim-lspconfig $(PACKER_DIR)/nvim-lspconfig - @test -d $(PACKER_DIR)/guihua ||\ - git clone --depth 1 https://github.com/ray-x/guihua.lua $(PACKER_DIR)/guihua + @test -d $(PACKER_DIR)/guihua.lua ||\ + git clone --depth 1 https://github.com/ray-x/guihua.lua $(PACKER_DIR)/guihua.lua @test -d $(PACKER_DIR)/nvim-treesitter ||\ - git clone --depth 1 https://github.com/nvim-treesitter/nvim-treesitter $(PACKER_DIR)/nvim-treesitter + git clone --depth 1 -b main https://github.com/nvim-treesitter/nvim-treesitter $(PACKER_DIR)/nvim-treesitter @test -d $(PACKER_DIR)/go.nvim || ln -s ${shell pwd} $(PACKER_DIR) - nvim --headless -u lua/tests/minimal.vim -i NONE -c "TSUpdateSync go" -c "q" + nvim --headless -u lua/tests/minimal.vim -i NONE -c "TSUpdate go" -c "q" diff --git a/README.md b/README.md index dd24042ca..a72bf8dbf 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ The plugin covers most features required for a gopher. ## Installation -Use your favorite package manager to install. The dependency `treesitter` (and optionally, treesitter-objects) should be +Use your favorite package manager to install. The dependency `treesitter` **main** branch (and optionally, treesitter-objects) should be installed the first time you use it. Also Run `TSInstall go` to install the go parser if not installed yet. `sed` is recommended to run this plugin. @@ -58,14 +58,14 @@ recommended to run this plugin. Plug 'nvim-treesitter/nvim-treesitter' Plug 'neovim/nvim-lspconfig' Plug 'ray-x/go.nvim' -Plug 'ray-x/guihua.lua' ; recommended if need floating window support +Plug 'ray-x/guihua.lua' ; required if you using treesitter main branch ``` -### [packer.nvim](https://github.com/wbthomason/packer.nvim) +### [packer.nvim/pckr.nvim](https://github.com/lewis6991/pckr.nvim) ```lua use 'ray-x/go.nvim' -use 'ray-x/guihua.lua' -- recommended if need floating window support +use 'ray-x/guihua.lua' -- required if using treesitter main branch use 'neovim/nvim-lspconfig' use 'nvim-treesitter/nvim-treesitter' ``` @@ -80,11 +80,8 @@ use 'nvim-treesitter/nvim-treesitter' "neovim/nvim-lspconfig", "nvim-treesitter/nvim-treesitter", }, - opts = { - -- lsp_keymaps = false, - -- other options - }, - config = function(lp, opts) + opts = function() + require("go").setup(opts) local format_sync_grp = vim.api.nvim_create_augroup("GoFormat", {}) vim.api.nvim_create_autocmd("BufWritePre", { @@ -94,6 +91,10 @@ use 'nvim-treesitter/nvim-treesitter' end, group = format_sync_grp, }) + return { + -- lsp_keymaps = false, + -- other options + } end, event = {"CmdlineEnter"}, ft = {"go", 'gomod'}, @@ -850,6 +851,8 @@ require('go').setup({ -- signs = {'๎ช‡', '๎ฉฌ', '๎ฉด', '๏„ฉ'}, -- set to true to use default signs, an array of 4 to specify custom signs -- update_in_insert = false, -- }, + -- set to false/nil: disable config gopls diagnostic + -- if you need to setup your ui for input and select, you can do it here -- go_input = require('guihua.input').input -- set to vim.ui.input to disable guihua input -- go_select = require('guihua.select').select -- vim.ui.select to disable guihua select diff --git a/init.lua b/init.lua new file mode 100644 index 000000000..c7032eeb6 --- /dev/null +++ b/init.lua @@ -0,0 +1,68 @@ +-- Define the plugin directory variable (s:plugin_dir in VimScript) +local plugin_dir = vim.fn.expand('~/.local/share/nvim/site/pack/vendor/start') + +-- set rtp+=. +vim.opt.rtp:append('.') + +-- execute 'set rtp^=' . s:plugin_dir . '/plenary.nvim' +-- execute 'set rtp^=' . s:plugin_dir . '/nvim-treesitter' +-- execute 'set rtp^=' . s:plugin_dir . '/nvim-lspconfig' +vim.opt.rtp:prepend(plugin_dir .. '/plenary.nvim') +vim.opt.rtp:prepend(plugin_dir .. '/nvim-treesitter') +vim.opt.rtp:prepend(plugin_dir .. '/nvim-lspconfig') + +-- runtime! plugin/plenary.vim +-- runtime! plugin/nvim-treesitter.vim +-- runtime! plugin/playground.vim +-- runtime! plugin/nvim-lspconfig.vim +vim.cmd('runtime! plugin/plenary.vim') +vim.cmd('runtime! plugin/nvim-treesitter.vim') +vim.cmd('runtime! plugin/playground.vim') +vim.cmd('runtime! plugin/nvim-lspconfig.vim') + +-- Option settings (set noswapfile, set nobackup, etc.) +vim.opt.swapfile = false +vim.opt.backup = false +vim.opt.writebackup = false +vim.opt.autoindent = false +vim.opt.cindent = false +vim.opt.smartindent = false +vim.opt.indentexpr = '' +vim.opt.shada = 'NONE' + +-- filetype indent off +vim.cmd('filetype indent off') + +-- Lua configuration block +_G.test_rename = true +_G.test_close = true + +-- require("plenary/busted") +require('plenary.busted') + +-- require("go").setup({...}) +require('go').setup({ + gofmt = 'gofumpt', + goimports = 'goimports', + verbose = true, + log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', + lsp_cfg = true, +}) + +vim.lsp.enable('gopls') + +require('nvim-treesitter').setup({ + -- Directory to install parsers and queries to + install_dir = vim.fn.stdpath('data') .. '/site', +}) + +vim.api.nvim_create_autocmd('FileType', { + pattern = { 'go' }, + callback = function() + local queries = require('nvim-treesitter.config').get_installed('queries') + if not vim.tbl_contains(queries, 'go') then + error('No queries for go found') + end + pcall(vim.treesitter.start) + end, +}) diff --git a/lua/go.lua b/lua/go.lua index e71db61d7..65793ebc9 100644 --- a/lua/go.lua +++ b/lua/go.lua @@ -5,6 +5,7 @@ local vfn = vim.fn -- Keep this in sync with README.md -- Keep this in sync with doc/go.txt _GO_NVIM_CFG = { + treesitter_main = false, disable_defaults = false, -- true|false when true disable all default settings, user need to set all settings remap_commands = {}, -- Vim commands to remap or disable, e.g. `{ GoFmt = "GoFormat", GoDoc = false }` go = 'go', -- set to go1.18beta1 if necessary @@ -74,6 +75,8 @@ _GO_NVIM_CFG = { severity = vim.diagnostic.severity.WARN, -- severity level of the diagnostics }, }, + diagnostic = false, -- set to false to disable diagnostic setup from go.nvim + --[[ diagnostic = { -- set diagnostic to false to disable diagnostic hdlr = false, -- hook diagnostic handler and send error to quickfix underline = true, @@ -84,7 +87,7 @@ _GO_NVIM_CFG = { -- signs = { -- text = { '๐Ÿš‘', '๐Ÿ”ง', '๐Ÿช›', '๐Ÿงน' }, -- }, - }, + }, --]] go_input = function() if require('go.utils').load_plugin('guihua.lua', 'guihua.gui') then return require('guihua.input').input @@ -210,6 +213,10 @@ function go.setup(cfg) } end + -- ts master branch use nvim-treesitter.configs + -- ts main branch use nvim-treesitter.config + local has_ts_main = pcall(require, 'nvim-treesitter.config') + _GO_NVIM_CFG.treesitter_main = has_ts_main -- legacy options if type(cfg.null_ls) == 'boolean' then vim.notify('go.nvim config: null_ls=boolean deprecated, refer to README for more info', vim.log.levels.WARN) @@ -274,11 +281,14 @@ function go.setup(cfg) else -- we do not setup diagnostic from go.nvim -- use whatever user has setup - _GO_NVIM_CFG.diagnostic = {} + _GO_NVIM_CFG.diagnostic = nil end else - local dcfg = vim.tbl_extend('force', {}, _GO_NVIM_CFG.diagnostic) - vim.diagnostic.config(dcfg) + -- vim.notify('go.nvim diagnostic setup deprecated, use vim.diagnostic instead', vim.log.levels.DEBUG) + if next(_GO_NVIM_CFG.diagnostic or {}) then + local dcfg = vim.tbl_extend('force', {}, _GO_NVIM_CFG.diagnostic) + vim.diagnostic.config(dcfg) + end end vim.defer_fn(function() require('go.coverage').setup() @@ -334,4 +344,8 @@ go.set_test_runner = function(runner) vim.notify('runner not supported ' .. runner, vim.log.levels.ERROR) end +go.config = function() + return _GO_NVIM_CFG +end + return go diff --git a/lua/go/comment.lua b/lua/go/comment.lua index 831e87828..36f93f184 100644 --- a/lua/go/comment.lua +++ b/lua/go/comment.lua @@ -2,48 +2,53 @@ -- for func name(args) rets {} -- add cmts // name : rets local comment = {} -local placeholder = _GO_NVIM_CFG.comment_placeholder or "" -local ulog = require("go.utils").log -local api = vim.api +local placeholder = _GO_NVIM_CFG.comment_placeholder or '' +local ulog = require('go.utils').log +local api = vim.api + +local ok, ts_utils = pcall(require, 'nvim-treesitter.ts_utils') +if not ok then + ts_utils = require('guihua.ts_obsolete.ts_utils') +end local gen_comment = function() local comments = nil - local ns = require("go.ts.go").get_package_node_at_pos() + local ns = require('go.ts.go').get_package_node_at_pos() if ns ~= nil and ns ~= {} then -- ulog("parnode" .. vim.inspect(ns)) - comments = "// Package " .. ns.name .. " provides " .. ns.name + comments = '// Package ' .. ns.name .. ' provides ' .. ns.name return comments, ns end - ns = require("go.ts.go").get_func_method_node_at_pos() + ns = require('go.ts.go').get_func_method_node_at_pos() if ns ~= nil and ns ~= {} then -- ulog("parnode" .. vim.inspect(ns)) - comments = "// " .. ns.name .. " " .. ns.type + comments = '// ' .. ns.name .. ' ' .. ns.type return comments, ns end - ns = require("go.ts.go").get_struct_node_at_pos() + ns = require('go.ts.go').get_struct_node_at_pos() if ns ~= nil and ns ~= {} then - comments = "// " .. ns.name .. " " .. ns.type + comments = '// ' .. ns.name .. ' ' .. ns.type return comments, ns end - ns = require("go.ts.go").get_interface_node_at_pos() + ns = require('go.ts.go').get_interface_node_at_pos() if ns ~= nil and ns ~= {} then -- ulog("parnode" .. vim.inspect(ns)) - comments = "// " .. ns.name .. " " .. ns.type + comments = '// ' .. ns.name .. ' ' .. ns.type return comments, ns end - ns = require("go.ts.go").get_type_node_at_pos() + ns = require('go.ts.go').get_type_node_at_pos() if ns ~= nil and ns ~= {} then -- ulog("parnode" .. vim.inspect(ns)) - comments = "// " .. ns.name .. " " .. ns.type + comments = '// ' .. ns.name .. ' ' .. ns.type return comments, ns end - return "" + 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 + return comment_line .. ' ' .. placeholder, ns end return comment_line, ns end @@ -55,14 +60,13 @@ comment.gen = function() local bufnr = api.nvim_get_current_buf() if ns == nil then -- nothing found - local ts_utils = require("nvim-treesitter.ts_utils") ns = ts_utils.get_node_at_cursor() - local node_text = require("go.utils").get_node_text(ns, bufnr) + local node_text = require('go.utils').get_node_text(ns, bufnr) local line = api.nvim_get_current_line() - local regex = "^(%s+)" + local regex = '^(%s+)' local q = line:match(regex) - c = (q or "") .. "// " .. node_text + c = (q or '') .. '// ' .. node_text c, _ = wrap_comment(c, {}) vim.fn.append(row - 1, c) vim.fn.cursor(row, #c + 1) @@ -70,14 +74,14 @@ comment.gen = function() end ulog(vim.inspect(ns)) row, col = ns.dim.s.r, ns.dim.s.c - ulog("set cursor " .. tostring(row)) + ulog('set cursor ' .. tostring(row)) 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 - api.nvim_command("startinsert!") + api.nvim_command('startinsert!') return c end diff --git a/lua/go/fixplurals.lua b/lua/go/fixplurals.lua index b959a41e5..f06da2d0d 100644 --- a/lua/go/fixplurals.lua +++ b/lua/go/fixplurals.lua @@ -1,33 +1,35 @@ -- lua implementation of the fixplurals -local ts_utils = require("nvim-treesitter.ts_utils") - -local info = require("go.utils").info +local ok, ts_utils = pcall(require, 'nvim-treesitter.ts_utils') +if not ok then + ts_utils = require('guihua.ts_obsolete.ts_utils') +end +local info = require('go.utils').info local get_node_text = vim.treesitter.get_node_text local function fixplurals() local n = ts_utils.get_node_at_cursor() if not n then - return info("no node found") + return info('no node found') end local p = n:parent() - if p:type() ~= "parameter_declaration" then - return info("not in parameter declaration") + if p:type() ~= 'parameter_declaration' then + return info('not in parameter declaration') end if p:named_child_count() ~= 2 then - return info("no plural parameter") + return info('no plural parameter') end local type_node = p:named_child(1) local type = get_node_text(type_node, 0) local edits = {} while ts_utils.get_next_node(p) ~= nil do local next_node = ts_utils.get_next_node(p) - if next_node:type() == "parameter_declaration" then + if next_node:type() == 'parameter_declaration' then local type_node2 = next_node:named_child(1) local type_next = get_node_text(type_node2, 0) if type == type_next then local range1 = ts_utils.node_to_lsp_range(p:named_child(1)) - range1["start"]["character"] = range1["start"]["character"] - 1 - local edit1 = { range = range1, newText = "" } + range1['start']['character'] = range1['start']['character'] - 1 + local edit1 = { range = range1, newText = '' } table.insert(edits, 1, edit1) end @@ -38,9 +40,9 @@ local function fixplurals() end if #edits == 0 then - return info("no plural parameter") + return info('no plural parameter') end local bufnr = vim.api.nvim_get_current_buf() - vim.lsp.util.apply_text_edits(edits, bufnr, "utf-8") + vim.lsp.util.apply_text_edits(edits, bufnr, 'utf-8') end return { fixplurals = fixplurals } diff --git a/lua/go/ginkgo.lua b/lua/go/ginkgo.lua index 413457086..2fad60321 100644 --- a/lua/go/ginkgo.lua +++ b/lua/go/ginkgo.lua @@ -12,7 +12,13 @@ local long_opts = { floaterm = 'F', } local ts = vim.treesitter -local parsers = require('nvim-treesitter.parsers') + +local parsers +if _GO_NVIM_CFG.treesitter_main then + parsers = require('guihua.ts_obsolete.parsers') +else + parsers = require('nvim-treesitter.parsers') +end local getopt = require('go.alt_getopt') local short_opts = 'vct:bsF' @@ -44,7 +50,7 @@ local function find_nearest_test_case() local query = require('go.ts.go').ginkgo_query local bufnr = vim.api.nvim_get_current_buf() - local parser = parsers.get_parser(bufnr, 'go') + local parser = vim.treesitter.get_parser(bufnr, 'go') if not parser then log('no parser found') return diff --git a/lua/go/gopls.lua b/lua/go/gopls.lua index beca2bec9..d6c7ddaa1 100644 --- a/lua/go/gopls.lua +++ b/lua/go/gopls.lua @@ -27,10 +27,12 @@ local gopls_cmds = { 'gopls.gc_details', 'gopls.generate', 'gopls.go_get_package', + 'gopls.lsp', 'gopls.list_imports', 'gopls.list_known_packages', 'gopls.maybe_prompt_for_telemetry', 'gopls.mem_stats', + 'gopls.modify_tags', 'gopls.modules', 'gopls.package_symbols', 'gopls.packages', @@ -41,6 +43,7 @@ local gopls_cmds = { 'gopls.run_govulncheck', 'gopls.run_tests', 'gopls.scan_imports', + 'gopls.split_package', 'gopls.start_debugging', 'gopls.start_profile', 'gopls.stop_profile', diff --git a/lua/go/health.lua b/lua/go/health.lua index a26653c9f..634658e14 100644 --- a/lua/go/health.lua +++ b/lua/go/health.lua @@ -148,12 +148,18 @@ local function plugin_check() end end if ts_installed then - local _info = require('nvim-treesitter.info').installed_parsers() - if vim.tbl_contains(_info, 'go') then - ok('nvim-treesitter-go is installed') + local has_ts_main = pcall(require, 'nvim-treesitter.config') + if has_ts_main then + any_warn = false + warn('nvim-treesitter main module loaded, WIP') else - warn('nvim-treesitter-go is not installed, Please run TSInstall go to install') - any_warn = true + local _info = require('nvim-treesitter.info').installed_parsers() + if vim.tbl_contains(_info, 'go') then + ok('nvim-treesitter-go is installed') + else + warn('nvim-treesitter-go is not installed, Please run TSInstall go to install') + any_warn = true + end end end plugins = { diff --git a/lua/go/impl.lua b/lua/go/impl.lua index cf3ef4e12..7761e7c17 100644 --- a/lua/go/impl.lua +++ b/lua/go/impl.lua @@ -1,4 +1,3 @@ --- local ts_utils = require 'nvim-treesitter.ts_utils' local utils = require('go.utils') local log = utils.log local vfn = vim.fn @@ -61,9 +60,7 @@ local run = function(...) end vim.cmd('redraw!') if iface == '' then - utils.notify( - 'Impl: please input interface name e.g. io.Reader or receiver name e.g. GoImpl MyType' - ) + utils.notify('Impl: please input interface name e.g. io.Reader or receiver name e.g. GoImpl MyType') -- print("Usage: GoImpl f *File io.Reader") end elseif #arg == 1 then -- at least interface or type are specified diff --git a/lua/go/mockgen.lua b/lua/go/mockgen.lua index b4d806551..686a362e2 100644 --- a/lua/go/mockgen.lua +++ b/lua/go/mockgen.lua @@ -1,4 +1,3 @@ --- local ts_utils = require 'nvim-treesitter.ts_utils' local utils = require('go.utils') local log = utils.log local vfn = vim.fn diff --git a/lua/go/runner.lua b/lua/go/runner.lua index 7978e2c41..c86f3e103 100644 --- a/lua/go/runner.lua +++ b/lua/go/runner.lua @@ -61,11 +61,11 @@ local run = function(cmd, opts, uvopts) end log(locopts) if opts.setloclist ~= false then - vim.schedule(function() - vim.fn.setloclist(0, {}, 'a', locopts) - vim.notify('run lopen to see output', vim.log.levels.INFO) - end) - end + vim.schedule(function() + vim.fn.setloclist(0, {}, 'a', locopts) + vim.notify('run lopen to see output', vim.log.levels.INFO) + end) + end end return lines end @@ -135,11 +135,7 @@ local run = function(cmd, opts, uvopts) log('failed to run', code, output_buf, output_stderr) vim.schedule(function() util.info( - cmd_str - .. ' exit with code: ' - .. tostring(code or 0) - .. (output_buf or '') - .. (output_stderr or '') + cmd_str .. ' exit with code: ' .. tostring(code or 0) .. (output_buf or '') .. (output_stderr or '') ) end) end diff --git a/lua/go/snips.lua b/lua/go/snips.lua index 42becb0c9..b592e051f 100644 --- a/lua/go/snips.lua +++ b/lua/go/snips.lua @@ -1,22 +1,14 @@ -- first version: from https://github.com/arsham/shark local ls = require('luasnip') local fmt = require('luasnip.extras.fmt').fmt +local ts_locals local ok, ts_utils = pcall(require, 'nvim-treesitter.ts_utils') if not ok then - local ok, packer = pcall(require, 'packer') - if ok then - require('packer').loader('nvim-treesitter') - else - local ok, lazy = pcall(require, 'lazy') - if lazy then - lazy.load({ plugins = { 'nvim-treesitter' } }) - else - error('Please install nvim-treesitter') - end - end - ts_utils = require('nvim-treesitter.ts_utils') + ts_utils = require('guihua.ts_obsolete.ts_utils') + ts_locals = require('guihua.ts_obsolete.locals') +else + ts_locals = require('nvim-treesitter.locals') end -local ts_locals = require('nvim-treesitter.locals') local rep = require('luasnip.extras').rep local ai = require('luasnip.nodes.absolute_indexer') @@ -25,7 +17,7 @@ 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 "" + local msg = spec and spec[1] or '' if spec and spec[2] then err_name = err_name .. spec[2] end @@ -158,10 +150,11 @@ local function return_value_nodes(info) local function_node for _, scope in ipairs(scope_tree) do - if scope:type() == 'function_declaration' - or scope:type() == 'method_declaration' - or scope:type() == 'method_declaration' - or scope:type() == 'func_literal' + if + scope:type() == 'function_declaration' + or scope:type() == 'method_declaration' + or scope:type() == 'method_declaration' + or scope:type() == 'func_literal' then function_node = scope break diff --git a/lua/go/tags.lua b/lua/go/tags.lua index 27b7bc01f..0595f9b7b 100644 --- a/lua/go/tags.lua +++ b/lua/go/tags.lua @@ -11,8 +11,8 @@ local tags = {} -- gomodifytags -file demo.go -line 8,11 -clear-tags xml local gomodify = 'gomodifytags' -local transform = _GO_NVIM_CFG.tag_transform -local options = _GO_NVIM_CFG.tag_options +local transform = require('go').config().tag_transform +local options = require('go').config().tag_options tags.modify = function(...) require('go.install').install(gomodify) diff --git a/lua/go/ts/go.lua b/lua/go/ts/go.lua index 33bef1450..e6c0da8af 100644 --- a/lua/go/ts/go.lua +++ b/lua/go/ts/go.lua @@ -1,35 +1,34 @@ local nodes = require('go.ts.nodes') -local tsutil = require('nvim-treesitter.ts_utils') local log = require('go.utils').log local warn = require('go.utils').warn local info = require('go.utils').info local debug = require('go.utils').debug local trace = require('go.utils').trace -local api = vim.api -local parsers = require "nvim-treesitter.parsers" -local utils = require "nvim-treesitter.utils" -local ts = vim.treesitter local 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_struct_block_type = [[((type_spec name:(type_identifier) @struct.name type: (struct_type))@struct.declaration)]], -- type(struct1, struct2) + query_struct_block = + [[((type_declaration (type_spec name:(type_identifier) @struct.name type: (struct_type)))@struct.declaration)]], + query_struct_block_type = [[((type_spec name:(type_identifier) @struct.name type: (struct_type))@struct.declaration)]], -- type(struct1, struct2) -- query_type_declaration = [[((type_declaration (type_spec name:(type_identifier)@type_decl.name type:(type_identifier)@type_decl.type))@type_decl.declaration)]], -- rename to gotype so not confuse with type query_type_declaration = [[((type_declaration (type_spec name:(type_identifier)@type_decl.name)))]], - query_em_struct_block = [[(field_declaration name:(field_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_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_interface_method = [[((method_elem name: (field_identifier)@method.name)@interface.method.declaration)]], -- -- this is a breaking change require TS parser update 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 = + '(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 @@ -258,11 +257,10 @@ M.get_tbl_testcase_node_name = function(bufnr) end end for _, node in pairs(nodes) do - local n = get_tc_block(node, function(start_row, end_row, curr_row) if (start_row <= curr_row and curr_row <= end_row) then -- curr_row starts from 1 - trace('valid node:', node) -- the nvim manual is out of sync for release version - return true -- cursor is in the same line, this is a strong match + trace('valid node:', node) -- the nvim manual is out of sync for release version + return true -- cursor is in the same line, this is a strong match end end) if n then @@ -272,15 +270,15 @@ M.get_tbl_testcase_node_name = function(bufnr) local start_row, _, end_row, _ = node:range() local result = {} -- find kv nodes inside test case struct - for pattern2, match2, _ in tbl_case_kv_query:iter_matches(tree:root(), bufn, start_row, end_row+1) do + for pattern2, match2, _ in tbl_case_kv_query:iter_matches(tree:root(), bufn, start_row, end_row + 1) do local id for i2, nodes2 in pairs(match2) do local name2 = tbl_case_kv_query.captures[i2] -- or tbl_case_kv_query.captures[pattern2] - for i, n2 in pairs(nodes2) do -- the order is abit random + for i, n2 in pairs(nodes2) do -- the order is abit random -- if name2 == 'test.name' then local start_row2, _, end_row2, _ = n2:range() if name2 == 'test.nameid' then - id = vim.treesitter.get_node_text(n2, bufn) + id = vim.treesitter.get_node_text(n2, bufn) if id == 'name' then result[name2] = id end @@ -296,7 +294,7 @@ M.get_tbl_testcase_node_name = function(bufnr) trace('found node', name2, n2:range()) end - trace('node type name',i2, i, name2, id, start_row2, end_row2, curr_row, tc_name, guess) + trace('node type name', i2, i, name2, id, start_row2, end_row2, curr_row, tc_name, guess) end end end @@ -332,7 +330,7 @@ M.get_sub_testcase_name = function(bufnr) -- tc_run is the first capture of a match, so we can use it to check if we are inside a test if name == 'tc.run' then local start_row, _, end_row, _ = node:range() - if (start_row < curr_row and curr_row <= end_row + 1) then + if (start_row < curr_row and curr_row <= end_row + 1) then is_inside_test = true else is_inside_test = false @@ -340,7 +338,6 @@ M.get_sub_testcase_name = function(bufnr) goto continue end if name == 'tc.name' and is_inside_test then - return string.gsub(vim.treesitter.get_node_text(node, bufn), '"', '') end ::continue:: @@ -363,6 +360,14 @@ end M.get_import_node_at_pos = function(bufnr) bufnr = bufnr or vim.api.nvim_get_current_buf() + local ok, tsutil = pcall(require, 'nvim-treesitter.ts_utils') + if not ok then + ok, tsutil = pcall(require, 'guihua.ts_obsolete.ts_utils') + if not ok then + warn('ts_utils not found') + return + end + end local cur_node = tsutil.get_node_at_cursor(0, true) if not cur_node then vim.notify('cursor not in a node or TS parser not init correctly', vim.log.levels.INFO) @@ -420,7 +425,11 @@ end function M.in_func() local ok, ts_utils = pcall(require, 'nvim-treesitter.ts_utils') if not ok then - return false + ok, ts_utils = pcall(require, 'guihua.ts_obsolete.ts_utils') + if not ok then + warn('ts_utils not found') + return false + end end local current_node = ts_utils.get_node_at_cursor() if not current_node then diff --git a/lua/go/ts/nodes.lua b/lua/go/ts/nodes.lua index 642d02163..5b1188fe6 100644 --- a/lua/go/ts/nodes.lua +++ b/lua/go/ts/nodes.lua @@ -1,8 +1,18 @@ -- 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 has_ts_main = pcall(require, 'nvim-treesitter.config') + +local ts_utils, ts_query, locals, parsers +if has_ts_main then + ts_utils = require('guihua.ts_obsolete.ts_utils') + ts_query = require('guihua.ts_obsolete.query') + locals = require('guihua.ts_obsolete.locals') + parsers = require('guihua.ts_obsolete.parsers') +else + ts_utils = require('nvim-treesitter.ts_utils') + ts_query = require('nvim-treesitter.query') + locals = require('nvim-treesitter.locals') + parsers = require('nvim-treesitter.parsers') +end local utils = require('go.ts.utils') local goutil = require('go.utils') local ulog = require('go.utils').log @@ -17,7 +27,7 @@ if parse == nil then parse = vim.treesitter.query.parse_query end -if not _GO_NVIM_CFG.verbose_ts then +if _GO_NVIM_CFG and not _GO_NVIM_CFG.verbose_ts then ulog = function() end end @@ -79,7 +89,7 @@ M.get_nodes = function(query, lang, defaults, bufnr) return nil end - local parser = parsers.get_parser(bufnr, lang) + local parser = vim.treesitter.get_parser(bufnr, lang) local root = parser:parse()[1]:root() local start_row, _, end_row, _ = root:range() local results = {} @@ -149,7 +159,7 @@ M.get_all_nodes = function(query, lang, defaults, bufnr, pos_row, pos_col, ntype return nil end - local parser = parsers.get_parser(bufnr, lang) + local parser = vim.treesitter.get_parser(bufnr, lang) local root = parser:parse()[1]:root() local start_row, _, end_row, _ = root:range() local results = {} @@ -176,7 +186,7 @@ M.get_all_nodes = function(query, lang, defaults, bufnr, pos_row, pos_col, ntype if #dbg_txt > 100 then dbg_txt = string.sub(dbg_txt, 1, 100) .. '...' end - type = string.sub(path, 1, idx - 1) -- e.g. struct.name, type is struct + type = string.sub(path, 1, idx - 1) -- e.g. struct.name, type is struct if type:find('type') and op == 'type' then -- type_declaration.type node_type = get_node_text(node, bufnr) ulog('type: ' .. type) @@ -185,8 +195,8 @@ M.get_all_nodes = function(query, lang, defaults, bufnr, pos_row, pos_col, ntype -- stylua: ignore ulog( "node ", vim.inspect(node), "\n path: " .. path .. " op: " .. op - .. " type: " .. type .. "\n txt: " .. dbg_txt .. "\n range: " .. tostring(a1 or 0) - .. ":" .. tostring(b1 or 0) .. " TO " .. tostring(c1 or 0) .. ":" .. tostring(d1 or 0) + .. " type: " .. type .. "\n txt: " .. dbg_txt .. "\n range: " .. tostring(a1 or 0) + .. ":" .. tostring(b1 or 0) .. " TO " .. tostring(c1 or 0) .. ":" .. tostring(d1 or 0) ) -- stylua: ignore end -- @@ -197,8 +207,7 @@ M.get_all_nodes = function(query, lang, defaults, bufnr, pos_row, pos_col, ntype type_node = node elseif op == 'declaration' or op == 'clause' then declaration_node = node - sRow, sCol, eRow, eCol = - ts_utils.get_vim_range({ vim.treesitter.get_node_range(node) }, bufnr) + sRow, sCol, eRow, eCol = ts_utils.get_vim_range({ vim.treesitter.get_node_range(node) }, bufnr) else ulog('unknown op: ' .. op) end @@ -219,8 +228,7 @@ M.get_all_nodes = function(query, lang, defaults, bufnr, pos_row, pos_col, ntype end if type_node ~= nil and ntype then ulog('type_only') - sRow, sCol, eRow, eCol = - ts_utils.get_vim_range({ vim.treesitter.get_node_range(type_node) }, bufnr) + sRow, sCol, eRow, eCol = ts_utils.get_vim_range({ vim.treesitter.get_node_range(type_node) }, bufnr) table.insert(results, { type_node = type_node, dim = { s = { r = sRow, c = sCol }, e = { r = eRow, c = eCol } }, @@ -263,10 +271,7 @@ M.nodes_at_cursor = function(query, default, bufnr, ntype) end local ns = M.get_all_nodes(query, ft, default, bufnr, row, col, ntype) if ns == nil then - vim.notify( - 'Unable to find any nodes. place your cursor on a go symbol and try again', - vim.log.levels.DEBUG - ) + vim.notify('Unable to find any nodes. place your cursor on a go symbol and try again', vim.log.levels.DEBUG) ulog('Unable to find any nodes. place your cursor on a go symbol and try again') return nil end @@ -282,10 +287,7 @@ M.nodes_at_cursor = function(query, default, bufnr, ntype) ulog(row, col, vim.inspect(nodes_at_cursor):sub(1, 100)) if nodes_at_cursor == nil or #nodes_at_cursor == 0 then if _GO_NVIM_CFG.verbose then - vim.notify( - 'Unable to find any nodes at pos. ' .. tostring(row) .. ':' .. tostring(col), - vim.log.levels.DEBUG - ) + vim.notify('Unable to find any nodes at pos. ' .. tostring(row) .. ':' .. tostring(col), vim.log.levels.DEBUG) end ulog('Unable to find any nodes at pos. ' .. tostring(row) .. ':' .. tostring(col)) return nil diff --git a/lua/go/ts/textobjects.lua b/lua/go/ts/textobjects.lua index 2a840cf9b..c833914a2 100644 --- a/lua/go/ts/textobjects.lua +++ b/lua/go/ts/textobjects.lua @@ -1,17 +1,18 @@ -local util = require("go.utils") +local util = require('go.utils') local plugins = util.load_plugin local M = {} function M.setup() - if not plugins("nvim-treesitter") then - util.log("treesitter not avalible") + if not plugins('nvim-treesitter') then + util.log('treesitter not avalible') return end local ok, configs = pcall(require, 'nvim-treesitter.configs') if not ok then - configs = require('nvim-treesitter') + -- treesitter main no longer provides textobjects by default + return end configs.setup({ @@ -21,26 +22,26 @@ function M.setup() lookahead = true, keymaps = { -- You can use the capture groups defined in textobjects.scm - ["af"] = "@function.outer", - ["if"] = "@function.inner", - ["ac"] = "@class.outer", - ["ic"] = "@class.inner", + ['af'] = '@function.outer', + ['if'] = '@function.inner', + ['ac'] = '@class.outer', + ['ic'] = '@class.inner', }, }, move = { enable = true, set_jumps = true, -- whether to set jumps in the jumplist goto_next_start = { - ["]]"] = "@function.outer", + [']]'] = '@function.outer', }, goto_next_end = { - ["]["] = "@function.outer", + [']['] = '@function.outer', }, goto_previous_start = { - ["[["] = "@function.outer", + ['[['] = '@function.outer', }, goto_previous_end = { - ["[]"] = "@function.outer", + ['[]'] = '@function.outer', }, }, }, diff --git a/lua/go/ts/utils.lua b/lua/go/ts/utils.lua index 9628f4e0d..21fcb242e 100644 --- a/lua/go/ts/utils.lua +++ b/lua/go/ts/utils.lua @@ -1,7 +1,15 @@ local api = vim.api local get_node_text = vim.treesitter.get_node_text -local ts_utils = require('nvim-treesitter.ts_utils') +local ts_utils, locals +local has_ts_main = pcall(require, 'nvim-treesitter.config') +if has_ts_main then + ts_utils = require('guihua.ts_obsolete.ts_utils') + locals = require('guihua.ts_obsolete.locals') +else + ts_utils = require('nvim-treesitter.ts_utils') + locals = require('nvim-treesitter.locals') +end local util = require('go.utils') local log = util.log local trace = util.trace @@ -26,7 +34,6 @@ M.intersects = function(row, col, sRow, sCol, eRow, eCol) return true end -local locals = require('nvim-treesitter.locals') -- from navigator/treesitter.lua -- modified from nvim-treesitter/treesitter-refactor plugin -- Get definitions of bufnr (unique and sorted by order of appearance). @@ -44,9 +51,9 @@ local function get_definitions(bufnr) local _, _, start = node:start() -- variadic_parameter_declaration if - node - and node:parent() - and string.find(node:parent():type(), 'parameter_declaration') + node + and node:parent() + and string.find(node:parent():type(), 'parameter_declaration') then trace('parameter_declaration skip') return @@ -67,7 +74,7 @@ local function get_definitions(bufnr) locals.recurse_local_nodes(loc.interface, function(def, node, full_match, match) local k, l, start = node:start() -- stylua: ignore start - trace( k, l, start, def, node, full_match, match, node:parent(), node:parent():start(), node:parent():type()) + trace(k, l, start, def, node, full_match, match, node:parent(), node:parent():start(), node:parent():type()) -- stylua: ignore end if nodes_set[start] == nil then nodes_set[start] = { node = node, type = match or '' } @@ -79,7 +86,7 @@ local function get_definitions(bufnr) local k, l, start = node:start() -- stylua: ignore start - trace( k, l, start, def, node, full_match, match, node:parent(), node:parent():start(), node:parent():type()) + trace(k, l, start, def, node, full_match, match, node:parent(), node:parent():start(), node:parent():type()) -- stylua: ignore end if nodes_set[start] == nil then -- if node:parent() and node:parent():type() == "field_declaration" then @@ -87,11 +94,11 @@ local function get_definitions(bufnr) -- return -- end -- qualified_type : e.g. io.Reader inside interface if - node:parent() - and node:parent():parent() - and node:type() == 'type_identifier' - and node:parent():type() == 'qualified_type' - and string.find(node:parent():parent():type(), 'interface') + node:parent() + and node:parent():parent() + and node:type() == 'type_identifier' + and node:parent():type() == 'qualified_type' + and string.find(node:parent():parent():type(), 'interface') then nodes_set[start] = { node = node, type = 'interface' } end @@ -146,8 +153,8 @@ function M.list_definitions_toc(bufnr) local index = n + 1 - i local parent_def = parents[index] if - ts_utils.is_parent(parent_def.node, def.node) - or (containers[parent_def.type] and ts_utils.is_parent(parent_def.node:parent(), def.node)) + ts_utils.is_parent(parent_def.node, def.node) + or (containers[parent_def.type] and ts_utils.is_parent(parent_def.node:parent(), def.node)) then break else diff --git a/lua/tests/go_comment_spec.lua b/lua/tests/go_comment_spec.lua index 6d731b90f..a763edf53 100644 --- a/lua/tests/go_comment_spec.lua +++ b/lua/tests/go_comment_spec.lua @@ -3,9 +3,13 @@ local eq = assert.are.same local busted = require('plenary/busted') local cur_dir = vim.fn.expand('%:p:h') describe('should get nodes ', function() + local queries = require('nvim-treesitter.config').get_installed('queries') + if not vim.tbl_contains(queries, 'go') then + error('No queries for go found') + end + _GO_NVIM_CFG.verbose = true _GO_NVIM_CFG.comment_placeholder = ' ๎˜ง ' - local status = require('plenary.reload').reload_module('go.nvim') status = require('plenary.reload').reload_module('nvim-treesitter/nvim-treesitter') diff --git a/lua/tests/go_coverage_spec.lua b/lua/tests/go_coverage_spec.lua index 297dada84..9e5bf8fb6 100644 --- a/lua/tests/go_coverage_spec.lua +++ b/lua/tests/go_coverage_spec.lua @@ -1,71 +1,72 @@ local eq = assert.are.same -local cur_dir = vim.fn.expand("%:p:h") -local busted = require("plenary/busted") +local cur_dir = vim.fn.expand('%:p:h') +local busted = require('plenary/busted') -describe("should read coveragefile", function() +describe('should read coveragefile', function() -- vim.fn.readfile('minimal.vim') -- vim.fn.writefile(vim.fn.readfile('fixtures/fmt/hello.go'), name) - local status = require("plenary.reload").reload_module("go.nvim") - it("should read coverage file", function() + local status = require('plenary.reload').reload_module('go.nvim') + it('should read coverage file', function() -- - local path = cur_dir .. "/lua/tests/fixtures/coverage/coverage.out" -- %:p:h ? %:p - print("test:" .. path) + local path = cur_dir .. '/lua/tests/fixtures/coverage/coverage.out' -- %:p:h ? %:p + print('test:' .. path) -- go.nvim may not auto loaded vim.cmd([[packadd go.nvim]]) require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand("$HOME") .. "/tmp/gonvim.log" + log_path = vim.fn.expand('$HOME') .. '/.cache/nvim/gonvim.log', }) - local cover = require("go.coverage") + local cover = require('go.coverage') local result = cover.read_cov(path) -- print(vim.inspect(result)) - local n = "branch.go" - local range = {['end'] = {character = 13, line = 4}, start = {character = 27, line = 3}} + local n = 'branch.go' + local range = { ['end'] = { character = 13, line = 4 }, start = { character = 27, line = 3 } } - eq(result[n][1].file, "github.com/go.nvim/branch.go") + eq(result[n][1].file, 'github.com/go.nvim/branch.go') eq(result[n][1].range, range) eq(result[n].file_lines, 9) eq(result[n].file_covered, 4) - range = {['end'] = {character = 13, line = 11}, start = {character = 2, line = 11}} + range = { ['end'] = { character = 13, line = 11 }, start = { character = 2, line = 11 } } eq(result[n][3].range, range) eq(result.total_lines, 9) eq(result.total_covered, 4) -- eq(result[n][1], "github.com/go.nvim/branch.go") end) - it("should generate sign list", function() + it('should generate sign list', function() -- - local path = cur_dir .. "/lua/tests/fixtures/coverage/coverage.out" -- %:p:h ? %:p - print("test:" .. path) + local path = cur_dir .. '/lua/tests/fixtures/coverage/coverage.out' -- %:p:h ? %:p + print('test:' .. path) -- go.nvim may not auto loaded vim.cmd([[packadd go.nvim]]) require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand("$HOME") .. "/tmp/gonvim.log", - gocoverage_sign = '|' + log_path = vim.fn.expand('$HOME') .. '/.cache/nvim/gonvim.log', + gocoverage_sign = '|', }) - local cover = require("go.coverage") + local cover = require('go.coverage') cover.highlight() local coverage = { { covered = 1, - file = "github.com/go.nvim/branch.go", - filename = "branch.go", + file = 'github.com/go.nvim/branch.go', + filename = 'branch.go', num = 1, - range = {['end'] = {character = 13, line = 4}, start = {character = 27, line = 3}} - }, { + range = { ['end'] = { character = 13, line = 4 }, start = { character = 27, line = 3 } }, + }, + { covered = 1, - file = "github.com/go.nvim/branch.go", - filename = "branch.go", + file = 'github.com/go.nvim/branch.go', + filename = 'branch.go', num = 1, - range = {['end'] = {character = 13, line = 7}, start = {character = 2, line = 7}} - } + range = { ['end'] = { character = 13, line = 7 }, start = { character = 2, line = 7 } }, + }, } local result = cover.add(1, coverage) @@ -76,7 +77,7 @@ describe("should read coveragefile", function() id = 3, lnum = 3, name = 'goCoverageCovered', - priority = 7 + priority = 7, } eq(result[1], sign) -- eq(result[n][1], "github.com/go.nvim/branch.go") diff --git a/lua/tests/go_fixplurals_spec.lua b/lua/tests/go_fixplurals_spec.lua index b839356da..a8ca726c8 100644 --- a/lua/tests/go_fixplurals_spec.lua +++ b/lua/tests/go_fixplurals_spec.lua @@ -16,16 +16,14 @@ describe('should run fixplurals', function() local path = cur_dir .. '/lua/tests/fixtures/fixplurals/fixp_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/fixplurals/fixp_golden.go'), '\n') + local expected = vim.fn.join(vim.fn.readfile(cur_dir .. '/lua/tests/fixtures/fixplurals/fixp_golden.go'), '\n') local cmd = " silent exe 'e " .. name .. "'" vim.cmd(cmd) local bufn = vim.fn.bufnr('') vim.treesitter.stop() vim.treesitter.start() - local parsers = require "nvim-treesitter.parsers" - local root_lang_tree = parsers.get_parser(bufn, 'go') + local root_lang_tree = vim.treesitter.get_parser(bufn, 'go') -- read current line root_lang_tree:parse() diff --git a/lua/tests/go_hover_spec.lua b/lua/tests/go_hover_spec.lua index 2260d802a..7e5f7380a 100644 --- a/lua/tests/go_hover_spec.lua +++ b/lua/tests/go_hover_spec.lua @@ -21,7 +21,7 @@ describe('regex should work', function() require('go').setup({ trace = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', + log_path = vim.fn.expand('$HOME') .. '/.cache/nvim/gonvim.log', }) print(vim.fn.expand('$HOME') .. '/tmp/gonvim.log') @@ -29,21 +29,21 @@ describe('regex should work', function() local str = [[func Println(a ...any) (n int, err error)]] local ret = require('go.lsp').find_ret(str) print(vim.inspect(ret)) - eq({'n', 'err'}, ret) + eq({ 'n', 'err' }, ret) end) it('should find return', function() local str = [[func fmt.Println(a ...any) (int, error)]] local ret, e = require('go.lsp').find_ret(str) print(vim.inspect(ret)) - eq({'i', 'err'}, ret) + eq({ 'i', 'err' }, ret) eq(true, e) end) it('should find return', function() local str = [[func fmt.Println(a, b int) (int, error)]] local ret, e = require('go.lsp').find_ret(str) print(vim.inspect(ret)) - eq({'i', 'err'}, ret) + eq({ 'i', 'err' }, ret) eq(true, e) end) @@ -51,7 +51,7 @@ describe('regex should work', function() local str = [[func fmt.Println(a, b int) int]] local ret, e = require('go.lsp').find_ret(str) print(vim.inspect(ret)) - eq({'i'}, ret) + eq({ 'i' }, ret) eq(false, e) end) @@ -59,7 +59,7 @@ describe('regex should work', function() local str = [[func fmt.Println(a, b int) MyType]] local ret, e = require('go.lsp').find_ret(str) print(vim.inspect(ret)) - eq({'myType'}, ret) + eq({ 'myType' }, ret) eq(false, e) end) @@ -67,7 +67,7 @@ describe('regex should work', function() local str = [[func fmt.Println(a, b int) (MyType, error)]] local ret, e = require('go.lsp').find_ret(str) print(vim.inspect(ret)) - eq({'myType', 'err'}, ret) + eq({ 'myType', 'err' }, ret) eq(true, e) end) end) @@ -86,6 +86,5 @@ describe('should run hover', function() local ret = require('go.lsp').gen_return(result) print(vim.inspect(ret)) - end) end) diff --git a/lua/tests/go_make_spec.lua b/lua/tests/go_make_spec.lua index 9f82ab83d..7d3fcb71c 100644 --- a/lua/tests/go_make_spec.lua +++ b/lua/tests/go_make_spec.lua @@ -16,9 +16,9 @@ describe('should run func make', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', + log_path = vim.fn.expand('$HOME') .. '/.cache/nvim/gonvim.log', }) - vim.cmd("silent cd " .. path) + vim.cmd('silent cd ' .. path) vim.cmd("silent exe 'e " .. fname .. "'") vim.fn.setpos('.', { 0, 5, 11, 0 }) local cmd = require('go.asyncmake').make('go', 'vet', './coverage') @@ -36,10 +36,10 @@ describe('should run func make', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', + log_path = vim.fn.expand('$HOME') .. '/.cache/nvim/gonvim.log', }) - vim.cmd("silent cd " .. path) + vim.cmd('silent cd ' .. path) vim.cmd("silent exe 'e " .. fname .. "'") vim.fn.setpos('.', { 0, 6, 11, 0 }) local cmd = require('go.asyncmake').make('go', 'test', './coverage') diff --git a/lua/tests/go_test_spec.lua b/lua/tests/go_test_spec.lua index 6a052ca14..6de0059b1 100644 --- a/lua/tests/go_test_spec.lua +++ b/lua/tests/go_test_spec.lua @@ -22,8 +22,8 @@ describe('should run func test', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', test_runner = 'go', + log_path = vim.fn.expand('$HOME') .. '/.cache/nvim/gonvim.log', }) vim.cmd('cd ' .. godir) vim.cmd("silent exe 'e " .. path .. "'") @@ -38,7 +38,6 @@ describe('should run func test', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', test_runner = 'go', }) @@ -55,7 +54,6 @@ describe('should run func test', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', test_runner = 'go', }) vim.cmd('cd ' .. godir) @@ -77,7 +75,6 @@ describe('should run func test', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', test_runner = 'go', }) vim.cmd('cd ' .. godir) @@ -101,7 +98,6 @@ describe('should run func test', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', test_runner = 'go', }) vim.cmd('cd ' .. godir) @@ -130,7 +126,6 @@ describe('should run func test', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', test_runner = 'go', }) vim.cmd('cd ' .. godir) @@ -172,7 +167,6 @@ describe('should run test file', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', test_runner = 'go', }) vim.cmd('cd ' .. godir) @@ -208,7 +202,6 @@ describe('should run test file with flags', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', }) vim.cmd('cd ' .. godir) vim.cmd("silent exe 'e " .. path .. "'") @@ -245,7 +238,6 @@ describe('should run test package: ', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', }) vim.cmd('cd ' .. godir) vim.cmd("silent exe 'e " .. path .. "'") @@ -290,7 +282,6 @@ describe('should allow select test func: ', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', }) vim.cmd('cd ' .. godir) vim.cmd("silent exe 'e " .. path .. "'") @@ -312,7 +303,6 @@ describe('should run test file with flags inside file: ', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', }) vim.cmd('cd ' .. godir) vim.cmd("silent exe 'e " .. path .. "'") @@ -349,7 +339,6 @@ describe('should run subcase tests: ', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', }) vim.cmd('cd ' .. godir) vim.cmd("silent exe 'e " .. path .. "'") @@ -364,7 +353,6 @@ describe('should run subcase tests: ', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', }) vim.cmd('cd ' .. godir) vim.cmd("silent exe 'e " .. path .. "'") @@ -378,7 +366,6 @@ describe('should run subcase tests: ', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', }) vim.cmd('cd ' .. godir) vim.cmd("silent exe 'e " .. path .. "'") @@ -392,7 +379,6 @@ describe('should run subcase tests: ', function() require('go').setup({ trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', }) vim.cmd('cd ' .. godir) vim.cmd("silent exe 'e " .. path .. "'") diff --git a/lua/tests/go_ts_node_spec.lua b/lua/tests/go_ts_node_spec.lua index ca47b2241..950dd5caf 100644 --- a/lua/tests/go_ts_node_spec.lua +++ b/lua/tests/go_ts_node_spec.lua @@ -43,7 +43,7 @@ describe('should get nodes ', function() require('plenary.reload').reload_module('go.nvim') require('plenary.reload').reload_module('nvim-treesitter/nvim-treesitter') - _GO_NVIM_CFG.verbose = true + -- _GO_NVIM_CFG.verbose = true local nodes = require('go.ts.nodes') it('get all nodes should get struct x', function() @@ -54,8 +54,7 @@ describe('should get nodes ', function() 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_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) @@ -69,8 +68,7 @@ describe('should get nodes ', function() 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_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) @@ -98,7 +96,7 @@ describe('should get nodes for play list ', function() local bufn = vim.fn.bufnr('') - _GO_NVIM_CFG.verbose = true + -- _GO_NVIM_CFG.verbose = true local nodes = require('go.ts.nodes') it('should get function name', function() vim.fn.setpos('.', { bufn, 21, 5, 0 }) @@ -178,8 +176,8 @@ describe('should get nodes for import golden ', function() vim.treesitter.stop() vim.treesitter.start() local buf = vim.api.nvim_win_get_buf(0) - local parsers = require "nvim-treesitter.parsers" - local root_lang_tree = parsers.get_parser(buf, 'go') + + local root_lang_tree = vim.treesitter.get_parser(buf, 'go') -- read current line print('current line', vim.api.nvim_get_current_line(), vim.o.filetype, buf) diff --git a/lua/tests/go_utils_spec.lua b/lua/tests/go_utils_spec.lua index a2ac11fc3..2199d3fd6 100644 --- a/lua/tests/go_utils_spec.lua +++ b/lua/tests/go_utils_spec.lua @@ -9,7 +9,6 @@ describe('should get file name and number ', function() verbose = true, trace = true, lsp_cfg = true, - log_path = vim.fn.expand('$HOME') .. '/tmp/gonvim.log', }) local utils = require('go.utils') diff --git a/lua/tests/init.lua b/lua/tests/init.lua new file mode 100644 index 000000000..4bb98c4b0 --- /dev/null +++ b/lua/tests/init.lua @@ -0,0 +1,58 @@ +-- Define the plugin directory variable (s:plugin_dir in VimScript) +local plugin_dir = vim.fn.expand('~/.local/share/nvim/site/pack/vendor/start') + +-- set rtp+=. +vim.opt.rtp:append('.') + +vim.opt.rtp:prepend(plugin_dir .. '/plenary.nvim') +vim.opt.rtp:prepend(plugin_dir .. '/nvim-treesitter') +vim.opt.rtp:prepend(plugin_dir .. '/nvim-lspconfig') + +vim.cmd('runtime! plugin/plenary.vim') +vim.cmd('runtime! plugin/nvim-treesitter.vim') +vim.cmd('runtime! plugin/playground.vim') +vim.cmd('runtime! plugin/nvim-lspconfig.vim') + +-- Option settings (set noswapfile, set nobackup, etc.) +vim.opt.swapfile = false +vim.opt.backup = false +vim.opt.writebackup = false +vim.opt.autoindent = false +vim.opt.cindent = false +vim.opt.smartindent = false +vim.opt.indentexpr = '' +vim.opt.shada = 'NONE' + +-- filetype indent off +vim.cmd('filetype indent off') + +-- Lua configuration block +_G.test_rename = true +_G.test_close = true + +-- require("plenary/busted") +require('plenary.busted') + +-- require("go").setup({...}) +require('go').setup({ + gofmt = 'gofumpt', + goimports = 'goimports', + verbose = true, + log_path = vim.fn.expand('$HOME') .. '/.cache/nvim/gonvim.log', + lsp_cfg = true, +}) + +vim.lsp.enable('gopls') + +require('nvim-treesitter').setup({ + -- Directory to install parsers and queries to + install_dir = vim.fn.stdpath('data') .. '/site', +}) +vim.opt.rtp:append(vim.fn.stdpath('data') .. '/site') + +vim.api.nvim_create_autocmd('FileType', { + pattern = { 'go' }, + callback = function() + vim.treesitter.start() + end, +}) diff --git a/lua/tests/install-parsers.lua b/lua/tests/install-parsers.lua new file mode 100644 index 000000000..374360871 --- /dev/null +++ b/lua/tests/install-parsers.lua @@ -0,0 +1,139 @@ +#!/usr/bin/env -S nvim -l +vim.opt.runtimepath:append('../nvim-treesitter') +vim.opt.runtimepath:append('.') + +local install_dir = vim.fn.stdpath('data') .. '/site' +print('Installing to: ' .. install_dir) + +-- Create directories if they don't exist +vim.fn.mkdir(install_dir .. '/parser', 'p') +vim.fn.mkdir(install_dir .. '/queries', 'p') + +-- Manual compilation approach +local function compile_parser() + local build_dir = '/tmp/tree-sitter-go' + + -- Clean up any existing build + vim.fn.system('rm -rf ' .. build_dir) + + -- Clone the tree-sitter-go repository + print('Cloning tree-sitter-go...') + local clone_result = vim.fn.system(string.format( + 'git clone --depth 1 https://github.com/tree-sitter/tree-sitter-go.git %s 2>&1', + build_dir + )) + print(clone_result) + + if vim.fn.isdirectory(build_dir .. '/src') ~= 1 then + print('ERROR: Failed to clone tree-sitter-go') + return false + end + + -- Compile the parser + print('Compiling parser...') + local parser_c = build_dir .. '/src/parser.c' + local scanner_c = build_dir .. '/src/scanner.c' + local output_so = install_dir .. '/parser/go.so' + + local sources = parser_c + if vim.fn.filereadable(scanner_c) == 1 then + sources = sources .. ' ' .. scanner_c + end + + local compile_cmd = string.format( + 'cc -o "%s" -I"%s/src" %s -shared -Os -fPIC 2>&1', + output_so, + build_dir, + sources + ) + + print('Compile command: ' .. compile_cmd) + local compile_result = vim.fn.system(compile_cmd) + print('Compile output: ' .. compile_result) + + -- Check if compilation succeeded + if vim.fn.filereadable(output_so) == 1 then + print('โœ“ Successfully compiled go.so') + return true + else + print('โœ— Failed to compile go.so') + return false + end +end + +-- Try nvim-treesitter first +print('Attempting nvim-treesitter installation...') +vim.opt.rtp:append(install_dir) + +local ok, _ = pcall(function() + require('nvim-treesitter').setup({ + install_dir = install_dir, + }) + + local install = require('nvim-treesitter.install') + install.update('go') + vim.wait(5000, function() return false end) +end) + +-- Check if nvim-treesitter installation worked +local go_so_path = install_dir .. '/parser/go.so' +if vim.fn.filereadable(go_so_path) ~= 1 then + print('nvim-treesitter installation did not create go.so, trying manual compilation...') + if not compile_parser() then + print('ERROR: Manual compilation also failed') + os.exit(1) + end +end + +-- Copy queries from nvim-treesitter source +print('\nCopying queries...') +local ts_queries_paths = { + vim.fn.expand('~/.local/share/nvim/site/pack/vendor/start/nvim-treesitter/queries/go'), + '../nvim-treesitter/queries/go', + '/tmp/tree-sitter-go/queries', +} + +local queries_copied = false +for _, ts_queries in ipairs(ts_queries_paths) do + if vim.fn.isdirectory(ts_queries) == 1 then + print('Copying queries from: ' .. ts_queries) + vim.fn.system(string.format('cp -r "%s" "%s/"', ts_queries, install_dir .. '/queries')) + queries_copied = true + break + end +end + +if not queries_copied then + print('WARNING: Could not find queries directory') +end + +-- Verify installation +print("\nVerifying parser installation...") +local parser_dir = install_dir .. '/parser' +local queries_dir = install_dir .. '/queries/go' + +if vim.fn.isdirectory(parser_dir) == 1 then + local files = vim.fn.readdir(parser_dir) + print('Parser files: ' .. vim.inspect(files)) + + local go_so_exists = vim.fn.filereadable(parser_dir .. '/go.so') == 1 + print('go.so exists: ' .. tostring(go_so_exists)) + print('go.so size: ' .. vim.fn.getfsize(parser_dir .. '/go.so') .. ' bytes') + + if not go_so_exists then + print('ERROR: go.so not found!') + os.exit(1) + end +else + print('ERROR: Parser directory does not exist!') + os.exit(1) +end + +if vim.fn.isdirectory(queries_dir) == 1 then + local files = vim.fn.readdir(queries_dir) + print('Query files: ' .. vim.inspect(files)) +else + print('WARNING: Queries directory does not exist - tests may fail') +end + +print('\nโœ“ Parser installation complete!') \ No newline at end of file diff --git a/lua/tests/minimal.lua b/lua/tests/minimal.lua new file mode 100644 index 000000000..c4e6092a7 --- /dev/null +++ b/lua/tests/minimal.lua @@ -0,0 +1,52 @@ +vim.opt.rtp:append('.') +vim.opt.rtp:append('../plenary.nvim/') +vim.opt.rtp:append('../nvim-treesitter') +vim.opt.rtp:append('../nvim-lspconfig/') +vim.opt.rtp:append('../guihua.lua/') + +-- Add the treesitter parser install directory to runtimepath BEFORE loading plugins +local parser_install_dir = vim.fn.stdpath('data') .. '/site' +vim.opt.rtp:prepend(parser_install_dir) + +vim.cmd([[ + runtime! plugin/plenary.vim + runtime! plugin/nvim-treesitter.vim + runtime! plugin/playground.vim + runtime! plugin/nvim-lspconfig.vim + runtime! plugin/guihua.lua +]]) + +vim.opt.swapfile = false -- no swapfile +vim.opt.backup = false -- no backup +vim.opt.writebackup = false -- no writebackup + +vim.cmd('filetype indent off') +vim.opt.autoindent = false +vim.opt.cindent = false +vim.opt.smartindent = false +vim.opt.indentexpr = '' -- clear any indentexpr + +require('plenary.busted') + +require('go').setup({ + debug = true, + verbose = true, + gofmt = 'gofumpt', + goimports = 'goimports', + log_path = vim.fn.expand('$HOME') .. '/.cache/nvim/gonvim.log', + lsp_cfg = true, +}) + +require('nvim-treesitter').setup({ + -- Directory to install parsers and queries to + install_dir = parser_install_dir, +}) + +vim.o.swapfile = false +vim.bo.swapfile = false + +-- Disable automatic treesitter start for now +vim.g.ts_highlight_disable = true + +vim.cmd([[set completeopt+=menuone,noselect,popup]]) +vim.lsp.enable('gopls') diff --git a/lua/tests/minimal.vim b/lua/tests/minimal.vim index 8fc2246c9..ea951181d 100644 --- a/lua/tests/minimal.vim +++ b/lua/tests/minimal.vim @@ -7,6 +7,7 @@ runtime! plugin/plenary.vim runtime! plugin/nvim-treesitter.vim runtime! plugin/playground.vim runtime! plugin/nvim-lspconfig.vim +runtime! plugin/guihua.lua set noswapfile set nobackup diff --git a/playground/init_lazy.lua b/playground/init_lazy.lua index a9cf1b0a8..267359d09 100644 --- a/playground/init_lazy.lua +++ b/playground/init_lazy.lua @@ -2,7 +2,7 @@ -- change the slash to backslash in PATH for Windows vim.cmd([[set runtimepath=$VIMRUNTIME]]) local tmpdir = vim.loop.os_tmpdir() .. '/nvim' -packpath = tmpdir .. '/lazy' +local packpath = tmpdir .. '/lazy' vim.cmd([[set packpath=]] .. packpath) -- print(packpath) @@ -32,35 +32,36 @@ local function load_plugins() return { { 'nvim-treesitter/nvim-treesitter', + lazy = false, + branch = 'main', + build = ':TSUpdate', config = function() - require('nvim-treesitter.configs').setup({ - ensure_installed = { 'go' }, - highlight = { enable = true }, + require('nvim-treesitter').setup({ + -- Directory to install parsers and queries to + install_dir = vim.fn.stdpath('data') .. '/site', }) + require('nvim-treesitter').install({ 'go' }):wait(3000) end, - build = ':TSUpdate', }, { 'neovim/nvim-lspconfig' }, { 'ray-x/go.nvim', dev = (plugin_folder() ~= ''), - -- dev = true, ft = { 'go', 'gomod', 'gosum', 'gotmpl', 'gohtmltmpl', 'gotexttmpl' }, dependencies = { 'mfussenegger/nvim-dap', -- Debug Adapter Protocol 'rcarriga/nvim-dap-ui', - 'nvim-neotest/nvim-nio', 'theHamsta/nvim-dap-virtual-text', 'ray-x/guihua.lua', }, config = true, opts = { verbose = true, - -- log_path = '~/tmp/go.log', + -- log_path = '~/tmp/gonvim.log', lsp_cfg = true, goimports = 'gopls', gofmt = 'gopls', - max_line_len = 80, + max_line_len = 120, }, }, } @@ -76,3 +77,10 @@ local opts = { } require('lazy').setup(load_plugins(), opts) + +vim.api.nvim_create_autocmd('FileType', { + pattern = { 'go' }, + callback = function() + vim.treesitter.start() + end, +})