# Neovim Migration Checklist Source of truth for the step-by-step rebuild. Keep this concise and up to date. See details in `neovim-migration-guide.md`. ## Phase 0 — Ground Rules - [x] Create AGENTS.md with rules ## Phase 1 — Clean & Archive Legacy Config ## Phase 1.1 — Confirm scope and priorities - [x] Confirm scope and priorities for this phase ## Phase 1.2 — Inventory legacy files - [x] Inventory existing Vimscript, plugin files, and directories ## Phase 1.3 — Create archive location - [x] Create `legacy/` archive folder within this config ## Phase 1.4 — Move legacy files into archive - [x] Move legacy init files and plugin directories into `legacy/` (do not delete) ## Phase 1.5 — Document archived contents - [x] Optionally add `legacy/README.md` noting what was archived ## Phase 1.6 — Preserve selected directories - [x] Keep `undodir`, `spell`, `view`, `UltiSnips`, `templates` as-is for now (review later) ## Phase 2 — Bootstrap ## Phase 2.1 — Confirm scope and priorities - [x] Confirm scope and priorities for this phase ## Phase 2.2 — Scaffold Lua config skeleton - [x] Scaffold Lua config skeleton (`init.lua`, `lua/settings.lua`, `lua/keymaps.lua`, `lua/autocmds.lua`, `lua/utils.lua`, `lua/plugins/`) ## Phase 2.3 — Bootstrap lazy.nvim - [x] Bootstrap `lazy.nvim` plugin manager ## Phase 2.4 — Disable unused providers - [x] Disable unused providers (ruby, perl, node) ## Phase 2.5 — Ensure lazy boots without specs - [x] Ensure lazy boots without specs (add empty `lua/plugins/init.lua`) ## Phase 3 — Core Editing & LSP ## Phase 3.1 — Confirm scope and priorities - [x] Confirm scope and priorities for this phase - [x] Decision: PHP LSP = `intelephense` - [x] Decision: Enable Markdown LSP = `marksman` - [x] Decision: Use legacy `listchars` and `showbreak` values - [x] Decision: Support per‑project config for `intelephense.includePaths` - [x] Decision: No direnv fallback for local config ## Phase 3.2 — Non-plugin settings to Lua - [x] Port non-plugin settings to Lua (options, listchars, showbreak, spelllang=en_gb) ## 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 (native exrc) - [x] Confirm scope and priorities for this subphase - [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] 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] 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 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 — 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] 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 ## Phase 4 — Navigation ## Phase 4.1 — Confirm scope and priorities - [ ] Confirm scope and priorities for this phase ## Phase 4.2 — Neo-tree setup - [ ] Add `neo-tree.nvim` with per-tab roots, sidebar toggle, floating view, and preview keymap (no buffer pollution) ## Phase 4.3 — Telescope setup - [ ] Add `telescope.nvim` (+ optional `telescope-fzf-native.nvim`) and basic pickers ## Phase 5 — Treesitter ## Phase 5.1 — Confirm scope and priorities - [ ] Confirm scope and priorities for this phase ## Phase 5.2 — Base Treesitter - [ ] Add `nvim-treesitter` with incremental selection, highlighting ## Phase 5.3 — Treesitter textobjects - [ ] Add `nvim-treesitter-textobjects` ## Phase 5.4 — Treesitter autotag - [ ] Add `nvim-ts-autotag` ## Phase 6 — UX / Editing ## Phase 6.1 — Confirm scope and priorities - [ ] Confirm scope and priorities for this phase ## Phase 6.2 — Comment.nvim - [ ] Add `numToStr/Comment.nvim` ## Phase 6.3 — Surround - [ ] Add `kylechui/nvim-surround` ## Phase 6.4 — Autopairs - [ ] Add `windwp/nvim-autopairs` ## Phase 6.5 — Indent guides - [ ] Add `lukas-reineke/indent-blankline.nvim` ## Phase 6.6 — Motion (leap/flash) - [ ] Add `ggandor/leap.nvim` or `folke/flash.nvim` ## Phase 6.7 — Folding (UFO) - [ ] Add `kevinhwang91/nvim-ufo` for folding ## Phase 6.8 — Optional: Undotree - [ ] (Optional) Add `mbbill/undotree` ## Phase 7 — Git, Markdown, Copilot, Formatting ## Phase 7.1 — Confirm scope and priorities - [ ] Confirm scope and priorities for this phase ## Phase 7.2 — Git - [ ] Add `lewis6991/gitsigns.nvim` ## Phase 7.3 — Markdown - [ ] Add `render-markdown.nvim` ## Phase 7.4 — Copilot - [ ] Add `zbirenbaum/copilot.lua` + `copilot-cmp` ## Phase 7.5 — Formatting - [ ] Add `nvimtools/none-ls.nvim` with minimal formatters/linters ## Phase 8 — Migrate Kept Behaviours ## Phase 8.1 — Confirm scope and priorities - [ ] Confirm scope and priorities for this phase ## Phase 8.2 — Abbreviations - [ ] Abbreviations: `adn→and`, `waht→what`, `tehn→then`, `functin→function`, `positin→position` ## Phase 8.3 — Templates - [ ] Templates: auto-populate new `.sh` from template ## Phase 8.4 — Whitespace highlighting - [ ] Whitespace highlighting (modern approach) ## Phase 8.5 — Persistent folds - [ ] Persistent folds (via UFO) ## Phase 9 — Cleanup & Validation ## Phase 9.1 — Confirm scope and priorities - [ ] Confirm scope and priorities for this phase ## Phase 9.2 — Retire legacy files - [ ] Retire legacy Vimscript files (keep for reference until verified) ## Phase 9.3 — Startup performance - [ ] Validate startup performance (no errors, fast launch) ## Phase 9.4 — Tab workflow validation - [ ] Validate tab-per-context workflow with Neo-tree ## Phase 9.5 — Navigation validation - [ ] Validate Telescope navigation + LSP jumps ## Phase 9.6 — Language tooling validation - [ ] Validate HTML/PHP/JS/Markdown tooling --- Notes: - Keep plugin specs minimal; configure in their own `lua/plugins/*.lua` files. - Avoid adding plugins not listed in the guide unless explicitly requested. - 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: - 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; 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. 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.