This commit is contained in:
Ray Elliott 2026-10-27 13:49:50 +00:00
commit dd3965a777
619 changed files with 136 additions and 110 deletions

99
LOG.md
View file

@ -76,7 +76,7 @@ Record every decision here with a short rationale. Append new entries; do not re
- **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, black formatter, ruff linter, treesitter parser
- **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)
@ -178,85 +178,40 @@ Record every decision here with a short rationale. Append new entries; do not re
- **No overrides needed**: Modern implementation doesn't require separate override file
- 2025-12-12: Added keymap reference documentation (now `README.md`) + `:KeymapsGuide` floating 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 `.vimtmp` backup 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.lua` settings are now read with `vim.secure.read()` before evaluation. This closes the trust bypass caused by manually calling `dofile()` 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-server` are available system-wide.
- 2026-10-27: Repaired `test-diagnostics.lua` so its intentional unreachable-code example remains valid Lua and can be parsed by `lua_ls`.
- 2026-10-27: Live validation confirmed Intelephense attaches in `WORKSPACE_TEST` and receives the trusted external `includePaths`. Conform reports prettier, phpcbf, and stylua available; nvim-lint resolves eslint_d, phpcs, and markdownlint.
- 2026-10-27: Updated `AGENTS.md` status and LSP architecture notes to reflect completed colorscheme work and the current Phase 12 implementation.
- 2026-10-27: Added Conform's built-in `ruff_format` for 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.
## Project-Local Configuration (design)
## Project-Local Configuration
Context: Projects can contain multiple git repositories (e.g., WordPress site with theme + multiple plugins). We need a way to set per-project `intelephense.includePaths` and similar without globalizing settings.
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.
Options considered
- Layered JSON files (recommended): `.nvim.json` (committed) + `.nvim.local.json` (gitignored)
- Walk upward from current file; collect and merge configs until reaching a boundary marker or filesystem root.
- Boundary marker: `.nvimroot` to define a workspace that can encompass multiple repos.
- Merge order: top → bottom; nearest wins on conflicts; arrays replace by default unless we later add a merge strategy.
- Pros: safe (data-only), portable, reviewable in PRs.
- Cons: less dynamic than Lua.
- Layered Lua files: `.nvim.lua` + `.nvim.local.lua`
- Pros: maximum flexibility (computed paths).
- Cons: executes code from the repo; security gates required.
- Env/direnv: rejected (decision 2025-12-06).
- Central registry file in `~/.config/nvim/`: possible later for private overrides, but not primary.
Example `.nvim.lua`:
Chosen approach (confirmed)
- Use `folke/neoconf.nvim` with `.neoconf.json` at the workspace root (or project roots) to supply LSP/plugin settings. Multi-repo: keep a single `.neoconf.json` at the parent workspace folder and open Neovim from there (or use a rooter later if needed).
Example `.neoconf.json`
```
{
"lspconfig": {
"intelephense": {
"settings": {
"intelephense": {
"environment": {
"includePaths": [
```lua
return {
lsp = {
intelephense = {
settings = {
intelephense = {
environment = {
includePaths = {
"wp-content/themes/my-theme",
"wp-content/plugins/custom-plugin"
]
}
}
}
}
}
}
```
- Files recognized per directory level:
- `.nvim.json`: checked into VCS; shared per-project defaults.
- `.nvim.local.json`: gitignored; machine-specific overrides.
- Loader behavior:
1. Start at the buffer’s directory; ascend toward root.
2. Stop at directory containing `.nvimroot` (if found) or at filesystem root.
3. At each level, if `.nvim.json` or `.nvim.local.json` exists, parse and stage for merge.
4. Merge staged configs in ascending order; nearest directory applies last.
- Path resolution:
- Relative paths resolve against the topmost boundary (i.e., `.nvimroot` directory if present; otherwise the highest directory in which a config was found). This allows referencing sibling repos (e.g., theme and plugins) from a single top-level site folder.
Example `.nvim.json`
```
{
"lsp": {
"php": {
"intelephense": {
"includePaths": [
"wp-content/themes/my-theme",
"wp-content/plugins/custom-plugin",
"vendor/some-package/src"
]
}
}
}
"wp-content/plugins/custom-plugin",
},
},
},
},
},
},
}
```
Intended integration
- A helper module `lua/local_config.lua` will expose:
- `load(start_dir) -> table` collecting and merging configs
- `get(path, default)` for reads, e.g., `get({"lsp","php","intelephense","includePaths"}, {})`
- LSP wiring (in Phase 3.5):
- Read includePaths via the helper and pass to `settings.intelephense.environment.includePaths` in `lspconfig.intelephense.setup{}`.
Open items to confirm
- Confirm JSON as the format (vs Lua) for project-local config.
- Confirm `.nvimroot` as the workspace boundary marker name.
- Confirm array merge behavior (replace vs concatenate). Initial proposal: replace.
Neoconf and the earlier layered JSON proposal were rejected. They remain in the chronological decision entries above only as superseded history.
## LSP Scope (initial)