complete neovim 0.12 compatibility audit

This commit is contained in:
Ray Elliott 2026-10-28 15:21:03 +00:00
commit ec7f6c8121
8 changed files with 45 additions and 28 deletions

View file

@ -8,7 +8,7 @@ This repository is being migrated to a modern, minimal Neovim setup driven by Lu
- Modern Lua-first config; avoid Vimscript unless explicitly requested.
- Keep it minimal, fast, and maintainable.
- Base plugin management on `lazy.nvim` with modular plugin specs.
- Support Telescope navigation, netrw for tree browsing, previews, and file operations, LSP, Treesitter, Copilot, and sane UX defaults.
- Support Telescope navigation, netrw for tree browsing, previews, and file operations, LSP, native completion, Treesitter, Copilot, and sane UX defaults.
- Native project-local configuration via `exrc` + `secure` (no external config plugins).
## Do Not Reintroduce
@ -32,12 +32,12 @@ This repository is being migrated to a modern, minimal Neovim setup driven by Lu
├── keymaps.lua -- non-plugin keymaps
├── autocmds.lua -- non-plugin autocommands
├── abbreviations.lua -- insert-mode abbreviations
├── completion.lua -- native insert-mode and LSP completion
├── netrw-config.lua -- netrw configuration
├── utils.lua -- helpers (only if needed)
└── plugins/ -- one file per plugin or domain
├── telescope.lua
├── treesitter.lua
├── cmp.lua
├── lsp.lua
├── copilot.lua
├── ufo.lua
@ -80,12 +80,12 @@ This repository is being migrated to a modern, minimal Neovim setup driven by Lu
- Rejected: `folke/neoconf.nvim` (incompatible with Neovim 0.11+ vim.lsp.config API).
## Required Plugin Categories
- Core: `nvim-lspconfig`, `nvim-cmp`, `cmp-nvim-lsp`, `cmp-buffer`, `cmp-path`, `LuaSnip`.
- Core: `nvim-lspconfig`; use Neovim 0.12 native insert-mode/LSP completion and snippets instead of the nvim-cmp stack.
- Navigation: `telescope.nvim` + `telescope-fzf-native.nvim`; netrw is the sole file explorer.
- Treesitter: `nvim-treesitter`, `nvim-treesitter-textobjects`, `nvim-ts-autotag`.
- UX/Editing: `Comment.nvim`, `nvim-surround`, `nvim-autopairs`, `indent-blankline.nvim`, `nvim-ufo`, `undotree`.
- UX/Editing: `Comment.nvim`, `nvim-surround`, `nvim-autopairs`, `indent-blankline.nvim`, `nvim-ufo`; use Neovim 0.12's native optional `nvim.undotree` package.
- Git: `gitsigns.nvim`.
- Copilot: `copilot.lua`, `copilot-cmp`.
- Copilot: `copilot.lua` with inline suggestions; do not integrate Copilot into the native completion popup.
- Formatting/Linting: `conform.nvim`, `nvim-lint`.
- LSP Management: `mason.nvim`, `mason-lspconfig.nvim`, `mason-tool-installer.nvim`.
@ -106,7 +106,7 @@ This repository is being migrated to a modern, minimal Neovim setup driven by Lu
- Spell & text: `spelllang=en_gb`, custom `listchars`, `showbreak`.
- Keyword characters: `iskeyword+=$` (for PHP/shell variables), `iskeyword+=-` (for CSS/HTML/config files).
## Current Status (Phase 12 In Progress)
## Current Status (Phase 13 In Progress)
- ✅ Phase 1-2: Archive legacy, bootstrap lazy.nvim
- ✅ Phase 3: Core editing & LSP (native exrc + vim.lsp.config migration complete)
- ✅ Phase 4: Navigation (Telescope and netrw)
@ -118,7 +118,8 @@ This repository is being migrated to a modern, minimal Neovim setup driven by Lu
- ✅ Phase 10: Migrate kept behaviors (abbreviations, templates, custom Treesitter queries)
- ✅ Phase 11: Modern Paper Tonic colorscheme
- ⏳ Phase 12: Cleanup and validation (repository cleanup and automated checks complete; interactive workflow checks remain)
- 📋 Phase 13: Controlled Neovim 0.12.6 upgrade (planned)
- ⏳ Phase 13: Controlled Neovim 0.12.6 upgrade (configuration audit complete; isolated plugin validation and activation remain)
- 📋 Phase 13.9: Native Undotree and completion consolidation after activation
- 📋 Phase 14: Netrw live previews and directory summaries (planned after upgrade)
## Migration Notes

