From ce3c5fe2cb8f7f14652b5e73c1c5e30b00717777 Mon Sep 17 00:00:00 2001 From: ray-x Date: Wed, 8 Dec 2021 08:05:49 +1100 Subject: [PATCH] fix the referece floatwindow loading performance issue --- lua/navigator.lua | 114 ++++---- lua/navigator/lspclient/clients.lua | 390 +++++++++++++++++----------- lua/navigator/lspclient/mapping.lua | 4 +- lua/navigator/lspwrapper.lua | 121 +++++---- selene.toml | 1 + stylua.toml | 4 + thread.lua | 20 ++ vim.toml | 53 ++++ 8 files changed, 446 insertions(+), 261 deletions(-) create mode 100644 selene.toml create mode 100644 stylua.toml create mode 100644 thread.lua create mode 100644 vim.toml diff --git a/lua/navigator.lua b/lua/navigator.lua index 71237e3..aba1dcc 100644 --- a/lua/navigator.lua +++ b/lua/navigator.lua @@ -1,11 +1,11 @@ local M = {} local function warn(msg) - vim.api.nvim_echo({{"WRN: " .. msg, "WarningMsg"}}, true, {}) + vim.api.nvim_echo({ { 'WRN: ' .. msg, 'WarningMsg' } }, true, {}) end local function info(msg) - vim.api.nvim_echo({{"Info: " .. msg}}, true, {}) + vim.api.nvim_echo({ { 'Info: ' .. msg } }, true, {}) end _NgConfigValues = { @@ -19,8 +19,8 @@ _NgConfigValues = { keymaps = {}, -- e.g keymaps={{key = "GR", func = "references()"}, } this replace gr default mapping external = nil, -- true: enable for goneovim multigrid otherwise false - border = "single", -- border style, can be one of 'none', 'single', 'double', "shadow" - combined_attach = "both", -- both: use both customized attach and navigator default attach, mine: only use my attach defined in vimrc + border = 'single', -- border style, can be one of 'none', 'single', 'double', "shadow" + combined_attach = 'both', -- both: use both customized attach and navigator default attach, mine: only use my attach defined in vimrc on_attach = function(client, bufnr) -- your on_attach will be called at end of navigator on_attach end, @@ -38,14 +38,14 @@ _NgConfigValues = { sign = true, sign_priority = 40, virtual_text = true, - virtual_text_icon = true + virtual_text_icon = true, }, code_lens_action = { enable = true, sign = true, sign_priority = 40, virtual_text = true, - virtual_text_icon = true + virtual_text_icon = true, }, format_on_save = true, -- set to false to disasble lsp code format on save (if you are using prettier/efm/formater etc) disable_format_cap = {}, -- a list of lsp disable file format (e.g. if you using efm or vim-codeformat etc), empty by default @@ -57,7 +57,7 @@ _NgConfigValues = { -- to load those files diagnostic_virtual_text = true, -- show virtual for diagnostic message diagnostic_update_in_insert = false, -- update diagnostic message in insert mode - diagnostic_scrollbar_sign = {'▃', '▆', '█'}, -- set to nil to disable, set to {'╍', 'ﮆ'} to enable diagnostic status in scroll bar area + diagnostic_scrollbar_sign = { '▃', '▆', '█' }, -- set to nil to disable, set to {'╍', 'ﮆ'} to enable diagnostic status in scroll bar area tsserver = { -- filetypes = {'typescript'} -- disable javascript etc, -- set to {} to disable the lspclient for all filetype @@ -67,44 +67,44 @@ _NgConfigValues = { -- sumneko_binary = sumneko_binary, -- cmd = {'lua-language-server'} }, - servers = {} -- you can add additional lsp server so navigator will load the default for you + servers = {}, -- you can add additional lsp server so navigator will load the default for you }, lsp_installer = false, -- set to true if you would like use the lsp installed by williamboman/nvim-lsp-installer icons = { icons = true, -- set to false to use system default ( if you using a terminal does not have nerd/icon) -- Code action - code_action_icon = "🏏", -- "", + code_action_icon = '🏏', -- "", -- code lens - code_lens_action_icon = "👓", + code_lens_action_icon = '👓', -- Diagnostics diagnostic_head = '🐛', - diagnostic_err = "📛", - diagnostic_warn = "👎", + diagnostic_err = '📛', + diagnostic_warn = '👎', diagnostic_info = [[👩]], diagnostic_hint = [[💁]], - diagnostic_head_severity_1 = "🈲", - diagnostic_head_severity_2 = "☣️", - diagnostic_head_severity_3 = "👎", - diagnostic_head_description = "👹", - diagnostic_virtual_text = "🦊", - diagnostic_file = "🚑", + diagnostic_head_severity_1 = '🈲', + diagnostic_head_severity_2 = '☣️', + diagnostic_head_severity_3 = '👎', + diagnostic_head_description = '👹', + diagnostic_virtual_text = '🦊', + diagnostic_file = '🚑', -- Values - value_changed = "📝", - value_definition = "🦕", + value_changed = '📝', + value_definition = '🐶', -- it is easier to see than 🦕 -- Treesitter match_kinds = { - var = " ", -- "👹", -- Vampaire - method = "ƒ ", -- "🍔", -- mac - ["function"] = " ", -- "🤣", -- Fun - parameter = " ", -- Pi - associated = "🤝", - namespace = "🚀", - type = " ", - field = "🏈" + var = ' ', -- "👹", -- Vampaire + method = 'ƒ ', -- "🍔", -- mac + ['function'] = ' ', -- "🤣", -- Fun + parameter = ' ', -- Pi + associated = '🤝', + namespace = '🚀', + type = ' ', + field = '🏈', }, - treesitter_defult = "🌲" - } + treesitter_defult = '🌲', + }, } vim.cmd("command! -nargs=0 LspLog lua require'navigator.lspclient.config'.open_lsp_log()") @@ -112,12 +112,12 @@ vim.cmd("command! -nargs=0 LspRestart lua require'navigator.lspclient.config'.re vim.cmd("command! -nargs=0 LspToggleFmt lua require'navigator.lspclient.mapping'.toggle_lspformat()") M.deprecated = function(cfg) - local warn = require'navigator.util'.warn + local warn = require('navigator.util').warn if cfg.code_action_prompt then - warn("code_action_prompt moved to lsp.code_action") + warn('code_action_prompt moved to lsp.code_action') end if cfg.code_lens_action_prompt then - warn("code_lens_action_prompt moved to lsp.code_lens_action") + warn('code_lens_action_prompt moved to lsp.code_lens_action') end if cfg.lsp ~= nil and cfg.lsp.disable_format_ft ~= nil and cfg.lsp.disable_format_ft ~= {} then @@ -140,25 +140,37 @@ local extend_config = function(opts) end for key, value in pairs(opts) do if _NgConfigValues[key] == nil then - warn(string.format("[] Deprecated? Key %s is not in default setup, it could be incorrect to set to %s", key, - vim.inspect(value))) + warn( + string.format( + '[] Deprecated? Key %s is not in default setup, it could be incorrect to set to %s', + key, + vim.inspect(value) + ) + ) _NgConfigValues[key] = value -- return else - if type(_NgConfigValues[key]) == "table" then - if type(value) ~= "table" then - info(string.format("[] Reset type: Key %s setup value %s type %s , from %s", key, vim.inspect(value), - type(value), vim.inspect(_NgConfigValues[key]))) + if type(_NgConfigValues[key]) == 'table' then + if type(value) ~= 'table' then + info( + string.format( + '[] Reset type: Key %s setup value %s type %s , from %s', + key, + vim.inspect(value), + type(value), + vim.inspect(_NgConfigValues[key]) + ) + ) end for k, v in pairs(value) do - if type(k) == "number" then + if type(k) == 'number' then -- replace all item in array _NgConfigValues[key] = value break end -- level 3 - if type(_NgConfigValues[key][k]) == "table" then - if type(v) == "table" then + if type(_NgConfigValues[key][k]) == 'table' then + if type(v) == 'table' then for k2, v2 in pairs(v) do _NgConfigValues[key][k][k2] = v2 end @@ -169,13 +181,14 @@ local extend_config = function(opts) if _NgConfigValues[key][k] == nil then if key == 'lsp' then local lsp = require('navigator.lspclient.clients').lsp - if not vim.tbl_contains(lsp or {}, k) and k ~= 'efm' then - info(string.format("[] extend LSP support for %s ", k)) + if not vim.tbl_contains(lsp or {}, k) and k ~= 'efm' and k ~= 'null-ls' then + info(string.format('[] extend LSP support for %s ', k)) end elseif key == 'keymaps' then + info('keymap override') -- skip key check and allow mapping to handle that else - warn(string.format("[] Key %s %s not valid", key, k)) + warn(string.format('[] Key %s %s not valid', key, k)) end -- return end @@ -201,7 +214,7 @@ end M.setup = function(cfg) extend_config(cfg) - vim.cmd([[autocmd FileType,BufEnter * lua require'navigator.lspclient.clients'.setup()]]) -- BufWinEnter BufNewFile,BufRead ? + vim.cmd([[autocmd FileType,BufEnter * lua require'navigator.lspclient.clients'.on_filetype()]]) -- BufWinEnter BufNewFile,BufRead ? -- local log = require"navigator.util".log -- log(debug.traceback()) -- log(cfg, _NgConfigValues) @@ -209,10 +222,10 @@ M.setup = function(cfg) require('navigator.lazyloader').init() require('navigator.lspclient.clients').setup(_NgConfigValues) -- require("navigator.lspclient.mapping").setup(_NgConfigValues) - require("navigator.reference") - require("navigator.definition") - require("navigator.hierarchy") - require("navigator.implementation") + require('navigator.reference') + require('navigator.definition') + require('navigator.hierarchy') + require('navigator.implementation') -- log("navigator loader") @@ -224,7 +237,6 @@ M.setup = function(cfg) if _NgConfigValues.ts_fold == true then require('navigator.foldts').on_attach() end - end return M diff --git a/lua/navigator/lspclient/clients.lua b/lua/navigator/lspclient/clients.lua index 99ef2a6..bdcac2d 100644 --- a/lua/navigator/lspclient/clients.lua +++ b/lua/navigator/lspclient/clients.lua @@ -1,9 +1,9 @@ -- todo allow config passed in -local log = require"navigator.util".log -local trace = require"navigator.util".trace +local log = require('navigator.util').log +local trace = require('navigator.util').trace local uv = vim.loop -local warn = require'navigator.util'.warn +local warn = require('navigator.util').warn _NG_Loaded = {} _LoadedFiletypes = {} @@ -12,22 +12,22 @@ packer_plugins = packer_plugins or nil -- suppress warnings -- packer only -local highlight = require "navigator.lspclient.highlight" +local highlight = require('navigator.lspclient.highlight') -local has_lsp, lspconfig = pcall(require, "lspconfig") +local has_lsp, lspconfig = pcall(require, 'lspconfig') if not has_lsp then return { setup = function() - print("loading lsp config failed LSP may not working correctly") - end + print('loading lsp config failed LSP may not working correctly') + end, } end local util = lspconfig.util -local config = require"navigator".config_values() +local config = require('navigator').config_values() -- local cap = vim.lsp.protocol.make_client_capabilities() -local on_attach = require("navigator.lspclient.attach").on_attach +local on_attach = require('navigator.lspclient.attach').on_attach -- gopls["ui.completion.usePlaceholders"] = true -- lua setup @@ -37,25 +37,25 @@ local luadevcfg = { library = { vimruntime = true, -- runtime path types = true, -- full signature, docs and completion of vim.api, vim.treesitter, vim.lsp and others - plugins = {"nvim-treesitter", "plenary.nvim"} + plugins = { 'nvim-treesitter', 'plenary.nvim' }, }, lspconfig = { -- cmd = {sumneko_binary}, - on_attach = on_attach - } + on_attach = on_attach, + }, } local luadev = {} -require'navigator.lazyloader'.load('lua-dev.nvim', 'folke/lua-dev.nvim') -local ok, l = pcall(require, "lua-dev") +require('navigator.lazyloader').load('lua-dev.nvim', 'folke/lua-dev.nvim') +local ok, l = pcall(require, 'lua-dev') if ok and l then luadev = l.setup(luadevcfg) end -local path = vim.split(package.path, ";") +local path = vim.split(package.path, ';') -table.insert(path, "lua/?.lua") -table.insert(path, "lua/?/init.lua") +table.insert(path, 'lua/?.lua') +table.insert(path, 'lua/?/init.lua') local function add(lib) for _, p in pairs(vim.fn.expand(lib, false, true)) do @@ -67,7 +67,7 @@ local function add(lib) end -- add runtime -add("$VIMRUNTIME") +add('$VIMRUNTIME') -- add your config -- local home = vim.fn.expand("$HOME") @@ -79,22 +79,22 @@ add(vim.fn.stdpath('config')) -- add(home .. "/.local/share/nvim/site/pack/packer/start/*") -- end -library[vim.fn.expand("$VIMRUNTIME/lua")] = true -library[vim.fn.expand("$VIMRUNTIME/lua/vim")] = true -library[vim.fn.expand("$VIMRUNTIME/lua/vim/lsp")] = true +library[vim.fn.expand('$VIMRUNTIME/lua')] = true +library[vim.fn.expand('$VIMRUNTIME/lua/vim')] = true +library[vim.fn.expand('$VIMRUNTIME/lua/vim/lsp')] = true -- [vim.fn.expand("~/repos/nvim/lua")] = true -- TODO remove onece PR #944 merged to lspconfig -local path_sep = require"navigator.util".path_sep() -local strip_dir_pat = path_sep .. "([^" .. path_sep .. "]+)$" -local strip_sep_pat = path_sep .. "$" +local path_sep = require('navigator.util').path_sep() +local strip_dir_pat = path_sep .. '([^' .. path_sep .. ']+)$' +local strip_sep_pat = path_sep .. '$' local dirname = function(pathname) if not pathname or #pathname == 0 then return end - local result = pathname:gsub(strip_sep_pat, ""):gsub(strip_dir_pat, "") + local result = pathname:gsub(strip_sep_pat, ''):gsub(strip_dir_pat, '') if #result == 0 then - return "/" + return '/' end return result end @@ -103,97 +103,101 @@ end local setups = { clojure_lsp = { root_dir = function(fname) - return util.root_pattern("deps.edn", "build.boot", "project.clj", "shadow-cljs.edn", "bb.edn", ".git")(fname) - or util.path.dirname(fname) + return util.root_pattern('deps.edn', 'build.boot', 'project.clj', 'shadow-cljs.edn', 'bb.edn', '.git')(fname) + or util.path.dirname(fname) end, on_attach = on_attach, - filetypes = {"clojure", "edn"}, + filetypes = { 'clojure', 'edn' }, message_level = vim.lsp.protocol.MessageType.error, - cmd = {"clojure-lsp"} + cmd = { 'clojure-lsp' }, }, gopls = { on_attach = on_attach, -- capabilities = cap, - filetypes = {"go", "gomod"}, + filetypes = { 'go', 'gomod' }, message_level = vim.lsp.protocol.MessageType.Error, cmd = { - "gopls", -- share the gopls instance if there is one already - "-remote=auto", --[[ debug options ]] -- + 'gopls', -- share the gopls instance if there is one already + '-remote=auto', --[[ debug options ]] -- -- "-logfile=auto", -- "-debug=:0", - "-remote.debug=:0" + '-remote.debug=:0', -- "-rpc.trace", }, - flags = {allow_incremental_sync = true, debounce_text_changes = 1000}, + flags = { allow_incremental_sync = true, debounce_text_changes = 1000 }, settings = { gopls = { -- more settings: https://github.com/golang/tools/blob/master/gopls/doc/settings.md -- flags = {allow_incremental_sync = true, debounce_text_changes = 500}, -- not supported - analyses = {unusedparams = true, unreachable = false}, + analyses = { unusedparams = true, unreachable = false }, codelenses = { generate = true, -- show the `go generate` lens. gc_details = true, -- // Show a code lens toggling the display of gc's choices. test = true, - tidy = true + tidy = true, }, usePlaceholders = true, completeUnimported = true, staticcheck = true, - matcher = "fuzzy", - diagnosticsDelay = "500ms", - experimentalWatchedFileDelay = "1000ms", - symbolMatcher = "fuzzy", + matcher = 'fuzzy', + diagnosticsDelay = '500ms', + experimentalWatchedFileDelay = '1000ms', + symbolMatcher = 'fuzzy', gofumpt = false, -- true, -- turn on for new repos, gofmpt is good but also create code turmoils - buildFlags = {"-tags", "integration"} + buildFlags = { '-tags', 'integration' }, -- buildFlags = {"-tags", "functional"} - } + }, }, root_dir = function(fname) - return util.root_pattern("go.mod", ".git")(fname) or dirname(fname) -- util.path.dirname(fname) - end + return util.root_pattern('go.mod', '.git')(fname) or dirname(fname) -- util.path.dirname(fname) + end, }, clangd = { - flags = {allow_incremental_sync = true, debounce_text_changes = 500}, + flags = { allow_incremental_sync = true, debounce_text_changes = 500 }, cmd = { - "clangd", "--background-index", "--suggest-missing-includes", "--clang-tidy", - "--header-insertion=iwyu", "--clang-tidy-checks=-*,llvm-*,clang-analyzer-*", - "--cross-file-rename" + 'clangd', + '--background-index', + '--suggest-missing-includes', + '--clang-tidy', + '--header-insertion=iwyu', + '--clang-tidy-checks=-*,llvm-*,clang-analyzer-*', + '--cross-file-rename', }, - filetypes = {"c", "cpp", "objc", "objcpp"}, + filetypes = { 'c', 'cpp', 'objc', 'objcpp' }, on_attach = function(client) client.resolved_capabilities.document_formatting = true on_attach(client) - end + end, }, rust_analyzer = { root_dir = function(fname) - return util.root_pattern("Cargo.toml", "rust-project.json", ".git")(fname) or util.path.dirname(fname) + return util.root_pattern('Cargo.toml', 'rust-project.json', '.git')(fname) or util.path.dirname(fname) end, - filetypes = {"rust"}, + filetypes = { 'rust' }, message_level = vim.lsp.protocol.MessageType.error, on_attach = on_attach, settings = { - ["rust-analyzer"] = { - assist = {importMergeBehavior = "last", importPrefix = "by_self"}, - cargo = {loadOutDirsFromCheck = true}, - procMacro = {enable = true} - } + ['rust-analyzer'] = { + assist = { importMergeBehavior = 'last', importPrefix = 'by_self' }, + cargo = { loadOutDirsFromCheck = true }, + procMacro = { enable = true }, + }, }, - flags = {allow_incremental_sync = true, debounce_text_changes = 500} + flags = { allow_incremental_sync = true, debounce_text_changes = 500 }, }, sqls = { - filetypes = {"sql"}, + filetypes = { 'sql' }, on_attach = function(client, bufnr) client.resolved_capabilities.execute_command = true highlight.diagnositc_config_sign() - require"sqls".setup {picker = "telescope"} -- or default + require('sqls').setup({ picker = 'telescope' }) -- or default end, - flags = {allow_incremental_sync = true, debounce_text_changes = 500}, + flags = { allow_incremental_sync = true, debounce_text_changes = 500 }, settings = { - cmd = {"sqls", "-config", "$HOME/.config/sqls/config.yml"} + cmd = { 'sqls', '-config', '$HOME/.config/sqls/config.yml' }, -- alterantively: -- connections = { -- { @@ -201,92 +205,124 @@ local setups = { -- datasourcename = 'host=127.0.0.1 port=5432 user=postgres password=password dbname=user_db sslmode=disable', -- }, -- }, - } + }, }, sumneko_lua = { - cmd = {"lua-language-server"}, - filetypes = {"lua"}, + cmd = { 'lua-language-server' }, + filetypes = { 'lua' }, on_attach = on_attach, - flags = {allow_incremental_sync = true, debounce_text_changes = 500}, + flags = { allow_incremental_sync = true, debounce_text_changes = 500 }, settings = { Lua = { runtime = { -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) - version = "LuaJIT", + version = 'LuaJIT', -- Setup your lua path - path = vim.split(package.path, ";") + path = vim.split(package.path, ';'), }, diagnostics = { enable = true, -- Get the language server to recognize the `vim` global - globals = {"vim", "describe", "it", "before_each", "after_each", "teardown", "pending"} + globals = { 'vim', 'describe', 'it', 'before_each', 'after_each', 'teardown', 'pending' }, }, - completion = {callSnippet = "Both"}, + completion = { callSnippet = 'Both' }, workspace = { -- Make the server aware of Neovim runtime files library = library, maxPreload = 2000, - preloadFileSize = 40000 + preloadFileSize = 40000, }, - telemetry = {enable = false} - } + telemetry = { enable = false }, + }, }, on_new_config = function(cfg, root) local libs = vim.tbl_deep_extend('force', {}, library) libs[root] = nil cfg.settings.Lua.workspace.library = libs return cfg - end + end, }, pyright = { on_attach = on_attach, - cmd = {"pyright-langserver", "--stdio"}, - filetypes = {"python"}, - flags = {allow_incremental_sync = true, debounce_text_changes = 500}, + cmd = { 'pyright-langserver', '--stdio' }, + filetypes = { 'python' }, + flags = { allow_incremental_sync = true, debounce_text_changes = 500 }, settings = { python = { - formatting = {provider = 'black'}, + formatting = { provider = 'black' }, analysis = { autoSearchPaths = true, useLibraryCodeForTypes = true, - diagnosticMode = "workspace" - } - } - } + diagnosticMode = 'workspace', + }, + }, + }, }, ccls = { on_attach = on_attach, init_options = { - compilationDatabaseDirectory = "build", + compilationDatabaseDirectory = 'build', root_dir = [[ util.root_pattern("compile_commands.json", "compile_flags.txt", "CMakeLists.txt", "Makefile", ".git") or util.path.dirname ]], - index = {threads = 2}, - clang = {excludeArgs = {"-frounding-math"}} + index = { threads = 2 }, + clang = { excludeArgs = { '-frounding-math' } }, }, - flags = {allow_incremental_sync = true} + flags = { allow_incremental_sync = true }, }, jdtls = { settings = { - java = {signatureHelp = {enabled = true}, contentProvider = {preferred = 'fernflower'}} - } - } + java = { signatureHelp = { enabled = true }, contentProvider = { preferred = 'fernflower' } }, + }, + }, } setups.sumneko_lua = vim.tbl_deep_extend('force', luadev, setups.sumneko_lua) local servers = { - "angularls", "gopls", "tsserver", "flow", "bashls", "dockerls", "julials", "pylsp", "pyright", - "jedi_language_server", "jdtls", "sumneko_lua", "vimls", "html", "jsonls", "solargraph", "cssls", - "yamlls", "clangd", "ccls", "sqls", "denols", "graphql", "dartls", "dotls", - "kotlin_language_server", "nimls", "intelephense", "vuels", "phpactor", "omnisharp", - "r_language_server", "rust_analyzer", "terraformls", "svelte", "texlab", "clojure_lsp" + 'angularls', + 'gopls', + 'tsserver', + 'flow', + 'bashls', + 'dockerls', + 'julials', + 'pylsp', + 'pyright', + 'jedi_language_server', + 'jdtls', + 'sumneko_lua', + 'vimls', + 'html', + 'jsonls', + 'solargraph', + 'cssls', + 'yamlls', + 'clangd', + 'ccls', + 'sqls', + 'denols', + 'graphql', + 'dartls', + 'dotls', + 'kotlin_language_server', + 'nimls', + 'intelephense', + 'vuels', + 'phpactor', + 'omnisharp', + 'r_language_server', + 'rust_analyzer', + 'terraformls', + 'svelte', + 'texlab', + 'clojure_lsp', } local has_lspinst = false if config.lsp_installer == true then - has_lspinst, _ = pcall(require, "nvim-lsp-installer") + has_lspinst, _ = pcall(require, 'nvim-lsp-installer') if has_lspinst then - local srvs = require'nvim-lsp-installer.servers'.get_installed_servers() + local srvs = require('nvim-lsp-installer.servers').get_installed_servers() log('lsp_installered servers', srvs) if #srvs > 0 then servers = srvs @@ -300,7 +336,7 @@ end local ng_default_cfg = { on_attach = on_attach, - flags = {allow_incremental_sync = true, debounce_text_changes = 1000} + flags = { allow_incremental_sync = true, debounce_text_changes = 1000 }, } local configs = {} @@ -315,7 +351,7 @@ local function load_cfg(ft, client, cfg, loaded) log(ft, client, loaded) if lspconfig[client] == nil then - log("not supported by nvim", client) + log('not supported by nvim', client) return end @@ -342,26 +378,25 @@ local function load_cfg(ft, client, cfg, loaded) for _, c in pairs(loaded) do if client == c then -- loaded - trace(client, "already been loaded for", ft, loaded) + trace(client, 'already been loaded for', ft, loaded) return end end if lspconfig[client] == nil then - error("client " .. client .. " not supported") + error('client ' .. client .. ' not supported') return end - trace("load cfg", cfg) + trace('load cfg', cfg) log('lspconfig setup') -- log(lspconfig.available_servers()) -- force reload with config lspconfig[client].setup(cfg) vim.defer_fn(function() - vim.cmd([[doautocmd FileType ]] .. ft) end, 100) - log(client, "loading for", ft) + log(client, 'loading for', ft) end -- need to verify the lsp server is up end @@ -378,9 +413,9 @@ local function lsp_startup(ft, retry, user_lsp_opts) capabilities.textDocument.completion.completionItem.labelDetailsSupport = true capabilities.textDocument.completion.completionItem.deprecatedSupport = true capabilities.textDocument.completion.completionItem.commitCharactersSupport = true - capabilities.textDocument.completion.completionItem.tagSupport = {valueSet = {1}} + capabilities.textDocument.completion.completionItem.tagSupport = { valueSet = { 1 } } capabilities.textDocument.completion.completionItem.resolveSupport = { - properties = {'documentation', 'detail', 'additionalTextEdits'} + properties = { 'documentation', 'detail', 'additionalTextEdits' }, } capabilities.workspace.configuration = true @@ -396,13 +431,13 @@ local function lsp_startup(ft, retry, user_lsp_opts) if lspclient.name then lspclient = lspclient.name else - warn("incorrect set for lspclient", vim.inspect(lspclient)) + warn('incorrect set for lspclient', vim.inspect(lspclient)) goto continue end end if user_lsp_opts[lspclient] ~= nil and user_lsp_opts[lspclient].filetypes ~= nil then if not vim.tbl_contains(user_lsp_opts[lspclient].filetypes, ft) then - trace("ft", ft, "disabled for", lspclient) + trace('ft', ft, 'disabled for', lspclient) goto continue end end @@ -412,30 +447,30 @@ local function lsp_startup(ft, retry, user_lsp_opts) end if vim.tbl_contains(config.lsp.disable_lsp or {}, lspclient) then - log("disable lsp", lspclient) + log('disable lsp', lspclient) goto continue end local default_config = {} log(lspclient) if lspconfig[lspclient] == nil then - print("lspclient", lspclient, "no longer support by lspconfig, please submit an issue") + print('lspclient', lspclient, 'no longer support by lspconfig, please submit an issue') goto continue end if lspconfig[lspclient].document_config and lspconfig[lspclient].document_config.default_config then default_config = lspconfig[lspclient].document_config.default_config else - print("missing document config for client: ", lspclient) + print('missing document config for client: ', lspclient) goto continue end - default_config = vim.tbl_deep_extend("force", default_config, ng_default_cfg) + default_config = vim.tbl_deep_extend('force', default_config, ng_default_cfg) local cfg = setups[lspclient] or {} - cfg = vim.tbl_deep_extend("keep", cfg, default_config) + cfg = vim.tbl_deep_extend('keep', cfg, default_config) -- filetype disabled if not vim.tbl_contains(cfg.filetypes or {}, ft) then - trace("ft", ft, "disabled for", lspclient) + trace('ft', ft, 'disabled for', lspclient) goto continue end @@ -447,10 +482,10 @@ local function lsp_startup(ft, retry, user_lsp_opts) log(lspclient, config.lsp.disable_format_cap) if vim.tbl_contains(config.lsp.disable_format_cap or {}, lspclient) then - log("fileformat disabled for ", lspclient) + log('fileformat disabled for ', lspclient) disable_fmt = true end - cfg = vim.tbl_deep_extend("force", cfg, user_lsp_opts[lspclient]) + cfg = vim.tbl_deep_extend('force', cfg, user_lsp_opts[lspclient]) if config.combined_attach == nil then cfg.on_attach = function(client, bufnr) on_attach(client, bufnr) @@ -459,9 +494,9 @@ local function lsp_startup(ft, retry, user_lsp_opts) end end end - if config.combined_attach == "mine" then + if config.combined_attach == 'mine' then if config.on_attach == nil then - error("on attach not provided") + error('on attach not provided') end cfg.on_attach = function(client, bufnr) config.on_attach(client, bufnr) @@ -470,7 +505,7 @@ local function lsp_startup(ft, retry, user_lsp_opts) end end end - if config.combined_attach == "both" then + if config.combined_attach == 'both' then cfg.on_attach = function(client, bufnr) if config.on_attach then config.on_attach(client, bufnr) @@ -487,7 +522,7 @@ local function lsp_startup(ft, retry, user_lsp_opts) end cfg.on_init = function(client) if client and client.config and client.config.settings then - client.notify('workspace/didChangeConfiguration', {settings = client.config.settings}) + client.notify('workspace/didChangeConfiguration', { settings = client.config.settings }) end end end @@ -495,7 +530,7 @@ local function lsp_startup(ft, retry, user_lsp_opts) log('loading', lspclient, 'name', lspconfig[lspclient].name, 'has lspinst', has_lspinst) -- start up lsp if has_lspinst and _NgConfigValues.lsp_installer then - local installed, installer_cfg = require("nvim-lsp-installer.servers").get_server(lspconfig[lspclient].name) + local installed, installer_cfg = require('nvim-lsp-installer.servers').get_server(lspconfig[lspclient].name) log('lsp server', installer_cfg, lspconfig[lspclient].name) if installed and installer_cfg then @@ -511,12 +546,30 @@ local function lsp_startup(ft, retry, user_lsp_opts) ::continue:: end + if not _NG_Loaded['null_ls'] then + local nulls_cfg = user_lsp_opts['null_ls'] + if nulls_cfg then + local cfg = {} + cfg = vim.tbl_deep_extend('keep', cfg, nulls_cfg) + cfg.on_attach = function(client, bufnr) + if efm_cfg.on_attach then + efm_cfg.on_attach(client, bufnr) + end + on_attach(client, bufnr) + end + + lspconfig['null-ls'].setup(cfg) + log('null-ls loading') + _NG_Loaded['null-ls'] = true + configs['null-ls'] = cfg + end + end + if not _NG_Loaded['efm'] then local efm_cfg = user_lsp_opts['efm'] if efm_cfg then - local cfg = {} - cfg = vim.tbl_deep_extend("keep", cfg, efm_cfg) + cfg = vim.tbl_deep_extend('keep', cfg, efm_cfg) cfg.on_attach = function(client, bufnr) if efm_cfg.on_attach then efm_cfg.on_attach(client, bufnr) @@ -548,58 +601,67 @@ local function get_cfg(client) end local function setup(user_opts) - log(user_opts) + local ft = vim.bo.filetype - local bufnr = tostring(vim.api.nvim_get_current_buf()) - if _LoadedFiletypes[ft .. bufnr] then - log("navigator was loaded for ft", ft) + local bufnr = vim.api.nvim_get_current_buf() + local uri = vim.uri_from_bufnr(bufnr) + + if uri == 'file://' or uri == 'file:///' then + log('skip loading for ft ', ft, uri) + return + end + log(user_opts) + log(uri) + if _LoadedFiletypes[ft .. tostring(bufnr)] then + log('navigator was loaded for ft', ft) return end local disable_ft = { - "NvimTree", "guihua", "clap_input", "clap_spinner", "vista", "vista_kind", "TelescopePrompt", - "guihua_rust", "csv", "txt", "defx", "packer" + 'NvimTree', + 'guihua', + 'clap_input', + 'clap_spinner', + 'vista', + 'vista_kind', + 'TelescopePrompt', + 'guihua_rust', + 'csv', + 'txt', + 'defx', + 'packer', } for i = 1, #disable_ft do if ft == disable_ft[i] or _LoadedFiletypes[ft] then - trace("navigator disabled for ft or it is loaded", ft) + trace('navigator disabled for ft or it is loaded', ft) return end end if user_opts ~= nil then - log("navigator user setup", user_opts) + log('navigator user setup', user_opts) end trace(debug.traceback()) if #vim.lsp.buf_get_clients() > 0 and user_opts == nil then - log("already setup") + log('already setup') return end user_opts = user_opts or config -- incase setup was triggered from autocmd if ft == nil then - ft = vim.api.nvim_buf_get_option(0, "filetype") + ft = vim.api.nvim_buf_get_option(bufnr, 'filetype') end - if ft == nil or ft == "" then + if ft == nil or ft == '' then + log('nil filetype, callback') vim.defer_fn(function() setup(user_opts) - end, 500) - - log("nil filetype, callback") + end, 200) return end local retry = true - local bufnr = vim.fn.bufnr() - local uri = vim.uri_from_bufnr(bufnr) - - if uri == 'file://' or uri == 'file:///' then - log("skip loading for ft ", ft, uri) - return - end - trace('setup', user_opts) - log("loading for ft ", ft, uri) + log('loading for ft ', ft, uri) highlight.diagnositc_config_sign() highlight.add_highlight() local lsp_opts = user_opts.lsp @@ -609,10 +671,12 @@ local function setup(user_opts) if slua and not slua.cmd then if slua.sumneko_root_path and slua.sumneko_binary then lsp_opts.sumneko_lua.cmd = { - slua.sumneko_binary, "-E", slua.sumneko_root_path .. "/main.lua" + slua.sumneko_binary, + '-E', + slua.sumneko_root_path .. '/main.lua', } else - lsp_opts.sumneko_lua.cmd = {"lua-language-server"} + lsp_opts.sumneko_lua.cmd = { 'lua-language-server' } end end end @@ -621,18 +685,40 @@ local function setup(user_opts) --- if code line enabled if _NgConfigValues.lsp.code_lens then - require("navigator.codelens").setup() + require('navigator.codelens').setup() end _LoadedFiletypes[ft] = true -- _LoadedFiletypes[ft] = vim.tbl_extend("keep", _LoadedFiletypes[ft] or {}, {ft}) - end -- append lsps to servers function add_servers(lsps) - vim.validate {lsps = {lsps, 't'}} + vim.validate({ lsps = { lsps, 't' } }) vim.list_extend(servers, lsps) end -return {setup = setup, get_cfg = get_cfg, lsp = servers, add_servers = add_servers} +function on_filetype() + + local bufnr = vim.api.nvim_get_current_buf() + local uri = vim.uri_from_bufnr(bufnr) + + local ft = vim.bo.filetype + if ft == nil then return end + if uri == 'file://' or uri == 'file:///' then + log('skip loading for ft ', ft, uri) + return + end + + + log(uri) + + + local wids = vim.fn.win_findbuf(bufnr) + if wins == nil or wins == {} then + log('buf not shown return') + end + setup() +end + +return { setup = setup, get_cfg = get_cfg, lsp = servers, add_servers = add_servers , on_filetype = on_filetype} diff --git a/lua/navigator/lspclient/mapping.lua b/lua/navigator/lspclient/mapping.lua index b8cf04d..5be93d7 100644 --- a/lua/navigator/lspclient/mapping.lua +++ b/lua/navigator/lspclient/mapping.lua @@ -215,12 +215,12 @@ M.toggle_lspformat = function(on) if on == nil then print("format on save true") end - vim.cmd([[set eventignore=""]]) + vim.cmd([[set eventignore-=BufWritePre]]) else if on == nil then print("format on save false") end - vim.cmd([[set eventignore=BufWritePre]]) + vim.cmd([[set eventignore+=BufWritePre]]) end end diff --git a/lua/navigator/lspwrapper.lua b/lua/navigator/lspwrapper.lua index fc72486..00a283c 100644 --- a/lua/navigator/lspwrapper.lua +++ b/lua/navigator/lspwrapper.lua @@ -1,36 +1,36 @@ local M = {} -local util = require "navigator.util" +local util = require('navigator.util') local nvim_0_6 = util.nvim_0_6() -local gutil = require "guihua.util" -local lsp = require "vim.lsp" +local gutil = require('guihua.util') +local lsp = require('vim.lsp') local api = vim.api -local log = require"navigator.util".log -local lerr = require"navigator.util".error -local trace = require"navigator.util".trace -local symbol_kind = require"navigator.lspclient.lspkind".symbol_kind +local log = require('navigator.util').log +local lerr = require('navigator.util').error +local trace = require('navigator.util').trace +local symbol_kind = require('navigator.lspclient.lspkind').symbol_kind local cwd = vim.loop.cwd() -local is_win = vim.loop.os_uname().sysname:find("Windows") +local is_win = vim.loop.os_uname().sysname:find('Windows') -local path_sep = require"navigator.util".path_sep() -local path_cur = require"navigator.util".path_cur() +local path_sep = require('navigator.util').path_sep() +local path_cur = require('navigator.util').path_cur() cwd = gutil.add_pec(cwd) local ts_nodes = require('navigator.lru').new(1000, 1024 * 1024) local ts_nodes_time = require('navigator.lru').new(1000) -local TS_analysis_enabled = require"navigator".config_values().treesitter_analysis +local TS_analysis_enabled = require('navigator').config_values().treesitter_analysis -- extract symbol from range function M.get_symbol(text, range) if range == nil then - return "" + return '' end return string.sub(text, range.start.character + 1, range['end'].character) end local function check_lhs(text, symbol) - local find = require'guihua.util'.word_find + local find = require('guihua.util').word_find local s = find(text, symbol) local eq = string.find(text, '=') or 0 local eq2 = string.find(text, '==') or 0 @@ -40,7 +40,7 @@ local function check_lhs(text, symbol) return false end if s < eq and eq ~= eq2 then - trace(symbol, "modified") + trace(symbol, 'modified') end if eq == eq3 + 1 then return false @@ -54,18 +54,20 @@ local function check_lhs(text, symbol) end function M.lines_from_locations(locations, include_filename) - local fnamemodify = (function(filename) + local fnamemodify = function(filename) if include_filename then - return vim.fn.fnamemodify(filename, ":~:.") .. ":" + return vim.fn.fnamemodify(filename, ':~:.') .. ':' else - return "" + return '' end - end) + end local lines = {} for _, loc in ipairs(locations) do - table.insert(lines, - (fnamemodify(loc["filename"]) .. loc["lnum"] .. ":" .. loc["col"] .. ": " .. vim.trim(loc["text"]))) + table.insert( + lines, + (fnamemodify(loc['filename']) .. loc['lnum'] .. ':' .. loc['col'] .. ': ' .. vim.trim(loc['text'])) + ) end return lines @@ -83,18 +85,18 @@ function M.symbols_to_items(result) item.name = result[i].name -- symbol name item.text = result[i].name if kind ~= nil then - item.text = kind .. ": " .. item.text + item.text = kind .. ': ' .. item.text end item.filename = vim.uri_to_fname(item.uri) 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) + 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 + item.text = ' ' .. item.containerName .. item.text end table.insert(locations, item) end @@ -131,9 +133,9 @@ function M.check_capabilities(feature, client_id) return true else if #clients == 0 then - log("LSP: no client attached") + log('LSP: no client attached') else - trace("LSP: server does not support " .. feature) + trace('LSP: server does not support ' .. feature) end return false end @@ -145,7 +147,7 @@ function M.call_sync(method, params, opts, handler) local results_lsp, err = lsp.buf_request_sync(0, method, params, opts.timeout or vim.g.navtator_timeout or 1000) if nvim_0_6() then - handler(err, extract_result(results_lsp), {method = method}, nil) + handler(err, extract_result(results_lsp), { method = method }, nil) else handler(err, method, extract_result(results_lsp), nil, nil) end @@ -163,18 +165,18 @@ end local function ts_functions(uri) local unload_bufnr - local ts_enabled, _ = pcall(require, "nvim-treesitter.locals") + local ts_enabled, _ = pcall(require, 'nvim-treesitter.locals') if not ts_enabled or not TS_analysis_enabled then - lerr("ts not enabled") + lerr('ts not enabled') return nil end - local ts_func = require"navigator.treesitter".buf_func + local ts_func = require('navigator.treesitter').buf_func local bufnr = vim.uri_to_bufnr(uri) local x = os.clock() trace(ts_nodes) local tsnodes = ts_nodes:get(uri) if tsnodes ~= nil then - trace("get data from cache") + trace('get data from cache') local t = ts_nodes_time:get(uri) or 0 local fname = vim.uri_to_fname(uri) local modified = vim.fn.getftime(fname) @@ -188,7 +190,7 @@ local function ts_functions(uri) end local unload = false if not api.nvim_buf_is_loaded(bufnr) then - trace("! load buf !", uri, bufnr) + trace('! load buf !', uri, bufnr) vim.fn.bufload(bufnr) -- vim.api.nvim_buf_detach(bufnr) -- if user opens the buffer later, it prevents user attach event unload = true @@ -201,35 +203,35 @@ local function ts_functions(uri) ts_nodes:set(uri, funcs) ts_nodes_time:set(uri, os.time()) trace(funcs, ts_nodes:get(uri)) - trace(string.format("elapsed time: %.4f\n", os.clock() - x)) -- how long it tooks + trace(string.format('elapsed time: %.4f\n', os.clock() - x)) -- how long it tooks return funcs, unload_bufnr end local function ts_definition(uri, range) local unload_bufnr - local ts_enabled, _ = pcall(require, "nvim-treesitter.locals") + local ts_enabled, _ = pcall(require, 'nvim-treesitter.locals') if not ts_enabled or not TS_analysis_enabled then - lerr("ts not enabled") + lerr('ts not enabled') return nil end local key = string.format('%s_%d_%d_%d', uri, range.start.line, range.start.character, range['end'].line) - local tsnode = ts_nodes:get(key) + local tsnodes = ts_nodes:get(key) local ftime = ts_nodes_time:get(key) local fname = vim.uri_to_fname(uri) local modified = vim.fn.getftime(fname) if tsnodes and modified <= ftime then log('ts def from cache') - return tsnode + return tsnodes end - local ts_def = require"navigator.treesitter".find_definition + local ts_def = require('navigator.treesitter').find_definition local bufnr = vim.uri_to_bufnr(uri) local x = os.clock() trace(ts_nodes) local unload = false if not api.nvim_buf_is_loaded(bufnr) then - log("! load buf !", uri, bufnr) + log('! load buf !', uri, bufnr) vim.fn.bufload(bufnr) unload = true end @@ -238,7 +240,7 @@ local function ts_definition(uri, range) if unload then unload_bufnr = bufnr end - trace(string.format(" ts def elapsed time: %.4f\n", os.clock() - x), def_range) -- how long it takes + trace(string.format(' ts def elapsed time: %.4f\n', os.clock() - x), def_range) -- how long it takes ts_nodes:set(key, def_range) ts_nodes_time:set(key, x) return def_range, unload_bufnr @@ -279,7 +281,7 @@ local function slice_locations(locations, max_items) if #locations > max_items then local uri = locations[max_items] for i = max_items + 1, #locations do - if uri ~= locations[i] and not brk then + if uri ~= locations[i] then cut = i break end @@ -291,15 +293,17 @@ local function slice_locations(locations, max_items) second_part = vim.list_slice(locations, cut + 1, #locations) end return first_part, second_part - end local function test_locations() local locations = { - {uri = '1', range = {start = {line = 1}}}, {uri = '2', range = {start = {line = 2}}}, - {uri = '2', range = {start = {line = 3}}}, {uri = '1', range = {start = {line = 3}}}, - {uri = '1', range = {start = {line = 4}}}, {uri = '3', range = {start = {line = 4}}}, - {uri = '3', range = {start = {line = 4}}} + { uri = '1', range = { start = { line = 1 } } }, + { uri = '2', range = { start = { line = 2 } } }, + { uri = '2', range = { start = { line = 3 } } }, + { uri = '1', range = { start = { line = 3 } } }, + { uri = '1', range = { start = { line = 4 } } }, + { uri = '3', range = { start = { line = 4 } } }, + { uri = '3', range = { start = { line = 4 } } }, } local second_part order_locations(locations) @@ -310,7 +314,7 @@ end function M.locations_to_items(locations, max_items) max_items = max_items or 100000 -- if not locations or vim.tbl_isempty(locations) then - print("list not avalible") + print('list not avalible') return end local width = 4 @@ -325,12 +329,14 @@ function M.locations_to_items(locations, max_items) locations, second_part = slice_locations(locations, max_items) trace(locations) + vim.cmd([[set eventignore+=FileType]]) + local cut = -1 local unload_bufnrs = {} for i, loc in ipairs(locations) do local funcs = nil - local item = lsp.util.locations_to_items({loc})[1] + local item = lsp.util.locations_to_items({ loc })[1] -- log(item) item.range = locations[i].range or locations[i].targetRange item.uri = locations[i].uri or locations[i].targetUri @@ -376,7 +382,7 @@ function M.locations_to_items(locations, max_items) local def = uri_def[item.uri] if def and def.start and item.range then if def.start.line == item.range.start.line then - log("ts def in current line") + log('ts def in current line') item.definition = true end end @@ -400,17 +406,19 @@ function M.locations_to_items(locations, max_items) vim.defer_fn(function() for i, bufnr_unload in ipairs(unload_bufnrs) do if api.nvim_buf_is_loaded(bufnr_unload) and i > 10 then - api.nvim_buf_delete(bufnr_unload, {unload = true}) + api.nvim_buf_delete(bufnr_unload, { unload = true }) end end end, 100) end + vim.cmd([[set eventignore-=FileType]]) + return items, width + 24, second_part -- TODO handle long line? end function M.apply_action(action, ctx, client) - assert(action ~= nil, "action must not be nil") + assert(action ~= nil, 'action must not be nil') if action.edit then vim.lsp.util.apply_workspace_edit(action.edit) end @@ -426,7 +434,6 @@ function M.apply_action(action, ctx, client) end end log(action) - end local function apply_action(action, client, ctx) @@ -466,9 +473,12 @@ function M.on_user_choice(action_tuple, ctx) -- local client = vim.lsp.get_client_by_id(action_tuple[1]) local action = action_tuple[2] - if not action.edit and client and type(client.resolved_capabilities.code_action) == 'table' - and client.resolved_capabilities.code_action.resolveProvider then - + if + not action.edit + and client + and type(client.resolved_capabilities.code_action) == 'table' + and client.resolved_capabilities.code_action.resolveProvider + then client.request('codeAction/resolve', action, function(err, resolved_action) if err then vim.notify(err.code .. ': ' .. err.message, vim.log.levels.ERROR) @@ -483,7 +493,7 @@ end function M.symbol_to_items(locations) if not locations or vim.tbl_isempty(locations) then - print("list not avalible") + print('list not avalible') return end @@ -520,7 +530,6 @@ function M.request(method, hdlr) -- e.g textDocument/reference vim.lsp.for_each_buffer_client(bufnr, function(client, client_id, _bufnr) client.request(method, ref_params, hdlr, bufnr) end) - end return M diff --git a/selene.toml b/selene.toml new file mode 100644 index 0000000..7312a91 --- /dev/null +++ b/selene.toml @@ -0,0 +1 @@ +std="vim" diff --git a/stylua.toml b/stylua.toml new file mode 100644 index 0000000..a14776f --- /dev/null +++ b/stylua.toml @@ -0,0 +1,4 @@ +indent_type = "Spaces" +indent_width = 2 +column_width = 120 +quote_style = "AutoPreferSingle" diff --git a/thread.lua b/thread.lua new file mode 100644 index 0000000..827b033 --- /dev/null +++ b/thread.lua @@ -0,0 +1,20 @@ +local func = function(p, uv) + local before = os.time() + local async + async = uv.new_async(function(a, b, c) + p('in async notify callback') + p(a, b, c) + uv.close(async) + end) + local args = {500, 'string', nil, false, 5, "helloworld", async} + local unpack = unpack or table.unpack + uv.new_thread(function(num, s, null, bool, five, hw, asy) + local uv2 = require 'luv' + uv2.async_send(asy, 'a', true, 250) + uv2.sleep(1000) + end, unpack(args)):join() + local elapsed = (os.time() - before) * 1000 + assert(elapsed >= 1000, "elapsed should be at least delay ") +end + +func(print, vim.loop) diff --git a/vim.toml b/vim.toml new file mode 100644 index 0000000..f63f3f6 --- /dev/null +++ b/vim.toml @@ -0,0 +1,53 @@ +[selene] +base = "lua51" +name = "vim" + +[vim] +any = true + +[_G] +property = true +writable = "new-fields" + +[debug] +property = true + +[[describe.args]] +type = "string" +[[describe.args]] +type = "function" + +[[it.args]] +type = "string" +[[it.args]] +type = "function" + +[[before_each.args]] +type = "function" +[[after_each.args]] +type = "function" + +[assert.is_not] +any = true + +[[assert.equals.args]] +type = "any" +[[assert.equals.args]] +type = "any" +[[assert.equals.args]] +type = "any" +required = false + +[[assert.same.args]] +type = "any" +[[assert.same.args]] +type = "any" + +[[assert.truthy.args]] +type = "any" + +[[assert.spy.args]] +type = "any" + +[[assert.stub.args]] +type = "any"