Keep the loaded-buffer lifecycle protection while allowing Tree-sitter or Vim syntax highlighting; diagnostics and indent guides remain suppressed.
39 KiB
39 KiB
Neovim Rebuild — Decisions & Reference
Historical migration record and ongoing architectural decision log.
- Maintenance instructions:
AGENTS.md - Active workflows and keymap reference:
README.mdand:KeymapsGuide
Decisions Log
Record every decision here with a short rationale. Append new entries; do not rewrite history.
- 2025-01-13: Popup borders for visibility: Added rounded borders to all floating windows to prevent them from blending into the background. Changed
NormalFloatandFloatBorderbackgrounds from transparent (c.NONE) toc.bg_ui(slightly off-white) in colorscheme. Configured LSP handlers for hover and signature help to useborder = "rounded". Diagnostics already had borders configured. This provides clear visual separation between popups and main editor content. - 2025-01-13: Git files to quickfix: Added
<leader>ggkeymap to send all modified, deleted, and untracked Git files to quickfix list with status indicators. Usesgit status --porcelainto parse file status (Modified, Deleted, Added, Untracked, etc.) and displays it in the quickfix text column. Implementation inutils.git_changed_files(). Complements existing<leader>hq(Gitsigns hunks to quickfix) with file-level Git status workflow. - 2025-01-12: Custom Tabline Function: Implemented configurable custom tabline to replace Neovim's hardcoded path shortening (e.g.,
a/p/file.txt). Function inlua/utils.luaallows controlling: (1) number of full parent directories viautils.tabline_full_parents(default: 1), and (2) shortening length viautils.tabline_shorten_length(default: 3 characters). Example: with defaults,/path/to/my/project/src/file.txtbecomespat/to/my/project/src/file.txt. User preference for seeing enough context in shortened paths while keeping tab width manageable. - 2025-12-06: PHP LSP =
intelephense(good PHP ecosystem support; integrates includePaths). - 2025-12-06: Enable Markdown LSP =
marksman(lightweight, good MD features). - 2025-12-06: Use legacy
listcharsandshowbreakvalues (preserve muscle memory). - 2025-12-06: No direnv fallback for local config (keep setup simple and repo-driven).
- 2025-12-06: Project-local config = layered JSON
.nvim.json+.nvim.local.jsonwith.nvimrootas workspace boundary marker (multi-repo friendly). - 2025-12-06: Switch to
folke/neoconf.nvimfor project-local configuration (supersedes custom layered JSON loader); use.neoconf.jsonat workspace root. - 2025-12-06: Use
mason.nvim+mason-lspconfig.nvimto install/manage LSP servers; keep custom lspconfig setup; include.neoconf.jsonin root detection.- For PHP validation inside this repo: we require
.neoconf.jsonto attachintelephenseto avoid the repo’s.gitbeing chosen as the LSP root.
- For PHP validation inside this repo: we require
- 2025-12-06: Plugin approval policy — other plugins are allowed, but do not install any plugin not listed without explicit confirmation.
- 2025-12-07: CRITICAL REGRESSION FIX: Neovim 0.11+ does NOT support
on_new_configcallback invim.lsp.config(). Project-local settings (.nvim.lua) must be loaded viaLspAttachautocmd instead. Theon_new_confighook was silently ignored, causing empty settings and breaking goto-definition for external includes. Solution: UseLspAttachto load project settings, merge intoclient.settings, and sendworkspace/didChangeConfigurationnotification. - 2025-12-07: Native
exrc+.nvim.luafinalized as project-local config approach (replaces neoconf, which is incompatible with Neovim 0.11+ native LSP API). Security viavim.opt.secure = true. - 2025-12-07: Navigation Phase 4 decisions:
- Skip Neo-tree in favor of netrw for project visualization
- Use Telescope as primary "find file" tool with fuzzy finding
- Add Oil.nvim for file manipulation (rename/move/delete with buffer sync)
- netrw for tree view and preview splits; Oil for operations that would break buffer names
- PHP
gfenhancement viaincludeexprfor WordPress/PHP path resolution - Working directory locked to project root: Disabled
autochdir, setnetrw_keepdir = 1, captured initial cwd invim.g.project_root, configured Telescope to always search from project root regardless of current buffer
- 2026-07-06: Alternate-buffer netrw skip: Added a lightweight real-file buffer tracker and mapped
<C-6>/<C-^>so alternate-buffer jumps skip netrw explorer buffers when#points at netrw. Netrw buffers are also marked unlisted on FileType to reduce their impact on buffer navigation while preserving netrw browsing behavior. Fallback uses explicit:buffer #instead of:normal! <C-^>so regular alternate-file switching still works from the Lua mapping. - 2026-07-07: Netrw alternate detection fix: Real netrw alternate buffers can lose
filetype=netrwand remain as an unlistedNetrwTreeListingbuffer. The alternate-buffer skip now detects that buffer name as netrw so<C-6>returns to the previous real file instead of reopening an empty explorer buffer. - 2025-12-07: Treesitter Phase 5 decisions:
- Focus on core languages: PHP, HTML, JavaScript, TypeScript, CSS, Markdown, Lua, Bash, JSON
- Enable syntax highlighting with performance safeguard (disable for files >100KB)
- Incremental selection: CR to expand, BS to shrink, S-CR for scope expansion
- Textobjects for functions (
af/if), classes (ac/ic), parameters (aa/ia), conditionals, loops, comments - Movement keymaps:
]f/[ffor next/prev function,]c/[cfor classes,]a/[afor parameters - Parameter swapping:
<leader>a/<leader>Ato swap with next/prev parameter - Auto-tag for HTML/PHP/JS/React/TS/Vue files (auto-close, auto-rename, close-on-slash)
- Indent disabled initially (experimental); can enable per-filetype if stable
- 2025-12-07: UX/Editing Phase 6 decisions:
- Enable signcolumn=yes (always show for LSP diagnostics, git signs)
- Enable cursorline (highlight current line)
- Enable colorcolumn=80,120 (visual guides at 80 and 120 chars)
- NO cursorcolumn (as per AGENTS.md)
- NO auto-window toggling behavior (keep settings static, no per-window autocmds)
- NO motion plugin (skip leap/flash for simplicity)
- Undotree moved to separate phase (6.8)
- Comment.nvim for commenting (gcc/gc/gbc/gb keymaps)
- nvim-surround for text objects (ys/ds/cs operators)
- nvim-autopairs for auto-closing brackets/quotes with Treesitter and cmp integration
- indent-blankline for visual indent guides with scope highlighting
- nvim-ufo for enhanced folding with Treesitter/LSP providers (zR/zM/K for peek)
- undotree for visual undo history (u to toggle)
- 2025-12-07: Git integration Phase 7:
- Gitsigns with minimal config for signs in gutter (add, change, delete markers)
- Hunk navigation:
]h/[hfor next/prev hunk - Hunk actions: stage, reset, preview
- NO inline blame or advanced features (keep minimal)
- 2025-12-07: Copilot Phase 8:
- Integrated via copilot.lua + copilot-cmp (completion source)
- Auto-trigger suggestions as you type
- Copilot suggestions appear before LSP in completion menu (higher priority)
- Enabled for all filetypes
- No specific Copilot keymaps (use existing cmp keymaps)
- Node.js v22.21.1 confirmed working
- 2025-12-07: Formatting & Linting Phase 9:
- Philosophy: Formatters are authoritative; Neovim settings match formatter output
- Formatters: prettier (JS/TS/CSS/JSON/MD/HTML), phpcbf (PHP/WordPress), stylua (Lua), black (Python)
- Linters: eslint_d (JS/TS), phpcs (PHP/WordPress), markdownlint (Markdown), ruff (Python)
- Strategy: Project-local executables first (node_modules/.bin/, vendor/bin/), then Mason, then system PATH
- WordPress: phpcs/phpcbf already installed globally; use phpcs.xml or --standard=WordPress
- Format-on-save: Enabled by default, toggle with
<leader>lt - Manual format:
<leader>lf(buffer),<leader>lf(visual range) - Linting split: conform.nvim for formatting, nvim-lint for diagnostics (replaced none-ls after discovering phpcbf preprocessing bug)
- Python support: pyright LSP, ruff formatter/linter, treesitter parser (the original black plan was superseded)
- Per-filetype indentation: Explicit settings per filetype to match formatters
- PHP: tabs, 2-space display (WordPress standards)
- JS/TS/CSS/JSON/HTML: 2 spaces (Prettier)
- Lua: 2 spaces (common convention)
- Markdown: 2 spaces (Prettier)
- Python: 4 spaces (Black/PEP 8)
- Global defaults: 4 spaces (reasonable baseline for other filetypes)
- 2026-01-12: conform.nvim migration:
- Trigger: none-ls phpcbf builtin had preprocessing bug that added blank lines before formatting
- Root cause: none-ls uses LSP protocol for formatters, adds preprocessing step that corrupted input
- Investigation: Created debug wrappers, confirmed phpcbf CLI works correctly, traced issue to none-ls preprocessing
- Solution: Migrated to conform.nvim (modern, actively maintained, no LSP overhead)
- Configuration: Simplified config using conform's built-in formatters, only customized phpcbf for WordPress standard
- Benefits: Simpler code, no custom executable resolution needed, proper stdin/tmpfile handling per formatter
- Removed: none-ls.lua deleted (was renamed to .disabled during migration)
- 2025-12-07: Kept Behaviors Phase 10:
- Abbreviations: Common typo corrections (
adn→and,waht→what,tehn→then,functin→function,positin→position) in dedicatedlua/abbreviations.luafile for modularity - Templates: Shell script template (template.sh) auto-loaded via BufNewFile autocmd for
*.shfiles - Whitespace highlighting: Already handled via
listcharsin Phase 3.2 (settings.lua) - Persistent folds: Not needed; UFO handles folding without explicit persistence mechanism
- Persistent undo: Re-enabled 2025-01-06 via
undofile=trueandundodirin settings.lua (preserves undo history across sessions)
- Abbreviations: Common typo corrections (
- 2025-12-11: Colorscheme Phase 11.2:
- Color palette extraction: Extracted all 45 color definitions from original Paper Tonic colorscheme
- Structure: Created
lua/paper-tonic-modern/colors.luawith comprehensive documentation - Categories: Background colors (main, UI, highlights, status), foreground colors (text grays, exceptions), alerts/diagnostics, primary accents (brownish-red), and secondary accents (green/blue/cyan/magenta palettes)
- Format: Each color defined as
{hex, 256-color, ansi}tuple for broad terminal compatibility - Philosophy: Light, paper-like theme with subtle colors for long reading sessions
- Next steps: Phase 11.3 will create colorscheme structure and entry point
- 2025-12-11: Colorscheme Phase 11.3:
- Colorscheme structure: Created complete modular colorscheme architecture
- Entry point:
colors/paper-tonic-modern.luaproperly resets and loads colorscheme - Main module:
lua/paper-tonic-modern/init.luawith helper functions for setting highlights - Helper functions:
M.highlight()for single groups,M.highlight_all()for batch operations - Color conversion: Smart conversion between gui/cterm/ansi formats
- Group modules: Created stub files for editor, syntax, treesitter, semantic, lsp, and plugins
- Loading order: Structured to load groups in logical sequence (editor → syntax → treesitter → semantic → lsp → plugins)
- Validation: Colorscheme loads successfully, highlights applied correctly
- Language color consistency: All documentation updated to reflect that each language maintains its color identity everywhere (PHP=primary, HTML=blue, CSS=green, templates=magenta)
- 2025-12-11: Colorscheme Phase 11.4:
- Editor highlights: Comprehensive UI element highlighting (Normal, StatusLine, CursorLine, Visual, Search, Pmenu, Folds, Diffs, Spelling, Messages)
- Syntax highlights: Traditional Vim syntax groups (Comment, String, Function, Keyword, Type, etc.) with language-specific overrides
- Language support: Added specific highlighting for CSS (green/c2), HTML (blue/c3), Lua, Markdown, JSON, JavaScript/TypeScript, PHP
- Color verification: All key groups tested and verified (Normal=#8c8c8c on #ffffff, htmlTag=#005faf, cssClassName=#008700)
- CSS classes: Green tones (c2) for CSS syntax elements
- HTML tags: Blue tones (c3) for HTML structure
- PHP syntax: Primary brownish-red tones for PHP keywords/functions
- Test file: Created test-colorscheme.lua for visual verification
- 2025-12-11: Colorscheme Phase 11.5:
- TreeSitter highlights: Comprehensive modern
@*highlight groups implemented - Core groups: @variable, @function, @keyword, @string, @number, @boolean, @comment, @type, @property, @operator, @punctuation
- Language constructs: @keyword.function, @keyword.return, @keyword.conditional, @keyword.repeat, @keyword.exception
- Markup: @markup.strong, @markup.italic, @markup.heading (1-6), @markup.link, @markup.raw, @markup.list
- Template languages: @punctuation.special.twig, @keyword.jinja (magenta c5 for template syntax)
- Diagnostics: @diff.plus, @diff.minus, @diff.delta
- Debug tool: Added
<leader>hikeymap to show highlight group and resolved colors under cursor - Validation: All TreeSitter groups tested and verified with correct palette colors
- TreeSitter highlights: Comprehensive modern
- 2025-12-11: Colorscheme Phase 11.6:
- Language-specific TreeSitter groups: Enhanced with comprehensive per-language overrides
- CSS/SCSS: Properties, variables ($var, --custom), functions, tag selectors (green c2 tones)
- HTML: Tags, attributes, delimiters (blue c3 throughout)
- PHP: Variables ($var), functions, methods, built-ins ($this, $GLOBALS), properties (primary brownish-red)
- JavaScript/TypeScript: Variables, functions, properties, built-ins (this, arguments), JSX/TSX tags (primary + blue for JSX)
- Lua: Variables, functions, built-ins (_G, _VERSION), properties (primary)
- Markdown: Headings (1-6), links, code blocks, inline code (primary for structure)
- JSON: Properties, strings, numbers, booleans (neutral colors)
- Bash/Shell: Variables, functions, built-ins, strings (primary)
- Color consistency verified: HTML=#005faf (blue), CSS properties=#7c6666 (primary_weak), PHP variables=#7c6666
- Test files: Created test-html.html, test-css.css, test-colors.php for validation
- 2025-12-11: Colorscheme Phase 11.7:
- Semantic highlighting: Custom TreeSitter captures for cross-language consistency
- CSS semantic captures: @CssClassName (green c2), @CssIdentifier (strong green c2_strong, bold), @cssPseudoClass (bold brownish-red primary_strong - distinguishes from green selectors), @cssPseudoElement (bold brownish-red), @cssNestingSelector (strong green), @CssUniversalSelector
- CSS properties: @CssProp (primary_weak), @CssPropertyValue (bold fg), @CssUnit (delimiter)
- CSS media queries: @cssMediaFeatureName, @cssMediaQuery, @cssMediaQueryValue
- HTML attributes: @ClassNameAttribute, @IdAttribute, @DataAttribute (all fg_weak for attribute names)
- HTML data attributes: @DataAttributeValue (Function color)
- Cross-language consistency: Critical feature - class="my-class" in HTML uses same color (@CssClassName, green c2) as .my-class in CSS; id="my-id" in HTML uses same color (@CssIdentifier, green c2_strong) as #my-id in CSS
- Visual benefits: Easy to visually match selectors between HTML and CSS files; consistent color coding across languages
- Custom queries: Leverages existing after/queries/css/highlights.scm and after/queries/html/highlights.scm
- Priority fix: Added
(#set! priority 200)to all custom captures to override built-in captures (@string priority 99, @constant default priority) - Technical note: Custom queries require
;extendsdirective and higher priority than built-in captures to work correctly - Pseudo-class design: Uses bold brownish-red (primary_strong) instead of green to distinguish behavioral modifiers (:hover, :focus) from structural selectors (.class, #id)
- 2025-12-11: Colorscheme Phase 11.8:
- LSP highlights: Comprehensive diagnostic and UI highlights
- LSP diagnostics: Error (red #d70000), Warn (orange #d75f00), Info (blue #8989af), Hint (green #89af89)
- LSP diagnostic UI: Underlines (undercurl for errors/warnings), signs, floating windows, virtual text with tinted backgrounds
- LSP references: Cyan background gradients - Text (#e0eaff subtle), Read (#d4f0ff medium), Write (#a3e0ff strong)
- LSP semantic tokens: Fallback groups linking to TreeSitter equivalents for consistency
- Telescope highlights: Neutral base with primary accent for matching, selection, and titles
- Gitsigns highlights: Status colors - Add (green), Change (blue), Delete (red); inline diff backgrounds
- nvim-cmp highlights: Primary tones for item kinds, bold for match highlighting, italic for menu
- Oil.nvim highlights: Bold directories, status colors for permissions (read=green, write=orange, execute=blue), operation colors
- indent-blankline: Subtle grays for guides and scope
- nvim-ufo: Subtle backgrounds for folds with preview support
- 2025-12-11: Colorscheme Phase 11.9:
- Plugin configuration updated:
lua/plugins/colorscheme.lualoadspaper-tonic-modern - Cleanup: Moved old
paper-tonic/directory tolegacy/paper-tonic-original/ - Validation: Full config reload tested - all highlight groups load correctly
- Colorscheme integration: Native Neovim colorscheme at
colors/paper-tonic-modern.lua - No overrides needed: Modern implementation doesn't require separate override file
- Plugin configuration updated:
- 2025-12-12: Added keymap reference documentation (now
README.md) +:KeymapsGuidefloating viewer to document every configured keymap (global + plugin-specific) grouped by source file. - 2025-12-12: nvim-cmp updated to disable auto-selection; confirm requires explicit item selection.
- 2026-10-27: Phase 12 cleanup retired 607 tracked
.vimtmpbackup artifacts and a broken legacy Paper Tonic symlink while preserving the meaningful Vimscript archive. Added an ignore rule for the retired backup directory and corrected the legacy archive index. - 2026-10-27: Project
.nvim.luasettings are now read withvim.secure.read()before evaluation. This closes the trust bypass caused by manually callingdofile()from the LSP attachment callback. - 2026-10-27: Validation confirmed a clean Neovim 0.11.5 headless launch in approximately 45 ms with 29 configured plugins. Formatter and language-server executables managed by Mason are present in Mason's bin directory; PHP tools and
lua-language-serverare available system-wide. - 2026-10-27: Repaired
test-diagnostics.luaso its intentional unreachable-code example remains valid Lua and can be parsed bylua_ls. - 2026-10-27: Live validation confirmed Intelephense attaches in
WORKSPACE_TESTand receives the trusted externalincludePaths. Conform reports prettier, phpcbf, and stylua available; nvim-lint resolves eslint_d, phpcs, and markdownlint. - 2026-10-27: Updated
AGENTS.mdstatus and LSP architecture notes to reflect completed colorscheme work and the current Phase 12 implementation. - 2026-10-27: Added Conform's built-in
ruff_formatfor Python. Ruff was already Mason-managed for diagnostics; this closes a gap where documentation claimed Python formatting but format-on-save had no Python formatter and disabled LSP fallback. - 2026-10-27: Fixed
<C-6>in netrw when no previous real-file buffer has been recorded. Buffer classification now rejectsnil, non-numeric, and non-positive buffer identifiers before calling Neovim's buffer API, allowing the mapping to fall back safely. - 2026-10-27: Removed Oil.nvim after workflow evaluation. Netrw is now the sole tree browser and file explorer, preserving the same navigation model on remote systems; Telescope remains dedicated to fuzzy finding. Removed Oil's plugin spec, lockfile entry, keymaps, colorscheme groups, and active documentation.
- 2026-10-27: Planned the next work in two ordered phases. Phase 13 upgrades the standalone Neovim installation from 0.11.5 to stable 0.12.6 using versioned installations, isolated plugin testing, an unchanged initial lockfile, and an immediate rollback path; plugin updates follow only after core compatibility, and Mason tools remain a later step. Phase 14 then adds netrw-only live previews and read-only directory summaries against the validated 0.12 runtime.
- 2026-10-27: Recorded the pre-upgrade rollback baseline: Neovim 0.11.5, 28 active lazy.nvim plugin specs after Oil removal, 32 compiled Treesitter parser binaries, clean headless startup, all active Lua files parsing, and
git diff --checkpassing. The standalone 0.11.5 installation remains untouched under/opt/neovim/nvim-linux-x86_64. - 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 redundantvim.lsp.with()wrappers for hover and signature-help borders after 0.12 reported their deprecation; the sharedvim.lsp.util.open_floating_previewoverride 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.luaexplicitly configured and enabled the selected set. Disabled mason-lspconfig automatic activation, removed its obsoleteautomatic_installationoption, and aligned it with nvim-lspconfig's buffer events. This prevents unintended activation of installed tools such as StyLua's LSP mode and leaveslsp.luaas 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 toclient:notify(...), which works on both supported versions. - 2026-10-28: Replaced the remaining
vim.loop.fs_statcalls withvim.uv.fs_statand migrated[d/]dfrom deprecated diagnostic navigation functions tovim.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
exrcandsecureenabled through a normal XDG config, a trusted parent.nvim.luaexecuted exactly once andvim.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 netrwwould be redundant and would complicate 0.11 rollback compatibility.:Exploreopened the configured tree view,pcreated a real preview window, and<C-6>returned from the explorer to the source file. - 2026-10-28: Kept
mbbill/undotreeafter checking Neovim 0.12's built-in alternative. The nativenvim.undotreepackage is optional and remains unloaded; it exposes:Undotree, whereas the configured plugin's:UndotreeTogglecommand, 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.deprecatedscan now reports onlycopilot-cmp's upstreamclient.is_stoppedcall. 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 --checkis clean, and the measured 0.12 headless startup reachedNVIM STARTEDin approximately 43 ms with the existing locked plugins. - 2026-10-28: Updated plugins in an isolated Neovim 0.12 worktree and XDG environment. The candidate passed automated loading checks for LSP, completion, Telescope/fzf, Mason integration, formatting, linting, Gitsigns, indent guides, autopairs, surround, UFO, Undotree, and PHP/HTML/CSS/JavaScript Tree-sitter parsers and custom queries. Copilot's new native language-server download completed in isolation and the client authenticated successfully. Mason-managed tools were not updated.
- 2026-10-28: Kept
nvim-treesitterandnvim-treesitter-textobjectson their frozenmasterbranches. Their rewrittenmainbranches remove thenvim-treesitter.configsAPI used by this configuration and therefore require a separate migration; explicit branch pins prevent an ordinary plugin sync from crossing that boundary. Migrated the updated nvim-surround v4 configuration to its unchanged default mappings by removing the retiredopts.keymapsfield. - 2026-10-28: Disabled lazy.nvim's LuaRocks integration because no configured plugin requires LuaRocks. This removes the irrelevant missing-hererocks health error without adding a system dependency. Candidate health otherwise reports only optional missing language runtimes, the pending inline-Copilot migration, and the
copilot-cmpdeprecation that will disappear with that migration. - 2026-10-28: Adopted the isolated candidate's reviewed plugin lockfile and compatibility adjustments into the main worktree. Production plugin directories remain unchanged until the 0.12 activation step, preserving the working 0.11 rollback environment.
- 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.packmigration. After activating 0.12, replacembbill/undotreewith 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. - 2026-10-28: Activated Neovim 0.12.6 with the user-level selector
~/.local/bin/nvim, which precedes the older/optPATH entry. The root-owned/opt/neovimdirectory could not be reorganized without an interactive sudo password, so 0.11.5 remains intact at/opt/neovim/nvim-linux-x86_64/bin/nvim; rollback isln -sfn /opt/neovim/nvim-linux-x86_64/bin/nvim ~/.local/bin/nvim. - 2026-10-28: Implemented the 0.12 native editing trial. Native
nvim.undotreenow owns<leader>u; native autocomplete combines LSP omnifunc results and bounded buffer sources after a 150 ms delay, requires explicit selection, accepts with<C-y>, and uses built-in snippet tabstops. Copilot now supplies separate inline ghost text accepted with<M-l>and hides while the completion popup is visible. Removed the nvim-cmp, cmp source, LuaSnip, copilot-cmp, and external Undotree specs, integrations, lock entries, and highlight groups. - 2026-10-28: Refined native completion after the PTY smoke test showed buffer words sorting ahead of a valid PHP method. LSP-attached buffers now autocomplete exclusively from the LSP omnifunc;
<C-x><C-n>remains the explicit current-buffer word workflow, and non-LSP buffers retain bounded automatic word completion. This makes the first selectable language result predictable without losing native fallback completion. - 2026-10-28: Added narrow 0.12 guards around the new
autocompleteoption, source match limits, and optional native Undotree package. The retained 0.11.5 binary can therefore still start the configuration for emergency rollback, although native autocomplete and Undotree are intentionally unavailable until the selector is returned to 0.12.6. - 2026-10-28: Final smoke testing found that loading
nvim.undotreebefore lazy.nvim setup left its command registered but removed its Lua module path. Movedpackadd nvim.undotreeafter lazy.nvim finalizesruntimepath. The same test showed nvim-ts-autotag attaching to Markdown despite the intended filetype restriction; global autotag actions are now disabled and explicitly enabled only for HTML/PHP/JS/TS/Vue tag-bearing filetypes. - 2026-10-28: Active-runtime validation passed through the normal
nvimselector: native Undotree opens, netrw and Telescope load, PHP native completion offers and acceptsgreetExternal()with snippet syntax, Copilot's inline client is authenticated, Markdown no longer runs autotag, and HTML autotag exits Insert mode without errors.vim.deprecatedis clean. Remaining health warnings are optional missing language runtimes and the harmless unknownmarkdown.mdxfiletype hint. - 2026-10-28: Marked
neovim-migration-guide.mdas historical planning input. Its original Neo-tree, cmp, and plugin assumptions are retained for provenance but no longer compete with the active architecture documents. - 2026-10-28: User normal-use checks passed for the 0.12 native completion, snippet, autopairs, and inline Copilot workflow, closing the Phase 13.9 settling gate. Began Phase 14 with the confirmed netrw-only model:
pstarts previewing, cursor movement updates an existing preview, directories show read-only immediate-child summaries, and leaving netrw closes the preview. - 2026-10-28: Revalidated bundled netrw v184. Its documented
netrw#Call()bridge exposesNetrwGetWord,NetrwTreePath,NetrwBrowseChgDir, andNetrwPreview. In tree view,NetrwTreePathreturns the selected directory path or the selected file's parent, allowing local paths to be resolved without parsing indentation or mutating netrw's expand/collapse state. Remote URI targets will retain native fallback behavior. - 2026-10-28: Implemented Phase 14's plugin-free netrw preview extension in
lua/netrw-preview.lua. Pressingppreviews files through netrw's native machinery or shows a read-only immediate-child directory summary; while that preview window exists, a 90 ms buffer-local cursor debounce replaces it with the current selection. Manual:pclosestops updates, and leaving or wiping the explorer releases its preview and timer. Directory summaries are local-filesystem only, mirror netrw's active hide pattern, cap output at 200 entries, and never traverse symbolic links; remote URI schemes fall back to netrw's native preview path. - 2026-10-28: Automated Phase 14 checks passed for file/directory transitions, manual close and reopen, all four file-open actions, tree expansion and collapse, rapid cursor movement, spaces, Unicode, symlinks, empty and unreadable directories, and the 200-entry cap. A PTY-backed launch on a directory confirmed Neovim 0.12 enters the configured netrw tree, so no special
filetype=directoryhandling is required. Separate-tab, deleted-entry, and real SSH checks remain as interactive validation. - 2026-10-28: An isolated lifecycle rerun exposed netrw's focus hop into an existing preview window while replacing a directory summary through its native preview function. The extension now explicitly restores the netrw window after that call, preserving tree-focused
j/knavigation. Leave cleanup waits 20 ms before checking the settled current window and ignores callbacks raised while the native preview call is active, then closes only after a real explorer exit. The transient re-entrancy guard is not preview-mode state, and the cleanup timer is released when the netrw buffer is wiped. - 2026-10-28: Fixed a reproducible Neovim 0.12 Tree-sitter race during rapid cross-language netrw previews. Native
:peditunloads the previous preview buffer while its asynchronous parser may still be running, producingTSNode:range()errors. Preview-only file buffers are now kept loaded but unlisted for the rest of the Neovim session, with Tree-sitter highlighting suspended in favor of Vim syntax; avoiding parser detachment is necessary because delayed unloading reproduces the same race. Pre-existing buffer state is preserved, while entering a previewed file for real editing restores listed-buffer behavior and Tree-sitter immediately. An 80-step Markdown/Lua/JSON preview stress test, edit restoration check, retained-buffer check, and pre-existing-buffer check all pass. - 2026-10-28: Disabled diagnostic rendering in netrw file preview buffers. The preview metadata records each buffer's prior diagnostic state and restores it when the file is opened for editing, keeping ephemeral previews quiet without overriding buffers where diagnostics were already disabled.
- 2026-10-28: Made netrw file previews intentionally plain after CSS and HTML exposed residual colour. The remaining decoration was Vim regex syntax plus indent-blankline extmarks, not diagnostics or Tree-sitter. Preview buffers now clear
syntaxand disable their buffer-local indent guides, then restore both recorded states on real edit. - 2026-10-28: Added buffer-local netrw
<M-j>/<M-k>mappings to scroll the current preview with native<C-e>/<C-y>behavior while focus remains in the tree. The mappings accept Vim counts and quietly do nothing when no preview exists. - 2026-10-28: Hardened preview scrolling after an interactive over-scroll surfaced a window-local error that did not reproduce headlessly. The temporary preview-window call is now protected, so stale-window and boundary failures are treated like native top/bottom clamping instead of reaching the command line.
- 2026-10-28: Excluded netrw from automatic session persistence after
:mksessionserialized its generatedNetrwTreeListingname and restored an empty explorer buffer. Before the existing exit-time save, preview windows and netrw windows are removed; a netrw-only tab is dropped, while the sole remaining netrw window is replaced with an ordinary file buffer or a blank fallback. Netrw is intentionally not rebuilt on load. - 2026-10-28: Changed the enhanced netrw
pmapping into a true toggle. With no preview it opens the selected file or directory and begins live cursor updates; with an existing preview it closes that window and stops updates, matching manual:pclosebehavior. - 2026-10-28: Declared the migration complete after sustained daily use of the modern Lua configuration. Interactive navigation, language tooling, native completion, Copilot, formatting, linting, and the enhanced netrw workflow are considered validated. Real SSH URI previews and use of stock netrw without this configuration remain optional portability checks, not release gates. This decision also ends the requirement to retain migration-only archives and fixtures in the live repository; their removal will be handled as a separate, explicit cleanup.
- 2026-10-28: Replaced the migration-era
AGENTS.mdwith a concise maintenance guide for the established configuration. Removed completed phase tracking, obsolete validation-workspace instructions, resolved issue notes, and the target-tree description; retained current architectural guardrails, documentation expectations, a smoke-test command, and a short history note. - 2026-10-28: Retired the completed migration's legacy configuration, vendored plugin archive, UltiSnips collection, validation workspaces, root test assets, superseded planning documents, and phase labels in active Lua comments. Git history now provides the historical archive. Persistent undo storage moved from the configuration repository to
stdpath('state')/undo; the active README, architectural log, lockfile, colorscheme, spell data, and templates remain. - 2026-10-28: Diagnosed the Tree-sitter
TSNode:range()failure as the known incompatibility between Neovim 0.12 and nvim-treesitter's locked legacymasterbranch. Migrated nvim-treesitter and nvim-treesitter-textobjects to their rewrittenmainbranches: native Neovim highlighting and incremental selection replace the old modules, textobjects use explicit mappings, indentation uses the new plugin expression when a query exists, and autotag retains its direct supported setup. Installed the verified official Tree-sitter CLI 0.26.9 binary in~/.local/binafter the system package required interactive sudo and Cargo compilation required unavailable libclang. Reinstalled all configured parsers in the new site directory and removed obsolete generated parser copies from the plugin checkout. The plugin audit confirmed every plugin is current for its configured branch or release constraint; nvim-surround remains on the latest release rather than its newer unreleasedmaincommit. - 2026-10-28: Fixed stale deleted files persisting across session recreation. Deleting
Session.vimdid not clear the in-memory argument list or listed buffers, so:mksessionserialized the removed diagnostics fixture again. Session load and exit-time save now discard unmodified nonexistent local-file buffers and missing argument-list entries before restoring or writing the session; real files, URI buffers, unnamed buffers, and modified buffers remain protected. - 2026-10-28: Re-enabled highlighted netrw file previews after migrating to the Neovim 0.12-compatible nvim-treesitter
mainbranch. Preview buffers retain native Tree-sitter or Vim syntax highlighting, while diagnostics and indent guides remain suppressed. The existing loaded-but-unlisted buffer lifecycle protection remains in place so the original unload behavior is not restored. An automated 80-transition Markdown/Lua/JSON/CSS/HTML stress test and subsequent normal use passed withoutTSNode:range()errors, so the trial was adopted as the permanent behavior.
Project-Local Configuration
The final implementation uses Neovim's native exrc support with secure enabled. A project's trusted .nvim.lua returns an lsp table keyed by server name. An LspAttach callback securely reads settings from the client's actual root directory and sends them with workspace/didChangeConfiguration, so settings do not depend on Neovim's current working directory.
Example .nvim.lua:
return {
lsp = {
intelephense = {
settings = {
intelephense = {
environment = {
includePaths = {
"wp-content/themes/my-theme",
"wp-content/plugins/custom-plugin",
},
},
},
},
},
},
}
Neoconf and the earlier layered JSON proposal were rejected. They remain in the chronological decision entries above only as superseded history.
LSP Scope (initial)
- Core servers:
lua_ls,tsserver,html,cssls,jsonls,bashls - PHP:
intelephense(decision) - Markdown:
marksman(decision) - Keep configuration minimal; defer language-specific tuning.
Text & Editing Settings
spelllang = en_gblistcharsandshowbreakwill reuse legacy values.autocompletewithcompleteopt = menu,menuone,noselect,popup,fuzzyfor Neovim 0.12 native completion.
Maintenance Reminders
- Follow
AGENTS.mdfor current maintenance rules. - Update
README.mdwhen user-facing behavior changes. - Record significant architectural decisions in this log.
- Keep changes focused and verify affected workflows.