7
LOG.md
View file

@ -192,6 +192,13 @@ Record every decision here with a short rationale. Append new entries; do not re
- 2026-10-28: Installed the verified official Neovim 0.12.6 archive alongside the untouched 0.11.5 installation at `/opt/neovim/nvim-0.12.6`. Initial interactive startup with the existing configuration succeeded. Removed redundant `vim.lsp.with()` wrappers for hover and signature-help borders after 0.12 reported their deprecation; the shared `vim.lsp.util.open_floating_preview` override already applies the same border on both 0.11 and 0.12. Clean headless startup then passed with the existing locked plugins under both binaries.
- 2026-10-28: The 0.12 health review exposed overlapping LSP activation: mason-lspconfig v2 automatically enabled every installed server while `lsp.lua` explicitly configured and enabled the selected set. Disabled mason-lspconfig automatic activation, removed its obsolete `automatic_installation` option, and aligned it with nvim-lspconfig's buffer events. This prevents unintended activation of installed tools such as StyLua's LSP mode and leaves `lsp.lua` as the single activation authority.
- 2026-10-28: Live Intelephense attachment passed under both Neovim 0.11.5 and 0.12.6 after the LSP activation cleanup. The test also exposed the deprecated function-style `client.notify(...)` call in the project-settings callback; changed it to `client:notify(...)`, which works on both supported versions.
- 2026-10-28: Replaced the remaining `vim.loop.fs_stat` calls with `vim.uv.fs_stat` and migrated `[d`/`]d` from deprecated diagnostic navigation functions to `vim.diagnostic.jump({ count = -1/1 })`. Both APIs remain compatible with the rollback runtime, Neovim 0.11.5.
- 2026-10-28: Validated Neovim 0.12 project configuration using a disposable nested workspace and isolated trust database. With `exrc` and `secure` enabled through a normal XDG config, a trusted parent `.nvim.lua` executed exactly once and `vim.secure.read()` returned its contents. The live Intelephense test separately confirmed that the repository's project-local settings loader still receives trusted settings from the client's root.
- 2026-10-28: Validated the netrw workflow on Neovim 0.12.6. The default runtime wrapper automatically loads bundled netrw v184 from its optional package, so adding a configuration-level `packadd netrw` would be redundant and would complicate 0.11 rollback compatibility. `:Explore` opened the configured tree view, `p` created a real preview window, and `<C-6>` returned from the explorer to the source file.
- 2026-10-28: Kept `mbbill/undotree` after checking Neovim 0.12's built-in alternative. The native `nvim.undotree` package is optional and remains unloaded; it exposes `:Undotree`, whereas the configured plugin's `:UndotreeToggle` command, focused panel, and diff layout still open successfully under 0.12.6. There is no active command or runtime conflict.
- 2026-10-28: Completed the configuration-level Neovim 0.12 breaking-change audit. Diagnostic jump behavior passed under both 0.11.5 and 0.12.6, and a loaded-plugin `vim.deprecated` scan now reports only `copilot-cmp`'s upstream `client.is_stopped` call. That plugin warning is safe on 0.12 but remains a tracked compatibility concern before Neovim 0.13.
- 2026-10-28: Final Phase 13.3 smoke tests passed: both 0.11.5 and 0.12.6 start with the updated configuration, 0.12 attaches Intelephense with project settings, `git diff --check` is clean, and the measured 0.12 headless startup reached `NVIM STARTED` in approximately 43 ms with the existing locked plugins.
- 2026-10-28: Chose the post-activation native-feature direction for 0.12. Keep lazy.nvim because the configuration still benefits from its event/command loading, dependency ordering, and build hooks; do not mix the runtime upgrade with an experimental `vim.pack` migration. After activating 0.12, replace `mbbill/undotree` with the native optional package and trial native insert-mode/LSP completion plus built-in snippets. Copilot will use inline suggestions with a separate accept key rather than appearing in the completion popup; remove the cmp stack only after interactive language and editing validation.
## Project-Local Configuration

View file

