neodev.nvim icon indicating copy to clipboard operation
neodev.nvim copied to clipboard

bug: Can't get completion for plugins

Open rsb177 opened this issue 2 years ago • 15 comments

Did you check docs and existing issues?

  • [X] I have read all the neodev.nvim docs
  • [X] I have searched the existing issues of neodev.nvim
  • [X] I have searched the existing issues of plugins related to this issue

Neovim version (nvim -v)

0.9.0

Operating system/version

Windows 10/WSL Ubuntu

Describe the bug

I'm using the basic config for neodev and was able to get completion for neovim itself, but it doesn't seem to recognize my plugins. I'm not sure if it can't find them or there's a config i'm missing.

Steps To Reproduce

  1. use below repro.lua
  2. try to reference something from a plugin (i.e. lazy = require ("lazy"))

Expected Behavior

Get completion options for plugins.

Repro

-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify("./.repro", ":p")

-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
	vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
	vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
	"folke/tokyonight.nvim",
	"folke/neodev.nvim",
	{
		"VonHeikemen/lsp-zero.nvim",
		branch = "v2.x",
		dependencies = {
			-- LSP Support
			{ "neovim/nvim-lspconfig" }, -- Required
			{
				-- Optional
				"williamboman/mason.nvim",
				build = function()
					pcall(vim.cmd, "MasonUpdate")
				end,
			},
			{ "williamboman/mason-lspconfig.nvim" }, -- Optional

			-- Autocompletion
			{
				"hrsh7th/nvim-cmp",
				dependencies = {
					"onsails/lspkind.nvim",
				},
			}, -- Required
			{ "hrsh7th/cmp-nvim-lsp" }, -- Required
			{ "L3MON4D3/LuaSnip" }, -- Required

			{ "j-hui/fidget.nvim", opts = {} }, -- Optional
			-- Additional lua configuration, makes nvim stuff amazing!
		},
		config = function()
			local lsp = require("lsp-zero").preset({
				manage_nvim_cmp = {
					set_sources = "recommended",
					set_extra_mappings = true,
				},
			})

			lsp.on_attach(function(client, bufnr)
				lsp.default_keymaps({ buffer = bufnr })

				vim.keymap.set({ "n", "x" }, "<A-S-f>", function()
					vim.lsp.buf.format({ async = false, timeout_ms = 10000 })
				end, { buffer = bufnr, desc = "LSP: Format code" })
			end)
			lsp.ensure_installed({
				"tsserver",
				"eslint",
				"pyright",
				"ruff_lsp",
				"tflint",
			})

			local opts = {
				servers = {
					pyright = {
						settings = {
							python = {
								analysis = {
									typeCheckingMode = "off",
									autoSearchPaths = true,
									useLibraryCodeForTypes = true,
									diagnosticMode = "workspace",
								},
							},
						},
					},
					ruff_lsp = {
						init_options = {
							settings = {
								args = { "--max-line-length=80" },
							},
						},
					},
				},
			}
			-- (Optional) Configure lua language server for neovim
			require("lspconfig").lua_ls.setup(lsp.nvim_lua_ls(opts))

			lsp.setup()
			local cmp = require("cmp")
			local lspkind = require("lspkind")
			cmp.setup({
				preselect = "item",
				mapping = cmp.mapping.preset.insert({
					-- ["<Tab>"] = cmp_action.tab_complete(),
					-- ["<S-Tab>"] = cmp_action.select_prev_or_fallback(),
					["<CR>"] = cmp.mapping.confirm({ select = true }),
				}),
				formatting = {
					format = lspkind.cmp_format({
						mode = "symbol", -- show only symbol annotations
						maxwidth = 50, -- prevent the popup from showing more than provided characters (e.g 50 will not show more than 50 characters)
						ellipsis_char = "...", -- when popup menu exceed maxwidth, the truncated part would show ellipsis_char instead (must define maxwidth first)
					}),
				},
			})
		end,
	}, -- add any other plugins here
}
require("lazy").setup(plugins, {
	root = root .. "/plugins",
})

vim.cmd.colorscheme("tokyonight")
-- add anything else here

rsb177 avatar May 31 '23 19:05 rsb177

Here are some helpful things for those who might find this issue:

First, you can inspect whether the lua_ls language server has the workspace configured properly:

:lua= vim.lsp.get_active_clients({ name = "lua_ls" })[1].config.settings.Lua

EDIT: Fixed typo, ~get_clients()~ => get_active_clients()

This table should contain library = { ... } whose entries being paths to lua lib, e.g.

"$PLUGINS/neodev.nvim/types/nightly",
"$VIMRUNTIME/lua",
"$PLUGINS/your_plugin_1/lua",
"$PLUGINS/your_plugin_2/lua",
...

Second, there is a line that I find quite unexpected in neodev.lsp config https://github.com/folke/neodev.nvim/blob/main/lua/neodev/lsp.lua#L55 where opts.library.enabled is overwritten by util.is_nvim_config() (if that's the case, why there's opts.library.plugins config in the setup call?) If the lua file you opened that triggered startup of lua_ls is not a neovim config (e.g., nvim/config/lua/...) it will disable scanning of plugin lua runtime paths. I think the logic here should be improved.

