Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter out suggestion based on current typing characters #52

Open
BlueDruddigon opened this issue Apr 15, 2023 · 1 comment
Open

Filter out suggestion based on current typing characters #52

BlueDruddigon opened this issue Apr 15, 2023 · 1 comment

Comments

@BlueDruddigon
Copy link

I'm currently using latest release version of neovim (0.9.0)

I'm follow up this channel to setup lsp servers and completion with nvim-lspconfig, mason-lspconfig.nvim, mason.nvim and nvim-cmp comes up with cmp-nvim-lsp.

The LSP server i've setup is pyright. Current behavior is, when i type down isin, expected by isinstance builtin function in python. but the completion item suggest the np.isinf in the first place in completion menu.

Expected behavior is how to filter out the completion item depends on which user typed, such as the completion items start with isin in the previous examples.

@BlueDruddigon
Copy link
Author

Here is my config of lsp with lazy.nvim package manager

return {
	-- lspconfig
	{
		"neovim/nvim-lspconfig",
		dependencies = {
			{ "folke/neoconf.nvim", cmd = "Neoconf", config = true },
			{ "folke/neodev.nvim", opts = { experimental = { pathStrict = true } } },
			"mason.nvim",
			"williamboman/mason-lspconfig.nvim",
			{
				"tamago324/nlsp-settings.nvim",
				cmd = "LspSettings",
				lazy = true,
				opts = {
					config_home = vim.fn.stdpath("config") .. "/lsp-settings",
					local_settings_dir = ".lsp-settings",
					local_settings_root_markers_fallback = { ".git" },
					append_default_schemas = true,
					loader = "json",
				},
			},
			{ "b0o/SchemaStore.nvim", lazy = true },
			"nvim-navic",
		},
		opts = {
			-- options for vim.diagnostic.config()
			diagnostics = {
				underline = true,
				update_in_insert = false,
				virtual_text = { spacing = 4, prefix = "●" },
				severity_sort = true,
			},
			-- lsp servers
			servers = {
				jsonls = {},
				lua_ls = {
					settings = {
						Lua = {
							telemetry = { enable = false },
							runtime = { version = "LuaJIT" },
							diagnostics = { globals = { "vim" } },
							workspace = {
								library = vim.api.nvim_get_runtime_file("", true),
								checkThirdParty = false,
							},
						},
					},
				},
				-- python
				jedi = {},
				-- js, jsx, ts, tsx
				tsserver = {},
				cssls = {},
				tailwindcss = {},
				astro = {},
			},
		},
		config = function(_, opts)
			-- setup format on save
			local format_on_save = function(buf)
				vim.lsp.buf.format({
					bufnr = buf,
					timeout_ms = 2000,
					filter = function(client)
						return client.name == "null-ls"
					end,
				})
			end

			-- on attach
			local navic = require("nvim-navic")
			local augroup_format = vim.api.nvim_create_augroup("LspFormatting", {})
			vim.api.nvim_create_autocmd("LspAttach", {
				group = vim.api.nvim_create_augroup("UserLspConfig", {}),
				callback = function(args)
					local bufnr = args.buf
					local client = vim.lsp.get_client_by_id(args.data.client_id)

					-- enable completion triggered by <c-x><c-o>
					vim.bo[bufnr].omnifunc = "v:lua.vim.lsp.omnifunc"

					-- navic lsp symbol
					if client.server_capabilities.documentSymbolProvider then
						navic.attach(client, bufnr)
					end

					-- keymappings
					local buf_opts = { buffer = bufnr }
					vim.keymap.set("n", "gd", vim.lsp.buf.definition, buf_opts)
					vim.keymap.set("n", "gD", vim.lsp.buf.declaration, buf_opts)
					vim.keymap.set("n", "K", vim.lsp.buf.hover, buf_opts)
					vim.keymap.set("n", "gI", vim.lsp.buf.implementation, buf_opts)
					vim.keymap.set("n", "gr", vim.lsp.buf.references, buf_opts)
					vim.keymap.set("n", "<leader>D", vim.lsp.buf.type_definition, buf_opts)
					vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, buf_opts)

					if client.supports_method("textDocument/formatting") then
						vim.api.nvim_clear_autocmds({ group = augroup_format, buffer = bufnr })
						vim.api.nvim_create_autocmd("BufWritePre", {
							group = augroup_format,
							buffer = bufnr,
							callback = function()
								format_on_save(bufnr)
							end,
						})
					end
				end,
			})

			-- diagnostics
			for name, icon in pairs(require("user.icons").diagnostics) do
				name = "DiagnosticSign" .. name
				vim.fn.sign_define(name, { text = icon, texthl = name, numhl = "" })
			end
			vim.diagnostic.config(opts.diagnostics)

			local servers = opts.servers
			local capabilities = require("cmp_nvim_lsp").default_capabilities()
			capabilities.textDocument.completion.completionItem.snippetSupport = true
			capabilities.textDocument.completion.completionItem.resolveSupport = {
				properties = {
					"documentation",
					"detail",
					"additionalTextEdits",
				},
			}

			local function setup(server)
				local server_opts = {}
				if server == "jsonls" then
					server_opts = vim.tbl_deep_extend("force", {
						capabilities = vim.deepcopy(capabilities),
						settings = {
							json = {
								schemas = require("schemastore").json.schemas(),
								format = { enable = true },
								validate = { enable = true },
							},
						},
					}, servers["jsonls"])
				else
					server_opts = vim.tbl_deep_extend("force", {
						capabilities = vim.deepcopy(capabilities),
					}, servers[server] or {})
				end
				require("lspconfig")[server].setup(server_opts)
			end

			-- get all the servers that are available through mason-lspconfig
			local have_mason, mslp = pcall(require, "mason-lspconfig")
			local all_mslp_servers = {}
			if have_mason then
				all_mslp_servers = vim.tbl_keys(require("mason-lspconfig.mappings.server").lspconfig_to_package)
			end

			local ensure_installed = {}
			for server, server_opts in pairs(servers) do
				setup(server)
				if vim.tbl_contains(all_mslp_servers, server) then
					ensure_installed[#ensure_installed + 1] = server
				end
			end

			if have_mason then
				mslp.setup({ ensure_installed = ensure_installed })
				mslp.setup_handlers({ setup })
			end
		end,
	},

	-- formatters
	{
		"jose-elias-alvarez/null-ls.nvim",
		event = { "BufReadPre", "BufNewFile" },
		lazy = true,
		opts = function()
			local nls = require("null-ls")
			return {
				sources = {
					-- python
					nls.builtins.diagnostics.pylint,
					nls.builtins.diagnostics.flake8,
					nls.builtins.formatting.isort,
					nls.builtins.formatting.yapf,
					nls.builtins.formatting.autopep8,
					-- lua
					nls.builtins.formatting.stylua,
					-- js, jsx, ts, tsx
					nls.builtins.diagnostics.eslint,
					nls.builtins.formatting.prettierd,
					-- markdown
					nls.builtins.diagnostics.write_good,
					nls.builtins.code_actions.cspell,
					nls.builtins.code_actions.proselint,
				},
			}
		end,
	},

	-- cmdline tools and lsp servers
	{
		"williamboman/mason.nvim",
		opts = {
			ensure_installed = {
				-- lua
				"stylua",
				-- python
				"pylint",
				"flake8",
				"yapf",
				"isort",
				"autopep8",
				-- markdown
				"write-good",
				"cspell",
				"proselint",
				-- js, jsx, ts, tsx
				"eslint-lsp",
				"prettierd",
			},
			pip = {
				upgrade_pip = true,
			},
		},
		config = function(_, opts)
			require("mason").setup(opts)
			local mr = require("mason-registry")
			local function ensure_installed()
				for _, tool in ipairs(opts.ensure_installed) do
					local p = mr.get_package(tool)
					if not p:is_installed() then
						p:install()
					end
				end
			end
			if mr.refresh then
				mr.refresh(ensure_installed)
			else
				ensure_installed()
			end
		end,
	},
}

