From 3e301ee157c79d1378980b5e7e4eebd3474229a4 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Wed, 5 Jun 2024 10:50:22 +0200 Subject: [PATCH] feat: added lspconfig integration to fix its workspace management --- README.md | 33 +++++++++++++++++++++---- lua/lazydev/config.lua | 24 +++++++++++++----- lua/lazydev/init.lua | 12 +++++++++ lua/lazydev/{ => integrations}/cmp.lua | 0 lua/lazydev/{ => integrations}/coq.lua | 0 lua/lazydev/integrations/lspconfig.lua | 34 ++++++++++++++++++++++++++ 6 files changed, 92 insertions(+), 11 deletions(-) rename lua/lazydev/{ => integrations}/cmp.lua (100%) rename lua/lazydev/{ => integrations}/coq.lua (100%) create mode 100644 lua/lazydev/integrations/lspconfig.lua diff --git a/README.md b/README.md index f76f308..af978dc 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ for editing your **Neovim** config by lazily updating your workspace libraries. -## 🚀 Features +## ✨ Features - much faster auto-completion, since only the modules you `require` in open Neovim files will be loaded. @@ -121,13 +121,36 @@ Default settings: local defaults = { runtime = vim.env.VIMRUNTIME --[[@as string]], library = {}, ---@type lazydev.Library.spec[] - -- add the cmp source for completion of: - -- `require "modname"` - -- `---@module "modname"` - cmp = true, + integrations = { + -- Fixes lspconfig's workspace management for LuaLS + -- Only create a new workspace if the buffer is not part + -- of an existing workspace or one of its libraries + lspconfig = true, + -- add the cmp source for completion of: + -- `require "modname"` + -- `---@module "modname"` + cmp = true, + -- same, but for Coq + coq = false, + }, ---@type boolean|(fun(root:string):boolean?) enabled = function(root_dir) return vim.g.lazydev_enabled == nil and true or vim.g.lazydev_enabled end, } ``` + +## 🚀 Usage + +Just install the plugin and start editing your Lua files. + +If you don't use [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig), +then you can use `require('lazydev').find_workspace(buf?)` to check if the buffer +is part of an existing workspace or its libraries. + +The `:LazyDev` command: + +- `:LazyDev` or `:LazyDev debug` will show a notification with the **lazydev** + settings for the current buffer. +- `:LazyDev lsp`: will show a notification with the settings for + **any** attached LSP servers. Not limited to **LuaLS**. diff --git a/lua/lazydev/config.lua b/lua/lazydev/config.lua index 69b8fc8..dac6abd 100644 --- a/lua/lazydev/config.lua +++ b/lua/lazydev/config.lua @@ -7,14 +7,22 @@ local M = {} local defaults = { runtime = vim.env.VIMRUNTIME --[[@as string]], library = {}, ---@type lazydev.Library.spec[] + integrations = { + -- Fixes lspconfig workspace management for LuaLS + -- Only create a new workspace if the buffer is not part + -- of an existing workspace or one of its libraries + lspconfig = true, + -- add the cmp source for completion of: + -- `require "modname"` + -- `---@module "modname"` + cmp = true, + -- same, but for Coq + coq = false, + }, ---@type boolean|(fun(root:string):boolean?) enabled = function(root_dir) return vim.g.lazydev_enabled == nil and true or vim.g.lazydev_enabled end, - -- add the cmp source for completion of: - -- `require "modname"` - -- `---@module "modname"` - cmp = true, debug = false, } @@ -47,6 +55,7 @@ function M.setup(opts) return end + ---@type lazydev.Config options = vim.tbl_deep_extend("force", {}, options or defaults, opts or {}) M.libs, M.words, M.mods = {}, {}, {} @@ -87,8 +96,11 @@ function M.setup(opts) vim.schedule(function() require("lazydev.buf").setup() - require("lazydev.cmp").setup() - require("lazydev.coq").setup() + for name, enabled in pairs(options.integrations) do + if enabled then + require("lazydev.integrations." .. name).setup() + end + end end) return options end diff --git a/lua/lazydev/init.lua b/lua/lazydev/init.lua index 776d375..1b36752 100644 --- a/lua/lazydev/init.lua +++ b/lua/lazydev/init.lua @@ -5,4 +5,16 @@ function M.setup(opts) require("lazydev.config").setup(opts) end +--- Checks if the current buffer is in a workspace: +--- * part of the workspace root +--- * part of the workspace libraries +--- Returns the workspace root if found +---@param buf? integer +function M.find_workspace(buf) + local fname = vim.api.nvim_buf_get_name(buf or 0) + local Workspace = require("lazydev.workspace") + local ws = Workspace.find({ path = fname }) + return ws and ws.root or nil +end + return M diff --git a/lua/lazydev/cmp.lua b/lua/lazydev/integrations/cmp.lua similarity index 100% rename from lua/lazydev/cmp.lua rename to lua/lazydev/integrations/cmp.lua diff --git a/lua/lazydev/coq.lua b/lua/lazydev/integrations/coq.lua similarity index 100% rename from lua/lazydev/coq.lua rename to lua/lazydev/integrations/coq.lua diff --git a/lua/lazydev/integrations/lspconfig.lua b/lua/lazydev/integrations/lspconfig.lua new file mode 100644 index 0000000..469f022 --- /dev/null +++ b/lua/lazydev/integrations/lspconfig.lua @@ -0,0 +1,34 @@ +local M = {} + +function M.setup() + local ok, Manager = pcall(require, "lspconfig.manager") + if not ok then + return + end + + local try_add = Manager.try_add + + --- @param buf integer + --- @param project_root? string + function Manager:try_add(buf, project_root) + local is_lua_ls = false + for _, ids in pairs(self._clients) do + for _, client_id in ipairs(ids) do + local client = vim.lsp.get_client_by_id(client_id) + if client and client.name == "lua_ls" then + is_lua_ls = true + break + end + end + end + if is_lua_ls and not project_root then + local root = require("lazydev").find_workspace(buf) + if root then + return self:add(root, false, buf) + end + end + return try_add(self, buf, project_root) + end +end + +return M