# Critical Regression Fix: LSP Project Settings Not Loading (2025-12-07) ## Summary `gd` (goto definition) stopped working for external library references in `WORKSPACE_TEST/site/external.php`. Even restoring to a git commit where it previously worked didn't fix it, indicating an **environment change** rather than a code regression. ## Root Cause **Neovim 0.11+ removed support for the `on_new_config` callback in `vim.lsp.config()`.** The previous implementation used `on_new_config` to load project-local settings from `.nvim.lua`: ```lua vim.lsp.config(server_name, { on_new_config = function(new_config, root_dir) -- Load project settings and merge into new_config.settings local project_settings = load_project_lsp_settings(server_name, root_dir) if project_settings.settings then new_config.settings = vim.tbl_deep_extend("force", new_config.settings or {}, project_settings.settings) end end, }) ``` **Problem**: This callback was **silently ignored** in Neovim 0.11+, resulting in: - Empty `client.settings` (confirmed via `:LspInfo` showing `Settings: {}`) - No `includePaths` sent to intelephense - `gd` failing with "No locations found" for external library symbols ## Symptoms 1. `:LspInfo` showed `Settings: {}` for intelephense 2. `gd` on `\ExtLib\Src\Util::greetExternal()` returned "No locations found" 3. Local (workspace) symbol navigation worked fine 4. Git history restore didn't help (environment issue, not code issue) ## Solution Use the `LspAttach` autocmd instead of `on_new_config` to load and apply project settings: ```lua vim.api.nvim_create_autocmd('LspAttach', { group = vim.api.nvim_create_augroup('lsp_project_settings', { clear = true }), callback = function(args) local client = vim.lsp.get_client_by_id(args.data.client_id) if not client then return end -- Load project-specific settings from .nvim.lua at client.root_dir local project_settings = load_project_lsp_settings(client.name, client.root_dir) if project_settings.settings then -- Merge into client.settings client.settings = vim.tbl_deep_extend("force", client.settings or {}, project_settings.settings) -- Notify server of updated settings vim.schedule(function() client.notify("workspace/didChangeConfiguration", { settings = client.settings }) end) end end, }) ``` ## Validation After fix: ```bash cd WORKSPACE_TEST nvim --headless +'e site/external.php' +'lua vim.wait(3000); local clients = vim.lsp.get_clients({name="intelephense"}); if clients[1] then print("Settings:", vim.inspect(clients[1].settings)) end' +quit ``` Output: ```lua Settings: { intelephense = { environment = { includePaths = { "/home/ray/.config/nvim/EXTERNAL_TEST" } } } } ``` ✅ Settings now correctly loaded and `gd` works for external symbols. ## Key Differences: Neovim 0.10 vs 0.11 LSP API ### Old API (lspconfig plugin, Neovim < 0.11) ```lua require('lspconfig').intelephense.setup({ on_new_config = function(new_config, root_dir) -- Called when creating new client end, }) ``` ### New API (native vim.lsp.config, Neovim 0.11+) ```lua -- Define config vim.lsp.config('intelephense', { ... }) -- Enable server vim.lsp.enable('intelephense') -- Handle dynamic settings via autocmd vim.api.nvim_create_autocmd('LspAttach', { callback = function(args) -- Access client, load settings, notify server end, }) ``` ## Documentation Updated - `README.md`: Added decision log entry for 2025-12-07 - `.github/copilot-instructions.md`: Documents LspAttach pattern - `AGENTS.md`: Already notes "Native exrc + vim.lsp.config migration done" ## Prevention - Always test LSP functionality after Neovim version upgrades - Check `:help news` for API changes - Validate `:LspInfo` settings are populated correctly - Test with external library references, not just workspace files ## Files Modified - `lua/plugins/lsp.lua`: Replaced `on_new_config` with `LspAttach` autocmd ## Timeline - **Before 2025-12-07**: `on_new_config` worked in older Neovim version - **2025-12-07**: Neovim upgraded to 0.11.5, `on_new_config` silently ignored - **2025-12-07**: Diagnosed via `:LspInfo` showing empty settings - **2025-12-07**: Fixed with `LspAttach` pattern, verified working