323 lines
16 KiB
Markdown
323 lines
16 KiB
Markdown
# 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
|
||
- [x] Confirm scope and priorities for this phase
|
||
- [x] Decision: Skip Neo-tree in favor of netrw for navigation/visual context
|
||
- [x] Decision: Use netrw for project structure visualization and file preview
|
||
- [x] Decision: Telescope as primary "find file" tool
|
||
- [x] Decision: Add Oil.nvim for file manipulation (handles buffer sync on rename/move/delete)
|
||
- [x] Note: Oil.nvim is for evaluation; alternative is mini.files if too heavy
|
||
|
||
## Phase 4.2 — Configure netrw
|
||
- [x] Configure netrw with tree view, preview split, and basic settings (no banner, sensible defaults)
|
||
- [x] Created `lua/netrw-config.lua` with settings: tree view, horizontal preview split below, 50/50 split, human-readable sizes
|
||
- [x] Add netrw keymaps: `<leader>te` (new tab at current file's directory), `<leader>tE` (new tab at project root)
|
||
- [x] Decision: No `<leader>e` or `<leader>v` keymaps - use `:Ex`, `:Vex` directly when needed
|
||
- [x] Preview behavior: Enter opens file in netrw window, `p` opens 50/50 horizontal split below
|
||
|
||
## Phase 4.2.1 — PHP gf enhancement
|
||
- [x] Add PHP `includeexpr` for intelligent `gf` behavior (handles `__DIR__`, `__FILE__`, `dirname(__FILE__)` patterns)
|
||
- [x] Created `after/ftplugin/php.lua` with path resolution for WordPress/PHP patterns
|
||
- [x] Tested and validated with test-gf.php
|
||
|
||
## Phase 4.3 — Telescope setup
|
||
- [x] Add `telescope.nvim` + `telescope-fzf-native.nvim` for fuzzy finding
|
||
- [x] Configure basic pickers: `find_files`, `live_grep`, `buffers`, `help_tags`, `oldfiles`, `current_buffer_fuzzy_find`
|
||
- [x] Add LSP pickers: `lsp_document_symbols`, `lsp_workspace_symbols`
|
||
- [x] Keymaps configured:
|
||
- `<leader>ff` - Find files
|
||
- `<leader>fg` - Live grep (search text)
|
||
- `<leader>fb` - Find buffers (with `<C-d>` to delete)
|
||
- `<leader>fh` - Find help
|
||
- `<leader>fr` - Recent files
|
||
- `<leader>/` - Search current buffer
|
||
- `<leader>fs` - Document symbols (LSP)
|
||
- `<leader>fS` - Workspace symbols (LSP)
|
||
- [x] Minimal UI: dropdown theme for files/buffers, no previewer for quick selection
|
||
|
||
## Phase 4.4 — Oil.nvim for file manipulation
|
||
- [x] Add `stevearc/oil.nvim` for filesystem operations (rename, create, delete, copy, move)
|
||
- [x] Configure to handle buffer name sync on file operations
|
||
- [x] Keep minimal - use only when shell operations would cause buffer issues
|
||
- [x] Keymaps configured:
|
||
- `<leader>fo` - Open Oil file browser (regular buffer)
|
||
- `<leader>fO` - Open Oil in floating window (with floating previews)
|
||
- `<C-p>` in Oil - Preview files (vertical split to right for regular, floating window for float mode)
|
||
- [x] Preview splits open to the right via `vertical = true` and `split = 'belowright'`
|
||
- [x] Floating window preview direction: `preview_split = "right"`
|
||
- [x] Note: Evaluate practicality; can switch to `mini.files` if preferred
|
||
|
||
## Phase 5 — Treesitter
|
||
|
||
## Phase 5.1 — Confirm scope and priorities
|
||
- [x] Confirm scope and priorities for this phase
|
||
- [x] Decision: Focus on languages: PHP, HTML, JavaScript, TypeScript, CSS, Markdown, Lua, Bash, JSON
|
||
- [x] Decision: Enable syntax highlighting and incremental selection (CR to expand, BS to shrink)
|
||
- [x] Decision: Enable textobjects for functions, classes, parameters, conditionals, loops
|
||
- [x] Decision: Enable autotag for HTML/PHP/JS/React files
|
||
- [x] Decision: Disable indent (experimental) to start; can enable per-filetype if stable
|
||
|
||
## Phase 5.2 — Base Treesitter
|
||
- [x] Add `nvim-treesitter` with incremental selection, highlighting
|
||
- [x] Configure parsers: lua, vim, vimdoc, php, html, javascript, typescript, tsx, css, scss, json, markdown, markdown_inline, bash, regex
|
||
- [x] Enable auto-install for missing parsers
|
||
- [x] Incremental selection keymaps: CR (init/expand), S-CR (scope expand), BS (shrink)
|
||
- [x] Disable for large files (>100KB) to maintain performance
|
||
|
||
## Phase 5.3 — Treesitter textobjects
|
||
- [x] Add `nvim-treesitter-textobjects`
|
||
- [x] Select keymaps: `af`/`if` (function), `ac`/`ic` (class), `aa`/`ia` (parameter), `ai`/`ii` (conditional), `al`/`il` (loop), `a/` (comment)
|
||
- [x] Move keymaps: `]f`/`[f` (next/prev function start), `]F`/`[F` (function end), similar for classes and parameters
|
||
- [x] Swap keymaps: `<leader>a`/`<leader>A` (swap parameter with next/prev)
|
||
|
||
## Phase 5.4 — Treesitter autotag
|
||
- [x] Add `nvim-ts-autotag`
|
||
- [x] Enable auto-close, auto-rename, and close-on-slash for HTML/PHP/JS/React/TS/Vue files
|
||
|
||
## Phase 6 — UX / Editing
|
||
|
||
## Phase 6.1 — Confirm scope and priorities
|
||
- [x] Confirm scope and priorities for this phase
|
||
- [x] Decision: No cursorcolumn (as per AGENTS.md)
|
||
- [x] Decision: No auto-window toggling behavior (keep settings static)
|
||
- [x] Decision: No motion plugin (skip leap/flash)
|
||
- [x] Decision: Move undotree to separate Phase 6.8
|
||
- [x] UX settings to add: signcolumn, cursorline, colorcolumn
|
||
|
||
## Phase 6.2 — Core UX settings
|
||
- [x] Add signcolumn=yes (always show gutter for LSP/git)
|
||
- [x] Add cursorline (highlight current line)
|
||
- [x] Add colorcolumn=80,120 (visual guides)
|
||
- [x] No cursorcolumn (excluded as per AGENTS.md)
|
||
- [x] No per-window autocommands (keep simple)
|
||
|
||
## Phase 6.3 — Comment.nvim
|
||
- [x] Add `numToStr/Comment.nvim`
|
||
- [x] Configure for gcc/gc commenting
|
||
- [x] Add keymaps if needed
|
||
|
||
## Phase 6.4 — Surround
|
||
- [x] Add `kylechui/nvim-surround`
|
||
- [x] Minimal config with default keymaps (ys, ds, cs)
|
||
|
||
## Phase 6.5 — Autopairs
|
||
- [x] Add `windwp/nvim-autopairs`
|
||
- [x] Integrate with nvim-cmp
|
||
|
||
## Phase 6.6 — Indent guides
|
||
- [x] Add `lukas-reineke/indent-blankline.nvim`
|
||
- [x] Configure scope highlighting
|
||
|
||
## Phase 6.7 — Folding (UFO)
|
||
- [x] Add `kevinhwang91/nvim-ufo` for folding
|
||
- [x] Configure with Treesitter and LSP providers
|
||
- [x] Add fold keymaps (za, zR, zM, etc.)
|
||
|
||
## Phase 6.8 — Undotree
|
||
- [x] Add `mbbill/undotree`
|
||
- [x] Add keymap to toggle undotree
|
||
- [x] Configure minimal settings
|
||
|
||
## Phase 7 — Git Integration
|
||
|
||
## Phase 7.1 — Confirm scope and priorities
|
||
- [x] Confirm scope and priorities for this phase
|
||
- [x] Decision: Gitsigns with minimal config - signs in gutter, hunk navigation/actions only
|
||
- [x] Decision: Skip markdown rendering plugins entirely
|
||
|
||
## Phase 7.2 — Gitsigns
|
||
- [x] Add `lewis6991/gitsigns.nvim`
|
||
- [x] Configure signs in gutter (add, change, delete, topdelete, changedelete)
|
||
- [x] Add hunk navigation keymaps (]h/[h for next/prev hunk)
|
||
- [x] Add hunk action keymaps (stage, reset, preview)
|
||
- [x] Keep minimal - no inline blame, no advanced features
|
||
|
||
## Phase 8 — Copilot
|
||
|
||
## Phase 8.1 — Confirm scope and priorities
|
||
- [ ] Confirm scope and priorities for this phase
|
||
|
||
## Phase 8.2 — Copilot setup
|
||
- [ ] Add `zbirenbaum/copilot.lua` + `copilot-cmp`
|
||
- [ ] Configure copilot integration with nvim-cmp
|
||
- [ ] Add keymaps for copilot suggestions
|
||
- [ ] Configure behavior preferences
|
||
|
||
## Phase 9 — Formatting & Linting
|
||
|
||
## Phase 9.1 — Confirm scope and priorities
|
||
- [ ] Confirm scope and priorities for this phase
|
||
|
||
## Phase 9.2 — none-ls setup
|
||
- [ ] Add `nvimtools/none-ls.nvim`
|
||
- [ ] Configure formatters (to be determined in 9.1)
|
||
- [ ] Configure linters (to be determined in 9.1)
|
||
- [ ] Add format-on-save or manual format keymaps
|
||
|
||
## Phase 10 — Migrate Kept Behaviours
|
||
|
||
## Phase 10.1 — Confirm scope and priorities
|
||
- [ ] Confirm scope and priorities for this phase
|
||
|
||
## Phase 10.2 — Abbreviations
|
||
- [ ] Abbreviations: `adn→and`, `waht→what`, `tehn→then`, `functin→function`, `positin→position`
|
||
|
||
## Phase 10.3 — Templates
|
||
- [ ] Templates: auto-populate new `.sh` from template
|
||
|
||
## Phase 10.4 — Whitespace highlighting
|
||
- [ ] Whitespace highlighting (modern approach)
|
||
|
||
## Phase 10.5 — Persistent folds
|
||
- [ ] Persistent folds (via UFO)
|
||
|
||
## Phase 11 — Cleanup & Validation
|
||
|
||
## Phase 11.1 — Confirm scope and priorities
|
||
- [ ] Confirm scope and priorities for this phase
|
||
|
||
## Phase 11.2 — Retire legacy files
|
||
- [ ] Retire legacy Vimscript files (keep for reference until verified)
|
||
|
||
## Phase 11.3 — Startup performance
|
||
- [ ] Validate startup performance (no errors, fast launch)
|
||
|
||
## Phase 11.4 — Tab workflow validation
|
||
- [ ] Validate tab-per-context workflow with Neo-tree (if used)
|
||
|
||
## Phase 11.5 — Navigation validation
|
||
- [ ] Validate Telescope navigation + LSP jumps
|
||
|
||
## Phase 11.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.
|
||
- **Phase 4 Navigation Strategy**: Skipped Neo-tree in favor of built-in netrw for visual context and project structure browsing. Telescope for fuzzy finding. Oil.nvim for file manipulation (evaluation phase; alternative is mini.files). Rationale: User needs visual context and preview, not per-tab roots or complex tree features. File manipulation primarily done in shell, but Oil.nvim handles buffer sync issues when renaming/moving files.
|