14 KiB
14 KiB
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
- Create AGENTS.md with rules
Phase 1 — Clean & Archive Legacy Config
Phase 1.1 — Confirm scope and priorities
- Confirm scope and priorities for this phase
Phase 1.2 — Inventory legacy files
- Inventory existing Vimscript, plugin files, and directories
Phase 1.3 — Create archive location
- Create
legacy/archive folder within this config
Phase 1.4 — Move legacy files into archive
- Move legacy init files and plugin directories into
legacy/(do not delete)
Phase 1.5 — Document archived contents
- Optionally add
legacy/README.mdnoting what was archived
Phase 1.6 — Preserve selected directories
- Keep
undodir,spell,view,UltiSnips,templatesas-is for now (review later)
Phase 2 — Bootstrap
Phase 2.1 — Confirm scope and priorities
- Confirm scope and priorities for this phase
Phase 2.2 — Scaffold Lua config skeleton
- 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
- Bootstrap
lazy.nvimplugin manager
Phase 2.4 — Disable unused providers
- Disable unused providers (ruby, perl, node)
Phase 2.5 — Ensure lazy boots without specs
- Ensure lazy boots without specs (add empty
lua/plugins/init.lua)
Phase 3 — Core Editing & LSP
Phase 3.1 — Confirm scope and priorities
- Confirm scope and priorities for this phase
- Decision: PHP LSP =
intelephense - Decision: Enable Markdown LSP =
marksman - Decision: Use legacy
listcharsandshowbreakvalues - Decision: Support per‑project config for
intelephense.includePaths - Decision: No direnv fallback for local config
Phase 3.2 — Non-plugin settings to Lua
- Port non-plugin settings to Lua (options, listchars, showbreak, spelllang=en_gb)
Phase 3.3 — Core completion stack
- Add core completion stack:
nvim-cmp,cmp-nvim-lsp,cmp-buffer,cmp-path,LuaSnip
Phase 3.4 — Project‑local configuration (native exrc)
- Confirm scope and priorities for this subphase
- Decision: Use native
exrc+secureinstead of neoconf (neoconf incompatible with Neovim 0.11+ vim.lsp.config API) - Enable
exrcandsecurein settings.lua - Implement
.nvim.lualoader in LSP config usingon_new_confighook - Wire
intelephense.environment.includePathsvia.nvim.lua - Create validation workspaces:
WORKSPACE_TEST/andEXTERNAL_TEST/with sample PHP files - Migrate to
vim.lsp.config()andvim.lsp.enable()(Neovim 0.11+ native API) - Verify project settings load correctly from actual root_dir
- Clean up debug notifications and temporary code
Phase 3.7 — Clean LSP config
- Remove debug/helper logic from LSP config
- Migrate from deprecated
require('lspconfig')[server].setup()tovim.lsp.config()+vim.lsp.enable() - Use
on_new_confighook for project-local settings loading (loads from actual root_dir, not cwd)
Phase 3.8 — Validate project-local LSP settings
- Create test workspaces with
.nvim.luafiles - Validate settings load from actual root_dir via
on_new_confighook - Verify
gdworks for external library references viaintelephense.environment.includePaths - Clean up debug code and notifications
Phase 3.9 — Native exrc + vim.lsp.config migration (RESOLVED)
- Discovered neoconf incompatible with Neovim 0.11+ (GitHub issue #116, unresolved since May 2024)
- Migrated to native
exrc+secureapproach (zero dependencies, aligned with minimal philosophy) - Implemented
.nvim.lualoader usingon_new_confighook (loads from actual root_dir) - Migrated from deprecated
require('lspconfig')framework tovim.lsp.config()+vim.lsp.enable() - Root detection handled by nvim-lspconfig's native configs (no custom root_dir needed)
- Validated
gdworks for external library symbols viaintelephense.environment.includePaths - Settings schema:
.nvim.luareturns{ lsp = { [server_name] = { settings = {...} } } } - Security:
securemode prompts user to trust.nvim.luafiles before execution - Kept
single_file_support = falseforintelephense - Fixed duplicate
gdresults issue
Phase 3.5 — LSP minimal defaults
- Add
nvim-lspconfigwith minimal defaults (no over-configuration) - Add minimal LSP on-attach keymaps (gd, gr, K, gD, gI)
- Add global LSP keymaps with fallback in
lua/keymaps.lua - Intelephense: set
single_file_support=false, root detection via nvim-lspconfig defaults - Project settings loaded via
on_new_confighook from.nvim.luafiles
Phase 3.6 — LSP server management (Mason)
- Confirm scope and priorities for this subphase
- Add
williamboman/mason.nvimandwilliamboman/mason-lspconfig.nvim - Ensure servers installed:
lua_ls,tsserver,html,cssls,jsonls,bashls,marksman,intelephense - 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
- Decision: Skip Neo-tree in favor of netrw for navigation/visual context
- Decision: Use netrw for project structure visualization and file preview
- Decision: Telescope as primary "find file" tool
- Decision: Add Oil.nvim for file manipulation (handles buffer sync on rename/move/delete)
- Note: Oil.nvim is for evaluation; alternative is mini.files if too heavy
Phase 4.2 — Configure netrw
- Configure netrw with tree view, preview split, and basic settings (no banner, sensible defaults)
- Created
lua/netrw-config.luawith settings: tree view, horizontal preview split below, 50/50 split, human-readable sizes - Add netrw keymaps:
<leader>te(new tab at current file's directory),<leader>tE(new tab at project root) - Decision: No
<leader>eor<leader>vkeymaps - use:Ex,:Vexdirectly when needed - Preview behavior: Enter opens file in netrw window,
popens 50/50 horizontal split below
Phase 4.2.1 — PHP gf enhancement
- Add PHP
includeexprfor intelligentgfbehavior (handles__DIR__,__FILE__,dirname(__FILE__)patterns) - Created
after/ftplugin/php.luawith path resolution for WordPress/PHP patterns - Tested and validated with test-gf.php
Phase 4.3 — Telescope setup
- Add
telescope.nvim+telescope-fzf-native.nvimfor fuzzy finding - Configure basic pickers:
find_files,live_grep,buffers,help_tags,oldfiles,current_buffer_fuzzy_find - Add LSP pickers:
lsp_document_symbols,lsp_workspace_symbols - 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)
- Minimal UI: dropdown theme for files/buffers, no previewer for quick selection
Phase 4.4 — Oil.nvim for file manipulation
- Add
stevearc/oil.nvimfor filesystem operations (rename, create, delete, copy, move) - Configure to handle buffer name sync on file operations
- Keep minimal - use only when shell operations would cause buffer issues
- 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)
- Preview splits open to the right via
vertical = trueandsplit = 'belowright' - Floating window preview direction:
preview_split = "right" - Note: Evaluate practicality; can switch to
mini.filesif preferred
Phase 5 — Treesitter
Phase 5.1 — Confirm scope and priorities
- Confirm scope and priorities for this phase
- Decision: Focus on languages: PHP, HTML, JavaScript, TypeScript, CSS, Markdown, Lua, Bash, JSON
- Decision: Enable syntax highlighting and incremental selection (CR to expand, BS to shrink)
- Decision: Enable textobjects for functions, classes, parameters, conditionals, loops
- Decision: Enable autotag for HTML/PHP/JS/React files
- Decision: Disable indent (experimental) to start; can enable per-filetype if stable
Phase 5.2 — Base Treesitter
- Add
nvim-treesitterwith incremental selection, highlighting - Configure parsers: lua, vim, vimdoc, php, html, javascript, typescript, tsx, css, scss, json, markdown, markdown_inline, bash, regex
- Enable auto-install for missing parsers
- Incremental selection keymaps: CR (init/expand), S-CR (scope expand), BS (shrink)
- Disable for large files (>100KB) to maintain performance
Phase 5.3 — Treesitter textobjects
- Add
nvim-treesitter-textobjects - Select keymaps:
af/if(function),ac/ic(class),aa/ia(parameter),ai/ii(conditional),al/il(loop),a/(comment) - Move keymaps:
]f/[f(next/prev function start),]F/[F(function end), similar for classes and parameters - Swap keymaps:
<leader>a/<leader>A(swap parameter with next/prev)
Phase 5.4 — Treesitter autotag
- Add
nvim-ts-autotag - 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
- 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.nvimorfolke/flash.nvim
Phase 6.7 — Folding (UFO)
- Add
kevinhwang91/nvim-ufofor 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.nvimwith 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
.shfrom 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 (if used)
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/*.luafiles. - 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
libbfdor 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
.gitdirectory (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+secureapproach. - vim.lsp.config migration: Migrated from deprecated
require('lspconfig')[server].setup()tovim.lsp.config()+vim.lsp.enable()(Neovim 0.11+ native API). - Project config format:
.nvim.luafiles return{ lsp = { [server_name] = { settings = {...} } } }. - Security model:
securemode prompts user to trust.nvim.luafiles before execution (one-time per file hash). - Settings loading:
on_new_confighook loads project settings from actualroot_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.