Indeed, I can see that the completions for neovim plugins work OK when I edit nvim config files (e.g., nvim/lua/.../*.lua), but no libraries were added when I add other lua files -- like when you are openining a lua lib file from any neovim plugin.

Finally, maybe as a workaround, you can enforce the config table like the following as mentioned in the README:

    require("neodev").setup {
      -- Always add neovim plugins into lua_ls library, even if not neovim config
      override = function(root_dir, library)
        library.enabled = true
        library.plugins = true
      end,
    }

NOTE: This might be not suitable for non-neovim-config lua projects, but you are welcomed to write your own logic depending on root_dir.

wookayin avatar Aug 10 '23 01:08 wookayin

Here are some helpful things for those who might find this issue:

First, you can inspect whether the lua_ls language server has the workspace configured properly:

:lua= vim.tbl_filter(function(l) return l.name == 'lua_ls' end, vim.lsp.get_clients())[1].config.settings.Lua

@wookayin

i copy / pasted the command you posted above and got the below error message probably something wrong on my end, but this is the output i got,

E5108: Error executing lua [string ":lua"]:1: attempt to call field 'get_clients' (a nil value)
stack traceback:
        [string ":lua"]:1: in main chunk

ipatch avatar Aug 13 '23 23:08 ipatch

@ipatch i got the same error. i think get_clients is only available in nightly right now (I'm in 9.1). i tried changing it to get_active_clients...which doesn't error out at least. for the library section under workspace...i just have my runtime and my .config/nvim/lua folder.

rsb177 avatar Aug 17 '23 14:08 rsb177

@ipatch i got the same error. i think get_clients is only available in nightly right now (I'm in 9.1). i tried changing it to get_active_clients...which doesn't error out at least. for the library section under workspace...i just have my runtime and my .config/nvim/lua folder.

thanks for the heads up on that. i built neovim from the git source the other day and sure enough the 0.10-dev build supports that command.

ipatch avatar Aug 17 '23 15:08 ipatch

It should be vim.lsp.get_active_clients() not get_clients(). Very sorry for the typo -- the API has existed since 0.5.0

wookayin avatar Aug 17 '23 15:08 wookayin

after a little more playing around, it looks like my main problem is that my nvim config is symlinked to my dotfiles repo. and i need to set pathStrict = false. if i remove the link and just copy my config, it seems to work. not sure if there's a way to get it to follow sym links.

Also haven't been successful in getting it working even using neoconf when I'm in my dotfiles repo.

rsb177 avatar Aug 17 '23 16:08 rsb177

require('neodev').setup({
  override   = function(_, library)
    library.enabled = true
    library.plugins = true
  end,
  pathStrict = true,
  -- lspconfig  = true
})

this configuration works fine for me. I've found plugins under the lua "namespace".

For me, this works fine:

-- Start typing lua. and the autocompletion return you a list of all the plugins
require("lua.plenary.path") 

25d96b avatar Oct 22 '23 20:10 25d96b

after a little more playing around, it looks like my main problem is that my nvim config is symlinked to my dotfiles repo. and i need to set pathStrict = false. if i remove the link and just copy my config, it seems to work. not sure if there's a way to get it to follow sym links.

Are you saying that pathStrict = false solves your issue? Because it doesn't for me. Plugin autocompletion doesn't work no matter what I try, even though the library entries are correctly set.

calops avatar Nov 14 '23 13:11 calops

Please I need help, I've tried everything that was said on this thread but it doesn't work, when I run the command to see what was added to my lua_ls library path I get nothing. I don't even get completion for the vim global. What did I miss? Do I need to add something to my lsp configuration or maybe to cmp I don't know but nothing seems to work please help

Fobo00 avatar Dec 14 '23 20:12 Fobo00

I'm working on windows 11 and have made sure that neodev gets initialized before lspconfig

Fobo00 avatar Dec 14 '23 20:12 Fobo00

Same issue for me. It works great outside of my dotfiles (like when developing another plugin), but within my dotfiles (which are symlinked) it seems that the workspace.library modules are not read even though they're set correctly.

epwalsh avatar Dec 20 '23 18:12 epwalsh

I was having issues with this but I realised I'd accidentally added some config for neoconf which was disabling neodev. Removing the offending config has fixed neodev and neoconf is working fine too. FWIW my dotfiles are symlinked too

dbatten5 avatar Jan 15 '24 10:01 dbatten5

My dotfyles aren't symlinked so that can't be a problem and I don't have neoconf installed so it's not disabling neodev

Fobo00 avatar Jan 24 '24 18:01 Fobo00

I had this issue, which got resolved once I made sure that neodev is loaded before nvim-lspconfig.

I did that by setting lazy=false when registering neodev.nvim in lazy.nvim.

itsfarseen avatar Jan 28 '24 00:01 itsfarseen

Still no dice for me after trying every single solution proposed here.

calops avatar May 02 '24 08:05 calops