@ -518,17 +518,17 @@ Source of truth for the step-by-step rebuild. Keep this concise and up to date.
- [x] Do not remove or overwrite the working 0.11.5 installation
## Phase 13.3 — Audit 0.12 compatibility before switching
- [ ] Review the Neovim 0.12 breaking changes against the active configuration
- [x] Review the Neovim 0.12 breaking changes against the active configuration
- [x] Remove deprecated `vim.lsp.with()` handler wrappers; the shared floating-preview override already supplies the configured border
- [x] Disable mason-lspconfig's automatic server activation and remove its obsolete `automatic_installation` option; `lsp.lua` remains the sole activation authority
- [x] Replace deprecated `client.notify(...)` with the 0.12-compatible `client:notify(...)` method for project-local settings
- [ ] Replace deprecated `vim.loop` usage with `vim.uv`
- [ ] Replace deprecated diagnostic navigation APIs with the current diagnostic jump API
- [ ] Revalidate native `exrc` behavior now that 0.12 searches parent directories
- [ ] Verify `vim.secure.read()` behavior in the project-local LSP settings loader
- [ ] Determine how Neovim 0.12's built-in directory buffers interact with opt-in legacy netrw
- [ ] Explicitly load netrw with `:packadd netrw` from Lua if 0.12 no longer loads it automatically
- [ ] Check for conflicts or redundancy with Neovim 0.12's built-in `:Undotree`; do not remove the plugin without a separate decision
- [x] Replace deprecated `vim.loop` usage with `vim.uv`
- [x] Replace deprecated diagnostic navigation APIs with the current diagnostic jump API
- [x] Revalidate native `exrc` behavior now that 0.12 searches parent directories
- [x] Verify `vim.secure.read()` behavior in the project-local LSP settings loader
- [x] Determine how Neovim 0.12's bundled optional netrw package behaves with the configured explorer workflow
- [x] Confirm no explicit `:packadd netrw` is needed: Neovim's default runtime wrapper loads netrw automatically
- [x] Keep the existing Undotree plugin: Neovim 0.12's built-in `:Undotree` is an inactive optional package, while the configured plugin's richer `:UndotreeToggle` workflow still opens cleanly
## Phase 13.4 — Install Neovim 0.12.6 alongside 0.11.5
- [x] Download the official `nvim-linux-x86_64.tar.gz` release archive
@ -550,10 +550,10 @@ Proposed layout:
- [ ] Use isolated `XDG_DATA_HOME`, `XDG_CACHE_HOME`, and `XDG_STATE_HOME` directories
- [ ] Install the currently locked plugin revisions into the isolated data directory
- [ ] Keep the production plugin and Mason directories untouched
- [ ] Validate headless startup and capture startup time
- [x] Validate headless startup and capture startup time
- [x] Run `:checkhealth` and review every relevant warning/error
- [ ] Verify netrw can be loaded and `:Explore` opens the expected tree browser
- [ ] Fix core/config compatibility issues before updating plugins
- [x] Verify netrw can be loaded and `:Explore` opens the expected tree browser
- [x] Fix core/config compatibility issues before updating plugins
## Phase 13.6 — Update plugins in isolation
- [ ] Use a temporary branch or worktree based on the rollback checkpoint
@ -569,7 +569,7 @@ Proposed layout:
- [ ] Validate netrw tree browsing, previews, alternate-buffer behavior, and file operations
- [ ] Validate Telescope files, grep, buffers, and LSP symbol pickers
- [ ] Validate LSP attachment, `gd`, `gr`, `K`, diagnostics, and project-local `.nvim.lua` settings
- [ ] Validate nvim-cmp, LuaSnip, and Copilot completion
- [ ] Validate the current completion stack before activation; native completion migration follows in Phase 13.9
- [ ] Validate conform format-on-save and nvim-lint/Ruff diagnostics
- [ ] Validate Treesitter highlighting, text objects, autotag, folding, and custom HTML/CSS queries
- [ ] Validate the Paper Tonic colorscheme, plugin highlights, sessions, persistent undo, and shell templates
@ -582,7 +582,16 @@ Proposed layout:
- [ ] Update AGENTS.md, README.md, and LOG.md with the final supported version and upgrade procedure
- [ ] Remove 0.11.5 only after an explicit later decision
## Phase 13.9 — Update external tools separately
## Phase 13.9 — Consolidate on Neovim 0.12 native features
- [x] Keep lazy.nvim as the plugin manager; do not combine the runtime upgrade with a migration to experimental `vim.pack`
- [ ] Replace `mbbill/undotree` with the optional native `nvim.undotree` package while preserving `<leader>u`
- [ ] Trial native automatic/LSP completion with explicit selection and built-in snippet expansion
- [ ] Enable Copilot inline suggestions with a distinct accept key and hide them while the native completion menu is visible
- [ ] Validate PHP, HTML, JavaScript/TypeScript, Markdown, Lua, paths, snippets, autopairs, and Copilot interactively
- [ ] Remove nvim-cmp, cmp-nvim-lsp, cmp-buffer, cmp-path, LuaSnip, and copilot-cmp only after the native workflow passes
- [ ] Remove obsolete completion integrations, lockfile entries, highlights, and documentation
## Phase 13.10 — Update external tools separately
- [ ] Review Mason package updates only after Neovim and plugin revisions are stable
- [ ] Update language servers, formatters, and linters in small groups
- [ ] Revalidate PHP, JavaScript/TypeScript, HTML/CSS, Markdown, Lua, and Python after each group