And here is my config of completion

return {
	-- snippets
	{
		"L3MON4D3/LuaSnip",
		event = "InsertEnter",
		dependencies = {
			"rafamadriz/friendly-snippets",
		},
		config = function()
			local user_snippets = vim.fn.stdpath("config") .. "/snippets"
			require("luasnip.loaders.from_vscode").lazy_load({ paths = user_snippets })
		end,
	},

	-- auto completion
	{
		"hrsh7th/nvim-cmp",
		version = false,
		event = "InsertEnter",
		dependencies = {
			"hrsh7th/cmp-nvim-lsp",
			"hrsh7th/cmp-buffer",
			"hrsh7th/cmp-path",
			"saadparwaiz1/cmp_luasnip",
		},
		opts = function()
			local luasnip = require("luasnip")
			local cmp = require("cmp")

			local has_word_before = function()
				unpack = unpack or table.unpack
				local line, col = unpack(vim.api.nvim_win_get_cursor(0))
				return col ~= 0
					and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
			end
			return {
				snippet = {
					expand = function(args)
						require("luasnip").lsp_expand(args.body)
					end,
				},
				sources = {
					{ name = "luasnip" },
					{ name = "nvim_lsp" },
					{ name = "buffer" },
					{ name = "path" },
				},
				window = {
					completion = cmp.config.window.bordered(),
					documentation = cmp.config.window.bordered(),
				},
				formatting = {
					fields = { "kind", "abbr", "menu" },
					format = function(entry, item)
						item.kind = require("user.icons").kinds[item.kind]
						item.menu = ({
							nvim_lsp = "[LSP]",
							path = "[Path]",
							luasnip = "[Snippet]",
							buffer = "[Buffer]",
						})[entry.source.name]
						item.dup = ({
							nvim_lsp = 0,
							path = 1,
							luasnip = 1,
							buffer = 1,
						})[entry.source.name]
						return item
					end,
				},
				mapping = cmp.mapping.preset.insert({
					["<C-k>"] = cmp.mapping(cmp.mapping.select_prev_item(), { "i", "c" }),
					["<C-j>"] = cmp.mapping(cmp.mapping.select_next_item(), { "i", "c" }),
					["<C-b>"] = cmp.mapping.scroll_docs(-4),
					["<C-f>"] = cmp.mapping.scroll_docs(4),
					["<Tab>"] = cmp.mapping(function(fallback)
						if cmp.visible() then
							cmp.select_next_item()
						elseif luasnip.expand_or_jumpable() then
							luasnip.expand_or_jump()
						elseif has_word_before() then
							cmp.complete()
						else
							fallback()
						end
					end, { "i", "s" }),
					["<S-Tab>"] = cmp.mapping(function(fallback)
						if cmp.visible() then
							cmp.select_prev_item()
						elseif luasnip.jumpable(-1) then
							luasnip.jump(-1)
						else
							fallback()
						end
					end, { "i", "s" }),
					["<C-Space>"] = cmp.mapping.complete(),
					["<C-e>"] = cmp.mapping.abort(),
					["<CR>"] = cmp.mapping.confirm({ select = true }),
				}),
			}
		end,
	},
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant