nvim/MIGRATION_PLAN.md

234 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 perproject 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 — Projectlocal 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.