View file

@ -48,8 +48,8 @@ Core keymaps available globally (not plugin-specific). These provide fallbacks f
| n | `<leader>xX` | Diagnostics → quickfix | Populates project-wide diagnostics |
| n | `<leader>xe` | Diagnostics → buffer errors | Location list filtered to errors |
| n | `<leader>xE` | Diagnostics → all errors | Quickfix filtered to errors |
| n | `[d` | Diagnostics: previous item | Uses `vim.diagnostic.goto_prev` |
| n | `]d` | Diagnostics: next item | Uses `vim.diagnostic.goto_next` |
| n | `[d` | Diagnostics: previous item | Uses `vim.diagnostic.jump` with a negative count |
| n | `]d` | Diagnostics: next item | Uses `vim.diagnostic.jump` with a positive count |
| n | `<leader>xd` | Diagnostic float | Opens hover window for cursor diagnostic |
| n | `<leader>xt` | Toggle diagnostics | Flips `vim.diagnostic.enable()` |
| n | `<leader>gg` | Git: Changed files → quickfix | Lists all modified/deleted/untracked files with status |

View file

@ -12,7 +12,7 @@ require('keymaps_reference')
-- Bootstrap lazy.nvim
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
if not vim.uv.fs_stat(lazypath) then
vim.fn.system({
'git', 'clone', '--filter=blob:none', '--single-branch',
'https://github.com/folke/lazy.nvim.git', lazypath,

View file

@ -50,10 +50,10 @@ map('n', '<leader>xE', function()
vim.diagnostic.setqflist({ severity = vim.diagnostic.severity.ERROR })
end, { desc = 'Diagnostics: All errors (quickfix)', silent = true })
map('n', '[d', function()
vim.diagnostic.goto_prev({ float = false })
vim.diagnostic.jump({ count = -1, float = false })
end, { desc = 'Diagnostics: Previous diagnostic', silent = true })
map('n', ']d', function()
vim.diagnostic.goto_next({ float = false })
vim.diagnostic.jump({ count = 1, float = false })
end, { desc = 'Diagnostics: Next diagnostic', silent = true })
map('n', '<leader>xd', function()
pcall(vim.diagnostic.open_float)

View file

@ -52,8 +52,8 @@ return {
-- Note: This runs once at config load, checks cwd for phpcs.xml
local cwd = vim.fn.getcwd()
local has_project_ruleset =
vim.loop.fs_stat(cwd .. "/phpcs.xml")
or vim.loop.fs_stat(cwd .. "/phpcs.xml.dist")
vim.uv.fs_stat(cwd .. "/phpcs.xml")
or vim.uv.fs_stat(cwd .. "/phpcs.xml.dist")
local phpcs_args = { "-q", "--report=json" }
if not has_project_ruleset then

View file

@ -39,7 +39,7 @@ return {
-- Disable for very large files
disable = function(lang, buf)
local max_filesize = 100 * 1024 -- 100 KB
local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf))
local ok, stats = pcall(vim.uv.fs_stat, vim.api.nvim_buf_get_name(buf))
if ok and stats and stats.size > max_filesize then
return true
end