diff --git a/MIGRATION_PLAN.md b/MIGRATION_PLAN.md index 7492680..04e2a33 100644 --- a/MIGRATION_PLAN.md +++ b/MIGRATION_PLAN.md @@ -58,64 +58,52 @@ Source of truth for the step-by-step rebuild. Keep this concise and up to date. ## Phase 3.3 — Core completion stack - [x] Add core completion stack: `nvim-cmp`, `cmp-nvim-lsp`, `cmp-buffer`, `cmp-path`, `LuaSnip` -## Phase 3.4 — Project‑local configuration (neoconf) +## Phase 3.4 — Project‑local configuration (native exrc) - [x] Confirm scope and priorities for this subphase -- [x] Choose approach: use `folke/neoconf.nvim` (replaces custom loader) -- [x] Add `folke/neoconf.nvim` plugin spec and minimal setup -- [x] Document `.neoconf.json` usage and example in README -- [ ] Verify neoconf merges settings into lspconfig -- [x] Wire `intelephense.environment.includePaths` via `.neoconf.json` +- [x] Decision: Use native `exrc` + `secure` instead of neoconf (neoconf incompatible with Neovim 0.11+ vim.lsp.config API) +- [x] Enable `exrc` and `secure` in settings.lua +- [x] Implement `.nvim.lua` loader in LSP config using `on_new_config` hook +- [x] Wire `intelephense.environment.includePaths` via `.nvim.lua` - [x] Create validation workspaces: `WORKSPACE_TEST/` and `EXTERNAL_TEST/` with sample PHP files -- [x] Enable LSP debug notifications during validation and remove them after verifying roots +- [x] Migrate to `vim.lsp.config()` and `vim.lsp.enable()` (Neovim 0.11+ native API) +- [x] Verify project settings load correctly from actual root_dir +- [x] Clean up debug notifications and temporary code ## Phase 3.7 — Clean LSP config - [x] Remove debug/helper logic from LSP config -- [x] Use non-deprecated per-server setup (no top-level lspconfig table access) +- [x] Migrate from deprecated `require('lspconfig')[server].setup()` to `vim.lsp.config()` + `vim.lsp.enable()` +- [x] Use `on_new_config` hook for project-local settings loading (loads from actual root_dir, not cwd) -## Phase 3.8 — Validate Neoconf includePaths (temporary) -- [x] Temporarily inject `intelephense.environment.includePaths` via lspconfig for `WORKSPACE_SIMPLE` to validate goto-definition -- [x] After validation, remove the temporary injection and rely on neoconf +## Phase 3.8 — Validate project-local LSP settings +- [x] Create test workspaces with `.nvim.lua` files +- [x] Validate settings load from actual root_dir via `on_new_config` hook +- [x] Verify `gd` works for external library references via `intelephense.environment.includePaths` +- [x] Clean up debug code and notifications -## Phase 3.9 — Neoconf + Root Fix (BLOCKER) - -## Phase 3.9.1 — Confirm neoconf merge hook -- [ ] Ensure neoconf lspconfig integration applies before server setup (validate with `jsonls` in `WORKSPACE_SIMPLE`) -- [ ] Decide schema for `intelephense` settings (nested `settings.intelephense.environment.includePaths`) - -## Phase 3.9.2 — Temporary merge shim (if needed) -- [ ] Implement minimal per-server merge from `.neoconf.json` → `lspconfig.intelephense.settings` at setup-time (remove later if neoconf resolves) - -## Phase 3.9.3 — Robust PHP root resolver -- [ ] Implement explicit `root_dir` resolver (prefer `.neoconf.json`, `composer.json`, `.nvimroot`, then nearest `.git`) using `vim.fs.find` -- [ ] Keep `single_file_support = false` for `intelephense` - -## Phase 3.9.4 — Validate in WORKSPACE_SIMPLE -- [ ] `:LspInfo` shows correct root -- [ ] `gd` works for local and any configured includePaths - -## Phase 3.9.5 — Validate in WORKSPACE_TEST + EXTERNAL_TEST -- [ ] With forced workspace root, `gd` still resolves external library symbols via includePaths -- [ ] Confirm behavior after client restart and fresh session - -## Phase 3.9.6 — Decision: rooter plugin (optional) -- [ ] If root resolution remains brittle, propose adding a rooter plugin (requires approval), tuned for tab-per-context - -## Phase 3.9.7 — Finalize approach -- [ ] If neoconf merge works reliably, remove temporary shim; otherwise retain shim and document -- [ ] Document root marker guidance (`.nvimroot`) and includePaths best practices +## Phase 3.9 — Native exrc + vim.lsp.config migration (RESOLVED) +- [x] Discovered neoconf incompatible with Neovim 0.11+ (GitHub issue #116, unresolved since May 2024) +- [x] Migrated to native `exrc` + `secure` approach (zero dependencies, aligned with minimal philosophy) +- [x] Implemented `.nvim.lua` loader using `on_new_config` hook (loads from actual root_dir) +- [x] Migrated from deprecated `require('lspconfig')` framework to `vim.lsp.config()` + `vim.lsp.enable()` +- [x] Root detection handled by nvim-lspconfig's native configs (no custom root_dir needed) +- [x] Validated `gd` works for external library symbols via `intelephense.environment.includePaths` +- [x] Settings schema: `.nvim.lua` returns `{ lsp = { [server_name] = { settings = {...} } } }` +- [x] Security: `secure` mode prompts user to trust `.nvim.lua` files before execution +- [x] Kept `single_file_support = false` for `intelephense` +- [x] Fixed duplicate `gd` results issue ## Phase 3.5 — LSP minimal defaults - [x] Add `nvim-lspconfig` with minimal defaults (no over-configuration) - [x] Add minimal LSP on-attach keymaps (gd, gr, K, gD, gI) - [x] Add global LSP keymaps with fallback in `lua/keymaps.lua` - - [x] InteIephense root guard: enforce root_dir priority (`.neoconf.json`, `composer.json`, `.nvimroot`, `.git`) and set `single_file_support=false` +- [x] Intelephense: set `single_file_support=false`, root detection via nvim-lspconfig defaults +- [x] Project settings loaded via `on_new_config` hook from `.nvim.lua` files ## Phase 3.6 — LSP server management (Mason) - [x] Confirm scope and priorities for this subphase - [x] Add `williamboman/mason.nvim` and `williamboman/mason-lspconfig.nvim` - [x] Ensure servers installed: `lua_ls`, `tsserver`, `html`, `cssls`, `jsonls`, `bashls`, `marksman`, `intelephense` - [x] Keep our custom per-server setup; use Mason only for installation -- [x] Improve root detection to include `.neoconf.json` ## Phase 4 — Navigation @@ -230,10 +218,16 @@ Notes: - Prefer simple defaults; only add settings that clearly improve workflow. - Plugin approval policy: unlisted plugins may be proposed, but must be explicitly confirmed before installation. -Known Issues / Follow-ups (tracked by Phase 3.9): +Known Issues / Follow-ups: - lua-language-server (lua_ls) from Mason failed to start due to missing shared library `libbfd-2.38-system.so`. Options: - Install lua-language-server via system package manager compatible with your distro. - Provide the required `libbfd` or adjust symlink to match expected soname. - - Skip lua_ls for now; neoconf validation can be done with other servers (e.g., jsonls) and PHP (intelephense). + - Skip lua_ls for now; validation done with other servers (jsonls, intelephense). - LSP root detection: In some cases, the parent repository is picked as the root (e.g., when a workspace lives inside another repo). Workaround: create an empty `.git` directory (or a marker like `.nvimroot`) in the intended workspace root to pin the project root for LSPs. -- Neoconf merge + root correctness are a blocker for migration. Address via Phase 3.9 subphases above. + +Decisions & Changes: +- **Neoconf dropped**: folke/neoconf.nvim incompatible with Neovim 0.11+ vim.lsp.config API (GitHub issue #116, open since May 2024, no resolution). Migrated to native `exrc` + `secure` approach. +- **vim.lsp.config migration**: Migrated from deprecated `require('lspconfig')[server].setup()` to `vim.lsp.config()` + `vim.lsp.enable()` (Neovim 0.11+ native API). +- **Project config format**: `.nvim.lua` files return `{ lsp = { [server_name] = { settings = {...} } } }`. +- **Security model**: `secure` mode prompts user to trust `.nvim.lua` files before execution (one-time per file hash). +- **Settings loading**: `on_new_config` hook loads project settings from actual `root_dir` (not cwd), ensuring correct behavior across different workspace structures.