diff --git a/AGENTS.md b/AGENTS.md index 2714d17..08ba23f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -43,7 +43,7 @@ This repository is being migrated to a modern, minimal Neovim setup driven by Lu ├── oil.lua ├── ufo.lua ├── gitsigns.lua - ├── conform.lua + ├── none-ls.lua ├── nvim-lint.lua ├── mason.lua ├── mason-lspconfig.lua @@ -87,7 +87,7 @@ This repository is being migrated to a modern, minimal Neovim setup driven by Lu - UX/Editing: `Comment.nvim`, `nvim-surround`, `nvim-autopairs`, `indent-blankline.nvim`, `nvim-ufo`, `undotree`. - Git: `gitsigns.nvim`. - Copilot: `copilot.lua`, `copilot-cmp`. -- Formatting/Linting: `conform.nvim`, `nvim-lint`. +- Formatting/Linting: `none-ls.nvim`, `nvim-lint`. - LSP Management: `mason.nvim`, `mason-lspconfig.nvim`, `mason-tool-installer.nvim`. ## Workflow Requirements to Preserve @@ -115,7 +115,7 @@ This repository is being migrated to a modern, minimal Neovim setup driven by Lu - ✅ Phase 6: UX/Editing (Comment, surround, autopairs, indent guides, UFO, undotree) - ✅ Phase 7: Git integration (Gitsigns) - ✅ Phase 8: Copilot integration (copilot.lua + copilot-cmp) -- ✅ Phase 9: Formatting & Linting (conform.nvim, nvim-lint, Mason tool installer) +- ✅ Phase 9: Formatting & Linting (none-ls, nvim-lint, Mason tool installer) - ✅ Phase 10: Migrate kept behaviors (abbreviations, templates, custom Treesitter queries) - ⏸️ Phase 11: Cleanup & validation (pending) @@ -201,7 +201,6 @@ Was caused by settings loading at wrong time; fixed by using `LspAttach` autocmd - After any config or plugin change, immediately update `MIGRATION_PLAN.md` (check off items, add notes, or adjust next steps). - After any change or decision, also update `LOG.md:1` (decisions log and design docs). - **After adding/removing/editing any keymaps**, immediately update `README.md` with the change (add new entries, remove deleted mappings, or update descriptions). -- **After changing formatter/linter configuration, standards, or tool resolution**, immediately update the "Configuration" section in `README.md` (update tool lists, override instructions, or behavior descriptions). - At the start of each phase, confirm scope and priorities for that phase. - Execute phases via subphases (`N.x`), where each bullet under a phase is its own implement-and-test step (e.g., Phase 3.1, 3.2, 3.3, 3.4). - Record decisions and rationale in `LOG.md:1` as they're made. diff --git a/CONFORM_MIGRATION.md b/CONFORM_MIGRATION.md deleted file mode 100644 index da0bfd8..0000000 --- a/CONFORM_MIGRATION.md +++ /dev/null @@ -1,72 +0,0 @@ -# Migration Plan: none-ls → conform.nvim - -**Date:** 2026-01-12 -**Status:** ✅ **COMPLETED** -**Reason:** none-ls's phpcbf formatter is buggy (adds blank lines). conform.nvim is more modern, doesn't use LSP overhead, better maintained. - -## Current State - -**Formatting (conform.nvim):** -- ✅ prettier (JS/TS/CSS/JSON/HTML/Markdown) -- ✅ stylua (Lua) -- ✅ phpcbf (PHP) with WordPress standard - -**Linting (nvim-lint):** -- phpcs, eslint_d, markdownlint - -**LSP (lspconfig):** -- Language features (autocomplete, goto-def, hover, etc.) - -## Migration Checklist - -### Phase 1: Setup conform.nvim -- [x] Create `lua/plugins/conform.lua` -- [x] Configure formatters: - - [x] prettier (JS/TS/CSS/JSON/HTML/Markdown) - - [x] stylua (Lua) - - [x] phpcbf (PHP) with WordPress standard support -- [x] Configure format-on-save behavior -- [x] Set up project-local executable resolution (vendor/bin, node_modules/.bin, Mason, global) -- [x] Add keymaps for manual formatting (`lf`, `lt`) - -### Phase 2: Remove none-ls -- [x] Delete `lua/plugins/none-ls.lua` -- [x] Remove none-ls from lazy-lock.json (happens automatically on `:Lazy sync`) -- [x] Remove the custom phpcbf autocmd workaround (no longer needed) - -### Phase 3: Testing -- [x] Test prettier formatting (JS/TS/CSS files) -- [x] Test stylua formatting (Lua files) -- [x] Test phpcbf formatting (PHP files) - **verified NO blank lines added** -- [x] Test format-on-save toggle (`lt`) -- [x] Test manual format (`lf`) -- [x] Test project-local formatter detection -- [x] Verify phpcs.xml is respected when present - -### Phase 4: Documentation -- [x] Update README.md Configuration section -- [x] Update AGENTS.md Process section (plugin list, formatting tools) -- [x] Update MIGRATION_PLAN.md status (Phase 9.2) -- [x] Update LOG.md with decision and rationale - -## Expected Benefits - -1. **No more blank line bug** - conform calls phpcbf cleanly without none-ls's buggy preprocessing -2. **No LSP overhead** - formatters run as simple shell commands -3. **Better maintained** - conform.nvim is actively developed -4. **Cleaner architecture** - clear separation: LSP (features), nvim-lint (diagnostics), conform (formatting) -5. **Easier debugging** - simpler execution path, better error messages - -## Rollback Plan - -If conform.nvim has issues: -1. Restore `lua/plugins/none-ls.lua` from git -2. Keep the custom phpcbf autocmd for PHP -3. Run `:Lazy sync` to reinstall none-ls - -## Notes - -- conform.nvim has built-in support for all our formatters (prettier, stylua, phpcbf) -- It handles executable resolution similarly to our `find_executable()` helper -- Format-on-save can be toggled per-buffer or globally -- Visual range formatting supported out of the box diff --git a/LOG.md b/LOG.md index 0b8276a..f274dac 100644 --- a/LOG.md +++ b/LOG.md @@ -9,9 +9,6 @@ Authoritative notes for the Neovim migration. Use this alongside `MIGRATION_PLAN 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 `NormalFloat` and `FloatBorder` backgrounds from transparent (`c.NONE`) to `c.bg_ui` (slightly off-white) in colorscheme. Configured LSP handlers for hover and signature help to use `border = "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 `gg` keymap to send all modified, deleted, and untracked Git files to quickfix list with status indicators. Uses `git status --porcelain` to parse file status (Modified, Deleted, Added, Untracked, etc.) and displays it in the quickfix text column. Implementation in `utils.git_changed_files()`. Complements existing `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 in `lua/utils.lua` allows controlling: (1) number of full parent directories via `utils.tabline_full_parents` (default: 1), and (2) shortening length via `utils.tabline_shorten_length` (default: 3 characters). Example: with defaults, `/path/to/my/project/src/file.txt` becomes `pat/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 `listchars` and `showbreak` values (preserve muscle memory). @@ -29,9 +26,6 @@ Record every decision here with a short rationale. Append new entries; do not re - 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 `gf` enhancement via `includeexpr` for WordPress/PHP path resolution - - **Working directory locked to project root**: Disabled `autochdir`, set `netrw_keepdir = 1`, captured initial cwd in `vim.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 ``/`` 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! ` 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=netrw` and remain as an unlisted `NetrwTreeListing` buffer. The alternate-buffer skip now detects that buffer name as netrw so `` 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) @@ -75,7 +69,7 @@ Record every decision here with a short rationale. Append new entries; do not re - **WordPress**: phpcs/phpcbf already installed globally; use phpcs.xml or --standard=WordPress - **Format-on-save**: Enabled by default, toggle with `lt` - **Manual format**: `lf` (buffer), `lf` (visual range) - - **Linting split**: conform.nvim for formatting, nvim-lint for diagnostics (replaced none-ls after discovering phpcbf preprocessing bug) + - **Linting split**: none-ls for formatting only, nvim-lint for diagnostics (none-ls removed linters) - **Python support**: pyright LSP, black formatter, ruff linter, treesitter parser - **Per-filetype indentation**: Explicit settings per filetype to match formatters - PHP: tabs, 2-space display (WordPress standards) @@ -84,20 +78,11 @@ Record every decision here with a short rationale. Append new entries; do not re - 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 dedicated `lua/abbreviations.lua` file for modularity - **Templates**: Shell script template (template.sh) auto-loaded via BufNewFile autocmd for `*.sh` files - **Whitespace highlighting**: Already handled via `listchars` in 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=true` and `undodir` in settings.lua (preserves undo history across sessions) - 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.lua` with comprehensive documentation diff --git a/MIGRATION_PLAN.md b/MIGRATION_PLAN.md index 1286e61..665be63 100644 --- a/MIGRATION_PLAN.md +++ b/MIGRATION_PLAN.md @@ -24,7 +24,6 @@ Source of truth for the step-by-step rebuild. Keep this concise and up to date. ## Phase 1.6 — Preserve selected directories - [x] Keep `undodir`, `spell`, `view`, `UltiSnips`, `templates` as-is for now (review later) -- [x] Re-enabled persistent undo in settings.lua (2025-01-06) ## Phase 2 — Bootstrap @@ -275,13 +274,14 @@ Source of truth for the step-by-step rebuild. Keep this concise and up to date. - [x] Philosophy: Formatters are authoritative source of truth; Neovim settings should match formatter rules per filetype - [x] Note: Phase 9.4 will align Neovim editor settings (tabstop, shiftwidth, expandtab) with formatter configurations -## Phase 9.2 — conform.nvim setup with project-aware executables -- [x] Add `stevearc/conform.nvim` (replaced none-ls due to phpcbf preprocessing bug) -- [x] Configure formatters (conform has built-in support for all): - - [x] prettier (auto-detects project-local, Mason, global) - - [x] phpcbf (auto-detects project-local, global; customized for WordPress standard) - - [x] stylua (auto-detects project-local, Mason, global) -- [x] Add `mfussenegger/nvim-lint` for linting (separate from formatting) +## Phase 9.2 — none-ls setup with project-aware executables +- [x] Add `nvimtools/none-ls.nvim` +- [x] Create helper function to detect project-local executables (node_modules/.bin/, vendor/bin/, Mason bin) +- [x] Configure formatters: + - [x] prettier (project-local first, then Mason, then global) + - [x] phpcbf (project-local first, then global system install - already available) + - [x] stylua (Mason installed) +- [x] Add `mfussenegger/nvim-lint` for linting (none-ls removed most linters from builtins) - [x] Configure linters via nvim-lint: - [x] eslint_d (project-local first, then Mason, then global - daemon version for speed) - [x] phpcs (project-local first, then global system install - already available) @@ -289,9 +289,8 @@ Source of truth for the step-by-step rebuild. Keep this concise and up to date. - [x] Add format-on-save autocommand with toggle capability (`lt` to toggle) - [x] Add manual format keymaps: `lf` (buffer), `lf` (visual range) - [x] Ensure WordPress coding standards work via phpcs.xml or --standard flag -- [x] Search order handled by conform.nvim automatically: project → Mason → system PATH +- [x] Search order: project node_modules/.bin/ → project vendor/bin/ → Mason bin → system PATH - [x] Note: Linting runs on BufEnter, BufWritePost, InsertLeave events -- [x] Removed none-ls.lua (bug caused blank lines in PHP formatting) ## Phase 9.3 — Mason formatter/linter installation - [x] Add `WhoIsSethDaniel/mason-tool-installer.nvim` for automated installation @@ -336,12 +335,6 @@ Source of truth for the step-by-step rebuild. Keep this concise and up to date. - [x] Persistent folds (via UFO) -- no need, this is no longer required. - [x] Note: UFO handles folding; no explicit persistence mechanism needed -## Phase 10.6 — Custom tabline function -- [x] Implement custom tabline with configurable path shortening (`lua/utils.lua`) -- [x] Configure tabline in `lua/settings.lua` with `utils.tabline_full_parents` -- [x] Document tabline configuration in `README.md` -- [x] Show N parent directories in full, shorten earlier paths to first letter - ## Phase 11 — Colorscheme: Modern Paper Tonic ## Phase 11.1 — Confirm scope and priorities @@ -480,8 +473,6 @@ Source of truth for the step-by-step rebuild. Keep this concise and up to date. - [ ] Validate Telescope navigation + LSP jumps - [ ] Validate netrw browsing and preview splits - [ ] Validate Oil.nvim file operations -- [x] Fix working directory behavior (disabled autochdir, locked Telescope to project root) -- [x] Make alternate-buffer jumps skip netrw explorer buffers when returning to the last real file ## Phase 12.5 — Language tooling validation - [ ] Validate HTML/PHP/JS/Markdown tooling diff --git a/NAVIGATION_MODE_PLAN.md b/NAVIGATION_MODE_PLAN.md deleted file mode 100644 index d0f21db..0000000 --- a/NAVIGATION_MODE_PLAN.md +++ /dev/null @@ -1,519 +0,0 @@ -# Navigation Enhancement Plans - -**Status**: Two complementary approaches being considered (not mutually exclusive) - -Both approaches aim to reduce repetitive typing when navigating with Neovim's bracket-based pairs (`[c`, `]d`, etc.). - ---- - -## Option 1: Repeat/Reverse Last Bracket Navigation - -### Concept -Two simple commands that remember and replay the last `[x` or `]x` navigation: -- **Repeat**: Execute the same navigation again (e.g., `]d` → `.` → `.` → `.`) -- **Reverse**: Execute the opposite direction (e.g., after `]d`, press `,` → `[d`) - -Similar to `;` and `,` for repeating/reversing `f/F/t/T` motions. - -### User Experience - -```vim -" Example 1: Scanning diagnostics -]d " Next diagnostic -. " Next diagnostic (repeat) -. " Next diagnostic (repeat) -. " Next diagnostic (repeat) -, " Previous diagnostic (reverse, oops went too far) - -" Example 2: Checking spelling -]s " Next misspelling -. " Next misspelling -. " Next misspelling - -" Example 3: Quickfix workflow -]q " Next quickfix item -. " Next quickfix -. " Next quickfix -``` - -### When This Works Best -- Repeatedly navigating **same type**: diagnostics, spelling, quickfix, location list -- Linear scanning through items of one kind -- Quick corrections when you overshoot (reverse) - -### Implementation - -**Module**: `lua/bracket-repeat.lua` - -```lua -local M = {} - --- Track last bracket navigation -local last_nav = { - prefix = nil, -- '[' or ']' - key = nil, -- 'c', 'd', 'm', 's', 'q', etc. -} - ---- Setup wrapper mappings to track bracket navigation -function M.setup() - -- Common bracket pairs to track - local pairs = { - 'c', -- Git hunks (gitsigns) - 'd', -- Diagnostics - 's', -- Spelling - 'q', -- Quickfix - 'l', -- Location list - 't', -- Tags - 'm', -- Methods (treesitter) - 'f', -- Functions (treesitter) - 'p', -- Parameters (treesitter) - } - - for _, key in ipairs(pairs) do - -- Wrap [x to track - vim.keymap.set('n', '[' .. key, function() - last_nav.prefix = '[' - last_nav.key = key - return '[' .. key - end, { expr = true, silent = true }) - - -- Wrap ]x to track - vim.keymap.set('n', ']' .. key, function() - last_nav.prefix = ']' - last_nav.key = key - return ']' .. key - end, { expr = true, silent = true }) - end -end - ---- Repeat last bracket navigation -function M.repeat_last() - if not last_nav.prefix or not last_nav.key then - vim.notify('No bracket navigation to repeat', vim.log.levels.WARN) - return - end - vim.cmd('normal! ' .. last_nav.prefix .. last_nav.key) -end - ---- Reverse last bracket navigation (flip direction) -function M.reverse_last() - if not last_nav.prefix or not last_nav.key then - vim.notify('No bracket navigation to reverse', vim.log.levels.WARN) - return - end - local opposite = last_nav.prefix == '[' and ']' or '[' - vim.cmd('normal! ' .. opposite .. last_nav.key) - -- Update tracking to reflect the reversal - last_nav.prefix = opposite -end - -return M -``` - -**Integration**: `init.lua` or `lua/keymaps.lua` - -```lua --- Setup tracking -require('bracket-repeat').setup() - --- Keybindings (choose one option) - --- Option A: Override ; and , (loses f/F/t/T repeat, but very ergonomic) -vim.keymap.set('n', ';', function() require('bracket-repeat').repeat_last() end, - { desc = 'Repeat bracket navigation' }) -vim.keymap.set('n', ',', function() require('bracket-repeat').reverse_last() end, - { desc = 'Reverse bracket navigation' }) - --- Option B: Use z prefix (keeps ; and , for f/t motions) -vim.keymap.set('n', 'z.', function() require('bracket-repeat').repeat_last() end, - { desc = 'Repeat bracket navigation' }) -vim.keymap.set('n', 'z,', function() require('bracket-repeat').reverse_last() end, - { desc = 'Reverse bracket navigation' }) - --- Option C: Use leader -vim.keymap.set('n', '.', function() require('bracket-repeat').repeat_last() end, - { desc = 'Repeat bracket navigation' }) -vim.keymap.set('n', ',', function() require('bracket-repeat').reverse_last() end, - { desc = 'Reverse bracket navigation' }) -``` - -### Pros & Cons - -**Pros:** -- ✅ Very simple (~40 lines) -- ✅ No mode switching, stays in normal mode -- ✅ Familiar pattern (like `;`/`,` for `f`/`t`) -- ✅ Works with natural workflow -- ✅ Easy to add more tracked pairs - -**Cons:** -- ⚠️ Only handles one "type" at a time (can't easily switch between `]d` and `]c`) -- ⚠️ Requires calling `.setup()` to track pairs -- ⚠️ Might want `;`/`,` for `f`/`t` repeat (depends on keybinding choice) - -### Estimated Complexity -- **Total**: ~40 lines -- **Time**: 15-30 minutes - ---- - -## Option 2: Navigation Mode (getchar Loop) - -## User Experience - -### Entry -- `z[` - Enter navigation mode with `[` prefix active (backward) -- `z]` - Enter navigation mode with `]` prefix active (forward) - -### In Mode -- All letter keys (`a-z`, `A-Z`) get prefixed with current bracket -- Examples: - - Press `c` → executes `[c` or `]c` (git hunks) - - Press `d` → executes `[d` or `]d` (diagnostics) - - Press `m` → executes `[m` or `]m` (methods) - - Press `f` → executes `[f` or `]f` (functions) - - Press `b` → executes `[b` or `]b` (buffers) - - Press `q` → executes `[q` or `]q` (quickfix) - -### Toggle Prefix -- `[` - Switch to `[` prefix (backward navigation) -- `]` - Switch to `]` prefix (forward navigation) - -### Exit -- `` - Exit navigation mode and return to normal editing - -### When This Works Best -- Switching between **different types** of navigation (`]d` → `]c` → `]m`) -- Want visual feedback showing current direction -- Prefer a dedicated "navigation state" -- Mixed workflow: `]q` to quickfix, then multiple `]c` for hunks (stay in mode, switch keys) - -### Example Workflow - -```vim -" Mixed navigation scenario -z] " Enter forward navigation mode (shows: NAV ] →:) -q " Execute ]q (next quickfix) -c " Execute ]c (next hunk) -c " Execute ]c (next hunk) -[ " Toggle to backward (shows: NAV [ ←:) -c " Execute [c (previous hunk) -d " Execute [d (previous diagnostic) - " Exit mode -``` - -## Technical Implementation - -### Approach: getchar() Loop (No Remapping) - -Instead of remapping keys, use a `while` loop with `vim.fn.getchar()` to read keypresses and manually execute the prefixed commands. - -**Why this approach:** -- ✅ Zero mapping conflicts (never touches existing keymaps) -- ✅ Simpler implementation (~50-80 lines vs ~150-250) -- ✅ Built-in visual feedback via `vim.api.nvim_echo()` -- ✅ Impossible to leak state (no cleanup needed if crashed) -- ✅ Predictable behavior (each keypress isolated) -- ✅ Naturally handles special keys - -**The "blocking" behavior is actually desired** - you're in a focused navigation mode, press `` to exit anytime. - -### Common Bracket Navigation Pairs -- `[c`/`]c` - Previous/next git hunk (gitsigns) -- `[d`/`]d` - Previous/next diagnostic -- `[b`/`]b` - Previous/next buffer (custom mapping) -- `[q`/`]q` - Previous/next quickfix item -- `[l`/`]l` - Previous/next location list item -- `[m`/`]m` - Previous/next method (treesitter textobjects) -- `[f`/`]f` - Previous/next function (treesitter textobjects) -- `[p`/`]p` - Previous/next parameter (treesitter textobjects) -- `[t`/`]t` - Previous/next tag - -## Implementation Details - -### Module Structure -Create `lua/navigation-mode.lua`: - -```lua -local M = {} - ---- Enter navigation mode with getchar() loop ---- @param prefix string Either '[' or ']' -function M.enter(prefix) - prefix = prefix or '[' - - while true do - -- Display prompt - local hl = prefix == '[' and 'DiagnosticInfo' or 'DiagnosticHint' - local arrow = prefix == '[' and '←' or '→' - vim.api.nvim_echo({{string.format('NAV %s %s: ', prefix, arrow), hl}}, false, {}) - - -- Get next keypress - local ok, char = pcall(vim.fn.getchar) - if not ok then break end -- Handle gracefully - - -- Convert to string - local key = type(char) == 'number' and vim.fn.nr2char(char) or char - - -- Handle special keys - if key == '\27' then -- ESC - break - elseif key == '[' then - prefix = '[' - elseif key == ']' then - prefix = ']' - else - -- Execute prefix + key as normal mode command - local cmd = prefix .. key - vim.cmd('normal! ' .. vim.api.nvim_replace_termcodes(cmd, true, false, true)) - end - end - - -- Clear prompt - vim.api.nvim_echo({{'', 'Normal'}}, false, {}) -end - -return M -``` - -**Key Points:** -- No state management needed (self-contained loop) -- `pcall(vim.fn.getchar)` handles `` interrupts gracefully -- `vim.api.nvim_replace_termcodes()` ensures special key sequences work -- Visual feedback built into the loop (shows `NAV [ ←:` or `NAV ] →:`) -- Press `[` or `]` to toggle prefix without exiting -- Press `` (or ``) to exit - -### Integration in keymaps.lua -```lua --- Navigation mode -vim.keymap.set('n', 'z[', function() - require('navigation-mode').enter('[') -end, { desc = 'Enter navigation mode (backward)' }) - -vim.keymap.set('n', 'z]', function() - require('navigation-mode').enter(']') -end, { desc = 'Enter navigation mode (forward)' }) -``` - -## Visual Feedback - -Built into the getchar() loop: -- Shows `NAV [ ←:` (in blue) when in backward mode -- Shows `NAV ] →:` (in teal) when in forward mode -- Prompt updates immediately when toggling with `[` or `]` -- Clears when exiting with `` - -No additional statusline integration needed - the command line prompt is clear and non-intrusive. - -## Design Decisions - -### Mapping Conflicts: Solved -No mapping conflicts possible - getchar() reads raw input without touching keymaps. - -### Buffer-local Mappings: Not Applicable -Loop executes `normal! [key` which uses whatever mappings exist naturally. - -### Visual Feedback: Built-in -Command line prompt is sufficient and non-intrusive. - -### Number Keys -Currently not prefixed - this allows using counts if a prefixed command accepts them. -Example: `3c` → executes `[3c` or `]3c` (may not be useful, but won't break anything) - -Could add special handling if needed: -```lua -if key:match('^%d$') then - -- Handle numbers specially -end -``` - -### Operators (d, c, y, etc.) -In navigation mode, `d` executes `[d` (diagnostic navigation), not delete operator. -This is desired behavior - use `` to exit and edit normally. - -### Error Handling -If a command doesn't exist (e.g., `[z`), Vim will show an error but mode continues. -User can press `` to exit or try another key. - -### Pros & Cons - -**Pros:** -- ✅ Switch between different navigation types easily (`c` → `d` → `m`) -- ✅ Visual feedback (command line prompt) -- ✅ No mapping conflicts -- ✅ Clean state (nothing to cleanup if interrupted) -- ✅ Natural for rapid mixed navigation - -**Cons:** -- ⚠️ Requires mode switching (mental overhead) -- ⚠️ Blocking loop (though this is by design) -- ⚠️ Need to remember entry/exit keys - -### Estimated Complexity -- **Total**: ~50-80 lines -- **Time**: 30-60 minutes - ---- - -## Comparison & Recommendation - -| Aspect | Repeat/Reverse | Navigation Mode | -|--------|---------------|----------------| -| **Best for** | Same-type scanning | Mixed navigation | -| **Complexity** | ~40 lines | ~50-80 lines | -| **Mental model** | Like `;`/`,` | New mode | -| **Typing (4× same nav)** | `]d ...` (4 keys) | `z] dddd ` (9 keys) | -| **Typing (mixed nav)** | `]d ]d ]c ]c` (8 keys) | `z] ddcc ` (9 keys) | -| **Mode switching** | No | Yes | -| **Visual feedback** | No (unless added) | Yes (built-in) | - -### Use Cases - -**Repeat/Reverse excels at:** -- Scanning diagnostics: `]d . . . .` -- Spell checking: `]s . . . .` -- Reviewing quickfix: `]q . . . .` -- Going back: `. . . , , ,` - -**Navigation Mode excels at:** -- Mixed workflow: `]q` → multiple `]c` hunks → check `]d` diagnostic -- When you want visual confirmation of direction -- Exploring unfamiliar code (trying different navigation types) - -### Implementation Strategy - -**Both can coexist!** They solve slightly different problems: - -1. **Start with Repeat/Reverse** (simpler, covers 80% of cases) - - Use for linear scanning (diagnostics, spelling, quickfix) - - Bind to `z.` and `z,` (or `;`/`,` if you don't use `f`/`t` repeat often) - -2. **Add Navigation Mode later** (optional, for mixed navigation) - - Use when you need to rapidly switch types - - Bind to `z[` and `z]` - -You'll naturally reach for whichever fits the situation better. - ---- - -## Common Bracket Pairs Reference - -- `[c`/`]c` - Previous/next git hunk (gitsigns) -- `[d`/`]d` - Previous/next diagnostic -- `[s`/`]s` - Previous/next misspelling -- `[q`/`]q` - Previous/next quickfix item -- `[l`/`]l` - Previous/next location list item -- `[m`/`]m` - Previous/next method (treesitter textobjects) -- `[f`/`]f` - Previous/next function (treesitter textobjects) -- `[p`/`]p` - Previous/next parameter (treesitter textobjects) -- `[t`/`]t` - Previous/next tag -- `[b`/`]b` - Previous/next buffer (if custom mapping exists) - ---- - -## Testing Checklists - -### Repeat/Reverse Testing -- [ ] Setup completes without errors -- [ ] `]d` followed by `.` repeats diagnostic navigation -- [ ] `]s` followed by `.` repeats spelling navigation -- [ ] `]q` followed by `.` repeats quickfix navigation -- [ ] `,` reverses last navigation direction -- [ ] Warning shown when no navigation to repeat/reverse -- [ ] Works across different buffers -- [ ] Multiple reverses work: `. . . , , ,` - -### Navigation Mode Testing -- [ ] Enter mode with `z[` and `z]` -- [ ] Verify visual prompt shows `NAV [ ←:` or `NAV ] →:` -- [ ] Press `c` → navigates to previous/next git hunk -- [ ] Press `d` → navigates to previous/next diagnostic -- [ ] Press `m` → navigates to previous/next method -- [ ] Press `f` → navigates to previous/next function -- [ ] Toggle with `[` → prompt updates to `NAV [ ←:` -- [ ] Toggle with `]` → prompt updates to `NAV ] →:` -- [ ] Exit with `` → prompt clears, back to normal mode -- [ ] Exit with `` → handles gracefully -- [ ] Works across different buffers -- [ ] Invalid keys (e.g., `z`) show error but don't crash -- [ ] Existing keymaps still work after exit - ---- - -## Implementation Priority - -**Recommended order:** - -1. **Phase 1: Repeat/Reverse** (start here) - - Simpler, faster to implement - - Covers most common use cases - - Get immediate value - -2. **Phase 2: Navigation Mode** (optional, evaluate need) - - Implement only if you find yourself wanting mixed navigation - - Can be added anytime without conflicts - - Both features work together - -**Time estimate:** -- Phase 1: 15-30 minutes -- Phase 2: 30-60 minutes -- Total: 45-90 minutes if both implemented - ---- - -## Implementation Steps - -### For Repeat/Reverse (Start Here) - -1. **Create `lua/bracket-repeat.lua`** (~40 lines) - - Implement tracking state - - Implement `setup()`, `repeat_last()`, `reverse_last()` - -2. **Add to `init.lua`** - ```lua - require('bracket-repeat').setup() - ``` - -3. **Add keymaps** (`lua/keymaps.lua`) - ```lua - vim.keymap.set('n', 'z.', function() require('bracket-repeat').repeat_last() end) - vim.keymap.set('n', 'z,', function() require('bracket-repeat').reverse_last() end) - ``` - -4. **Test** with diagnostics, spelling, quickfix - -5. **Document** in README.md - -### For Navigation Mode (Optional Later) - -1. **Create `lua/navigation-mode.lua`** (~50 lines) - - Implement `M.enter(prefix)` with getchar() loop - - Handle ESC, `[`, `]`, and general keys - - Add visual feedback via `nvim_echo` - -2. **Add keymaps** (`lua/keymaps.lua`) - ```lua - vim.keymap.set('n', 'z[', function() - require('navigation-mode').enter('[') - end, { desc = 'Navigation mode (backward)' }) - - vim.keymap.set('n', 'z]', function() - require('navigation-mode').enter(']') - end, { desc = 'Navigation mode (forward)' }) - ``` - -3. **Test basic functionality** - - Enter with `z[` / `z]` - - Navigate with `c`, `d`, `m`, `f`, `q` - - Toggle prefix with `[` / `]` - - Exit with `` - -4. **Polish** (optional) - - Add help text on first use - - Handle `` gracefully (already done with `pcall`) - - Consider adding common navigation cheatsheet - -5. **Document** - - Update `README.md` with new keymaps - - Add navigation pairs reference diff --git a/README.md b/README.md index 067fc05..45d1cf5 100644 --- a/README.md +++ b/README.md @@ -40,10 +40,6 @@ Core keymaps available globally (not plugin-specific). These provide fallbacks f | n | `gr` | LSP references placeholder | `` so LSP buffers can override cleanly | | n | `gI` | LSP implementation placeholder | `` so LSP buffers can override cleanly | | n | `K` | Keyword help fallback | Uses `keywordprg` (e.g., `man`) when LSP hover is unavailable | -| n | `co` | Quickfix: Open | Opens quickfix window | -| n | `cc` | Quickfix: Close | Closes quickfix window | -| n | `lo` | Location list: Open | Opens location list window | -| n | `lc` | Location list: Close | Closes location list window | | n | `xx` | Diagnostics → location list | Populates current buffer diagnostics | | n | `xX` | Diagnostics → quickfix | Populates project-wide diagnostics | | n | `xe` | Diagnostics → buffer errors | Location list filtered to errors | @@ -52,75 +48,14 @@ Core keymaps available globally (not plugin-specific). These provide fallbacks f | n | `]d` | Diagnostics: next item | Uses `vim.diagnostic.goto_next` | | n | `xd` | Diagnostic float | Opens hover window for cursor diagnostic | | n | `xt` | Toggle diagnostics | Flips `vim.diagnostic.enable()` | -| n | `gg` | Git: Changed files → quickfix | Lists all modified/deleted/untracked files with status | | n | `hi` | Highlight inspector | Shows highlight/capture stack under cursor | -| n | `bg` | Toggle background (light/dark) | Switches between light and dark colorscheme modes | ### `lua/netrw-config.lua` -#### `:Ex` Command Variants - -| Command | Opens netrw at | -| --- | --- | -| `:Ex` | Current working directory (`:pwd`) | -| `:Ex .` | Current file's directory | -| `:Ex %:h` | Current file's directory (explicit) | -| `:Ex /path/to/dir` | Specific path | - -#### Custom Keymaps - | Mode | Key | Description | | --- | --- | --- | -| n | `nt` | Open netrw in new tab at current file's directory | -| n | `nT` | Open netrw in new tab at project root | -| n | `nr` | Open netrw in current window at project root | -| n | `` / `` | Jump to alternate file, skipping netrw explorer buffers | - -**Note:** Project root is stored as the initial working directory when Neovim starts. This allows navigation back to the project root even after following symlinks to external directories. - -#### Default Netrw Keymaps - -##### Navigation & View - -| Key | Description | -| --- | --- | -| `` | Open file/directory under cursor | -| `-` | Go up to parent directory | -| `gh` | Toggle hidden files visibility (dotfiles) | -| `i` | Cycle through view types (thin/long/wide/tree) | -| `s` | Cycle sort order (name/time/size/extension) | -| `r` | Reverse current sort order | -| `I` | Toggle netrw banner (help text) | - -##### Preview & Splits - -| Key | Description | -| --- | --- | -| `p` | Preview file in horizontal split (50% window size) | -| `P` | Open file in previous window | -| `o` | Open file in horizontal split below | -| `v` | Open file in vertical split | - -##### File Operations - -| Key | Description | -| --- | --- | -| `%` | Create new file (prompts for name) | -| `d` | Create new directory (prompts for name) | -| `D` | Delete file/directory under cursor | -| `R` | Rename/move file under cursor | - -##### Marking & Batch Operations - -| Key | Description | -| --- | --- | -| `mf` | Mark file (for batch operations) | -| `mr` | Mark files using regex pattern | -| `mu` | Unmark all marked files | -| `mt` | Set mark target directory (for move/copy destination) | -| `mc` | Copy marked files to target directory | -| `mm` | Move marked files to target directory | -| `qf` | Display file info | +| n | `te` | Open netrw in a new tab rooted at current file directory | +| n | `tE` | Open netrw in a new tab rooted at project cwd | ## Plugin Reference @@ -138,7 +73,7 @@ Buffer-local keymaps available when an LSP client attaches: | n | `gI` | LSP: implementation | | n | `K` | LSP hover | -### Conform (Formatting) `lua/plugins/conform.lua` +### None-ls (Formatting) `lua/plugins/none-ls.lua` #### Keymaps @@ -179,7 +114,6 @@ Buffer-local keymaps available when inside a git repository: | n | `hp` | Preview hunk | | n | `hd` | Diff against index | | n | `hD` | Diff against previous commit (`~`) | -| n | `hq` | Send all hunks to quickfix list | | o/x | `ih` | Text object: select git hunk | ### Telescope `lua/plugins/telescope.lua` @@ -370,139 +304,3 @@ Buffer-local keymaps available when inside a git repository: | Mode | Key | Description | | --- | --- | --- | | insert | `` | Fast wrap the previous text with a pair | - -## Configuration - -### Formatting & Linting - -This config uses **conform.nvim** for formatting and **nvim-lint** for diagnostics. Both prefer project-local tools over global installations. - -#### Executable Resolution Order - -When looking for formatters/linters, the config searches in this priority: - -1. **Project-local** (e.g., `node_modules/.bin/`, `vendor/bin/`) -2. **Mason-managed** (`~/.local/share/nvim/mason/bin/`) -3. **System PATH** (globally installed tools) - -Conform.nvim handles this resolution automatically via its built-in `util.find_executable()`. nvim-lint uses a custom `find_executable()` helper in `lua/plugins/nvim-lint.lua`. - -#### Configured Tools - -**Formatters** (`lua/plugins/conform.lua`): -- **JavaScript/TypeScript/CSS/JSON/HTML/Markdown**: `prettier` -- **PHP**: `phpcbf` (WordPress standard by default) -- **Lua**: `stylua` -- **Python**: handled by `ruff` LSP (not conform) - -**Linters** (`lua/plugins/nvim-lint.lua`): -- **JavaScript/TypeScript**: `eslint_d` -- **PHP**: `phpcs` (WordPress standard by default) -- **Markdown**: `markdownlint` (disabled by default; use `:MarkdownLintEnable`) -- **Python**: handled by `ruff` LSP (not nvim-lint) - -#### Project-Specific Overrides - -Both formatters and linters respect project-level configuration files: - -**PHP** (phpcbf + phpcs): -- Create `phpcs.xml` or `phpcs.xml.dist` in your project root -- When present, this file controls the coding standard (e.g., PSR-12, WordPress, custom) -- When absent, defaults to `--standard=WordPress` - -Example `phpcs.xml`: -```xml - - - Project-specific PHP rules - - - - - - - - - - -``` - -**JavaScript/TypeScript** (prettier + eslint): -- Project config files: `.prettierrc`, `.eslintrc.json`, `eslint.config.js`, etc. -- Global fallback: `~/.eslintrc.json` (when no project config exists) - -**Lua** (stylua): -- Project config: `stylua.toml` or `.stylua.toml` -- Falls back to stylua defaults if not present - -**Markdown** (markdownlint): -- Project config: `.markdownlint.json`, `.markdownlintrc` - -#### Changing Standards Per-Project - -To switch a PHP project from WordPress to PSR-12: - -1. Create `phpcs.xml` in project root: - ```xml - - - - - ``` - -2. Restart Neovim (or reload config: `:source $MYVIMRC`) - -Both `phpcs` and `phpcbf` will now use PSR-12 rules in that project. - -#### Format-on-Save - -- **Enabled by default** for all supported filetypes -- **Toggle**: `lt` (see keymaps below) -- **Manual format**: `lf` (buffer or visual selection) - -#### Linting Behavior - -- **Automatic**: Runs on `BufEnter`, `BufWritePost`, `InsertLeave` -- **Per-filetype**: Configured in `lint.linters_by_ft` table -- **Markdown**: Opt-in only (`:MarkdownLintEnable` / `:MarkdownLintDisable`) - -## Configuration Options - -### Tabline Display - -Custom tabline shows intelligent path shortening with two configurable options. - -**Location:** `lua/settings.lua` (configured via `utils.tabline_full_parents` and `utils.tabline_shorten_length`) - -**Configuration Options:** - -1. **`utils.tabline_full_parents`** (default: `1`) - Number of parent directories to show in full -2. **`utils.tabline_shorten_length`** (default: `3`) - Number of characters to show for shortened directories - -**Examples:** - -With `full_parents = 1, shorten_length = 3`: -- `/path/to/my/project/src/file.txt` → `pat/to/my/project/src/file.txt` - -With `full_parents = 2, shorten_length = 3`: -- `/path/to/my/project/src/file.txt` → `pat/to/my/project/src/file.txt` - -With `full_parents = 1, shorten_length = 1`: -- `/path/to/my/project/src/file.txt` → `p/t/m/project/src/file.txt` - -With `full_parents = 0, shorten_length = 3`: -- `/path/to/my/project/src/file.txt` → `pat/to/my/pro/src/file.txt` - -The last N parent directories are shown in full, earlier directories are shortened to the specified number of characters. The filename itself is always shown in full. - -**To customize:** Edit `utils.tabline_full_parents` and `utils.tabline_shorten_length` values in `lua/settings.lua` - -## Working Directory Behavior - -The working directory (`:pwd`) is locked to the directory where you opened Neovim and does NOT change when switching files: - -- `autochdir` is disabled (working directory stays fixed at project root) -- `netrw_keepdir = 1` prevents netrw from changing directory when browsing -- Project root is captured at startup in `vim.g.project_root` (used by Telescope and netrw) -- Telescope searches from the initial project root regardless of current buffer -- Use `:cd ` to manually change directory if needed (affects Telescope search scope) diff --git a/after/queries/bash/folds.scm b/after/queries/bash/folds.scm deleted file mode 100644 index 30a154e..0000000 --- a/after/queries/bash/folds.scm +++ /dev/null @@ -1,4 +0,0 @@ -;; extends - -;; Fold comment blocks -(comment) @fold diff --git a/after/queries/css/folds.scm b/after/queries/css/folds.scm deleted file mode 100644 index 30a154e..0000000 --- a/after/queries/css/folds.scm +++ /dev/null @@ -1,4 +0,0 @@ -;; extends - -;; Fold comment blocks -(comment) @fold diff --git a/after/queries/html/folds.scm b/after/queries/html/folds.scm deleted file mode 100644 index 30a154e..0000000 --- a/after/queries/html/folds.scm +++ /dev/null @@ -1,4 +0,0 @@ -;; extends - -;; Fold comment blocks -(comment) @fold diff --git a/after/queries/javascript/folds.scm b/after/queries/javascript/folds.scm deleted file mode 100644 index c56348f..0000000 --- a/after/queries/javascript/folds.scm +++ /dev/null @@ -1,8 +0,0 @@ -;; extends - -;; Fold comment blocks (including consecutive single-line comments) -(comment) @fold - -;; Fold consecutive single-line comments as a block -((comment) @fold - (#match? @fold "^//")) diff --git a/after/queries/lua/folds.scm b/after/queries/lua/folds.scm deleted file mode 100644 index 30a154e..0000000 --- a/after/queries/lua/folds.scm +++ /dev/null @@ -1,4 +0,0 @@ -;; extends - -;; Fold comment blocks -(comment) @fold diff --git a/after/queries/php/folds.scm b/after/queries/php/folds.scm deleted file mode 100644 index 57f8cae..0000000 --- a/after/queries/php/folds.scm +++ /dev/null @@ -1,4 +0,0 @@ -;; extends - -;; Fold comment blocks (including /** */ docblocks) -(comment) @fold diff --git a/after/queries/python/folds.scm b/after/queries/python/folds.scm deleted file mode 100644 index 30a154e..0000000 --- a/after/queries/python/folds.scm +++ /dev/null @@ -1,4 +0,0 @@ -;; extends - -;; Fold comment blocks -(comment) @fold diff --git a/after/queries/scss/folds.scm b/after/queries/scss/folds.scm deleted file mode 100644 index 30a154e..0000000 --- a/after/queries/scss/folds.scm +++ /dev/null @@ -1,4 +0,0 @@ -;; extends - -;; Fold comment blocks -(comment) @fold diff --git a/after/queries/tsx/folds.scm b/after/queries/tsx/folds.scm deleted file mode 100644 index 30a154e..0000000 --- a/after/queries/tsx/folds.scm +++ /dev/null @@ -1,4 +0,0 @@ -;; extends - -;; Fold comment blocks -(comment) @fold diff --git a/after/queries/typescript/folds.scm b/after/queries/typescript/folds.scm deleted file mode 100644 index 30a154e..0000000 --- a/after/queries/typescript/folds.scm +++ /dev/null @@ -1,4 +0,0 @@ -;; extends - -;; Fold comment blocks -(comment) @fold diff --git a/after/queries/vim/folds.scm b/after/queries/vim/folds.scm deleted file mode 100644 index 30a154e..0000000 --- a/after/queries/vim/folds.scm +++ /dev/null @@ -1,4 +0,0 @@ -;; extends - -;; Fold comment blocks -(comment) @fold diff --git a/colors/paper-tonic-modern.lua b/colors/paper-tonic-modern.lua index d6179e5..5865390 100644 --- a/colors/paper-tonic-modern.lua +++ b/colors/paper-tonic-modern.lua @@ -1,5 +1,5 @@ -- Paper Tonic Modern --- A paper-like colorscheme for Neovim supporting both light and dark modes +-- A light, paper-like colorscheme for Neovim -- Forked from the original Paper Tonic with modern Lua implementation -- Reset highlights and syntax @@ -11,10 +11,8 @@ end -- Set colorscheme name vim.g.colors_name = 'paper-tonic-modern' --- Set default background if not already set -if vim.o.background == '' then - vim.o.background = 'light' -end +-- Set background to light +vim.o.background = 'light' -- Load the colorscheme require('paper-tonic-modern').load() diff --git a/lazy-lock.json b/lazy-lock.json index 768d060..98a2d44 100644 --- a/lazy-lock.json +++ b/lazy-lock.json @@ -4,28 +4,28 @@ "cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" }, "cmp-nvim-lsp": { "branch": "main", "commit": "cbc7b02bb99fae35cb42f514762b89b5126651ef" }, "cmp-path": { "branch": "main", "commit": "c642487086dbd9a93160e1679a1327be111cbc25" }, - "conform.nvim": { "branch": "master", "commit": "238f542a118984a88124fc915d5b981680418707" }, "copilot-cmp": { "branch": "master", "commit": "15fc12af3d0109fa76b60b5cffa1373697e261d1" }, - "copilot.lua": { "branch": "master", "commit": "5ace9ecd0db9a7a6c14064e4ce4ede5b800325f3" }, - "gitsigns.nvim": { "branch": "main", "commit": "42d6aed4e94e0f0bbced16bbdcc42f57673bd75e" }, + "copilot.lua": { "branch": "master", "commit": "efe563802a550b7f1b7743b007987e97cba22718" }, + "gitsigns.nvim": { "branch": "main", "commit": "5813e4878748805f1518cee7abb50fd7205a3a48" }, "indent-blankline.nvim": { "branch": "master", "commit": "005b56001b2cb30bfa61b7986bc50657816ba4ba" }, - "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "fe661093f4b05136437b531e7f959af2a2ae66c8" }, + "lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "0b9bb925c000ae649ff7e7149c8cd00031f4b539" }, "mason-tool-installer.nvim": { "branch": "main", "commit": "517ef5994ef9d6b738322664d5fdd948f0fdeb46" }, - "mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" }, - "nvim-autopairs": { "branch": "master", "commit": "c2a0dd0d931d0fb07665e1fedb1ea688da3b80b4" }, - "nvim-cmp": { "branch": "main", "commit": "85bbfad83f804f11688d1ab9486b459e699292d6" }, - "nvim-lint": { "branch": "master", "commit": "ca6ea12daf0a4d92dc24c5c9ae22a1f0418ade37" }, - "nvim-lspconfig": { "branch": "master", "commit": "92ee7d42320edfbb81f3cad851314ab197fa324a" }, - "nvim-surround": { "branch": "main", "commit": "1098d7b3c34adcfa7feb3289ee434529abd4afd1" }, + "mason.nvim": { "branch": "main", "commit": "57e5a8addb8c71fb063ee4acda466c7cf6ad2800" }, + "none-ls.nvim": { "branch": "main", "commit": "5abf61927023ea83031753504adb19630ba80eef" }, + "nvim-autopairs": { "branch": "master", "commit": "7a2c97cccd60abc559344042fefb1d5a85b3e33b" }, + "nvim-cmp": { "branch": "main", "commit": "d97d85e01339f01b842e6ec1502f639b080cb0fc" }, + "nvim-lint": { "branch": "master", "commit": "ebe535956106c60405b02220246e135910f6853d" }, + "nvim-lspconfig": { "branch": "master", "commit": "9c923997123ff9071198ea3b594d4c1931fab169" }, + "nvim-surround": { "branch": "main", "commit": "fcfa7e02323d57bfacc3a141f8a74498e1522064" }, "nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" }, "nvim-treesitter-textobjects": { "branch": "master", "commit": "5ca4aaa6efdcc59be46b95a3e876300cfead05ef" }, "nvim-ts-autotag": { "branch": "main", "commit": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc" }, - "nvim-ufo": { "branch": "main", "commit": "ab3eb124062422d276fae49e0dd63b3ad1062cfc" }, - "oil.nvim": { "branch": "master", "commit": "d278dc40f9de9980868a0a55fa666fba5e6aeacb" }, + "nvim-ufo": { "branch": "main", "commit": "72d54c31079d38d8dfc5456131b1d0fb5c0264b0" }, + "oil.nvim": { "branch": "master", "commit": "cbcb3f997f6f261c577b943ec94e4ef55108dd95" }, "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, "promise-async": { "branch": "main", "commit": "119e8961014c9bfaf1487bf3c2a393d254f337e2" }, "telescope-fzf-native.nvim": { "branch": "main", "commit": "6fea601bd2b694c6f2ae08a6c6fab14930c60e2c" }, "telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" }, - "undotree": { "branch": "master", "commit": "178d19e00a643f825ea11d581b1684745d0c4eda" } + "undotree": { "branch": "master", "commit": "0f1c9816975b5d7f87d5003a19c53c6fd2ff6f7f" } } diff --git a/lua/autocmds.lua b/lua/autocmds.lua index 1ce5b07..d66f1ac 100644 --- a/lua/autocmds.lua +++ b/lua/autocmds.lua @@ -82,9 +82,6 @@ vim.api.nvim_create_autocmd("FileType", { group = aug, pattern = "qf", -- Applies to both quickfix and location list callback = function() - -- Disable spell checking in quickfix/location list windows - vim.opt_local.spell = false - -- Use matchadd() for higher priority highlighting -- This will override the default qf syntax vim.fn.matchadd("qfError", "\\", 10) @@ -109,34 +106,18 @@ local session_aug = vim.api.nvim_create_augroup("SessionManagement", { clear = t vim.api.nvim_create_autocmd("VimEnter", { group = session_aug, pattern = "*", - once = true, + nested = true, -- Allow other autocmds to fire after loading session callback = function() -- Only auto-load if: -- 1. Session.vim exists in cwd -- 2. No files were specified on command line (vim.fn.argc() == 0) -- 3. Not started with nvim -S (check if we already loaded a session) if vim.fn.argc() == 0 and vim.fn.filereadable("Session.vim") == 1 and vim.v.this_session == "" then - vim.cmd("silent! source Session.vim") + vim.cmd("source Session.vim") end end, }) --- Ensure filetype is detected for current buffer after session load -vim.api.nvim_create_autocmd("SessionLoadPost", { - group = session_aug, - pattern = "*", - callback = function() - -- Trigger BufReadPost for all loaded buffers to ensure Treesitter/LSP attach - vim.schedule(function() - for _, buf in ipairs(vim.api.nvim_list_bufs()) do - if vim.api.nvim_buf_is_loaded(buf) and vim.bo[buf].buftype == "" then - vim.api.nvim_exec_autocmds("BufReadPost", { buffer = buf }) - end - end - end) - end, -}) - -- Auto-save session on exit, but ONLY if Session.vim already exists vim.api.nvim_create_autocmd("VimLeavePre", { group = session_aug, diff --git a/lua/keymaps.lua b/lua/keymaps.lua index 90bbf55..595335d 100644 --- a/lua/keymaps.lua +++ b/lua/keymaps.lua @@ -34,12 +34,6 @@ map('n', 'K', function() end end, { desc = 'Vim: Hover/Help (keywordprg fallback)', silent = true }) --- Quickfix and Location list keymaps -map('n', 'co', 'copen', { desc = 'Quickfix: Open', silent = true }) -map('n', 'cc', 'cclose', { desc = 'Quickfix: Close', silent = true }) -map('n', 'lo', 'lopen', { desc = 'Location list: Open', silent = true }) -map('n', 'lc', 'lclose', { desc = 'Location list: Close', silent = true }) - -- Diagnostic keymaps map('n', 'xx', vim.diagnostic.setloclist, { desc = 'Diagnostics: Buffer diagnostics (location list)', silent = true }) map('n', 'xX', vim.diagnostic.setqflist, { desc = 'Diagnostics: All diagnostics (quickfix)', silent = true }) @@ -49,39 +43,144 @@ end, { desc = 'Diagnostics: Buffer errors (location list)', silent = true }) map('n', '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 }) -end, { desc = 'Diagnostics: Previous diagnostic', silent = true }) -map('n', ']d', function() - vim.diagnostic.goto_next({ float = false }) -end, { desc = 'Diagnostics: Next diagnostic', silent = true }) -map('n', 'xd', function() - pcall(vim.diagnostic.open_float) -end, { desc = 'Diagnostics: Show diagnostic under cursor', silent = true }) +map('n', '[d', vim.diagnostic.goto_prev, { desc = 'Diagnostics: Previous diagnostic', silent = true }) +map('n', ']d', vim.diagnostic.goto_next, { desc = 'Diagnostics: Next diagnostic', silent = true }) +map('n', 'xd', vim.diagnostic.open_float, { desc = 'Diagnostics: Show diagnostic under cursor', silent = true }) map('n', 'xt', function() vim.diagnostic.enable(not vim.diagnostic.is_enabled()) end, { desc = 'Diagnostics: Toggle display', silent = true }) --- Git: Modified, deleted, and untracked files to quickfix -map('n', 'gg', function() - local utils = require('utils') - local qf_list = utils.git_changed_files() - if qf_list then - vim.fn.setqflist(qf_list, 'r') - vim.cmd('copen') - end -end, { desc = 'Git: Changed files to quickfix (with status)', silent = true }) - -- Debug: Show highlight group and color under cursor map('n', 'hi', function() - require('utils').show_highlight_info() -end, { desc = 'Debug: Show highlight group and color under cursor', silent = true }) - --- UI: Toggle background (light/dark) -map('n', 'bg', function() - if vim.o.background == 'dark' then - vim.o.background = 'light' - else - vim.o.background = 'dark' + local cursor_pos = vim.api.nvim_win_get_cursor(0) + local row, col = cursor_pos[1] - 1, cursor_pos[2] + + -- Get all highlight groups at cursor position + local ts_hl = vim.treesitter.get_captures_at_pos(0, row, col) + local synID = vim.fn.synID(row + 1, col + 1, 1) + local synName = vim.fn.synIDattr(synID, 'name') + local synTrans = vim.fn.synIDattr(vim.fn.synIDtrans(synID), 'name') + + -- Helper to resolve highlight links + local function resolve_hl(name) + local hl = vim.api.nvim_get_hl(0, { name = name }) + local max_depth = 10 + local depth = 0 + while hl.link and depth < max_depth do + name = hl.link + hl = vim.api.nvim_get_hl(0, { name = name }) + depth = depth + 1 + end + return hl, name end -end, { desc = 'UI: Toggle background (light/dark)', silent = true }) + + local lines = { + '=== Highlight Info Under Cursor ===', + '', + 'Position: row=' .. row .. ' col=' .. col, + '', + } + + -- TreeSitter captures + if #ts_hl > 0 then + table.insert(lines, 'TreeSitter Captures:') + for _, capture in ipairs(ts_hl) do + local cap_name = '@' .. capture.capture + local hl, resolved_name = resolve_hl(cap_name) + + table.insert(lines, string.format(' %s', cap_name)) + if resolved_name ~= cap_name then + table.insert(lines, string.format(' → resolves to: %s', resolved_name)) + end + if hl.fg then + table.insert(lines, string.format(' fg: #%06x', hl.fg)) + end + if hl.bg then + table.insert(lines, string.format(' bg: #%06x', hl.bg)) + end + + local styles = {} + if hl.bold then table.insert(styles, 'bold') end + if hl.italic then table.insert(styles, 'italic') end + if hl.underline then table.insert(styles, 'underline') end + if #styles > 0 then + table.insert(lines, ' style: ' .. table.concat(styles, ', ')) + end + end + table.insert(lines, '') + end + + -- Syntax group + if synName ~= '' then + table.insert(lines, 'Syntax Group: ' .. synName) + if synTrans ~= synName and synTrans ~= '' then + table.insert(lines, 'Translates to: ' .. synTrans) + end + + local hl, resolved_name = resolve_hl(synTrans ~= '' and synTrans or synName) + if hl.fg then + table.insert(lines, string.format(' fg: #%06x', hl.fg)) + end + if hl.bg then + table.insert(lines, string.format(' bg: #%06x', hl.bg)) + end + table.insert(lines, '') + end + + -- Final applied highlight (use TreeSitter if available, otherwise syntax) + local final_hl_name = nil + if #ts_hl > 0 then + final_hl_name = '@' .. ts_hl[1].capture + elseif synTrans ~= '' then + final_hl_name = synTrans + elseif synName ~= '' then + final_hl_name = synName + end + + if final_hl_name then + local final_hl, final_resolved = resolve_hl(final_hl_name) + table.insert(lines, 'Applied Highlight: ' .. final_resolved) + if final_hl.fg then + table.insert(lines, string.format(' fg: #%06x', final_hl.fg)) + else + table.insert(lines, ' fg: NONE') + end + if final_hl.bg then + table.insert(lines, string.format(' bg: #%06x', final_hl.bg)) + else + table.insert(lines, ' bg: NONE') + end + + local styles = {} + if final_hl.bold then table.insert(styles, 'bold') end + if final_hl.italic then table.insert(styles, 'italic') end + if final_hl.underline then table.insert(styles, 'underline') end + if final_hl.undercurl then table.insert(styles, 'undercurl') end + if #styles > 0 then + table.insert(lines, ' style: ' .. table.concat(styles, ', ')) + end + end + + -- Show in a floating window + local buf = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) + + local width = 0 + for _, line in ipairs(lines) do + width = math.max(width, #line) + end + width = math.min(width + 2, vim.o.columns - 4) + + local height = #lines + local opts = { + relative = 'cursor', + width = width, + height = height, + row = 1, + col = 0, + style = 'minimal', + border = 'rounded', + } + + vim.api.nvim_open_win(buf, false, opts) +end, { desc = 'Debug: Show highlight group and color under cursor', silent = true }) diff --git a/lua/netrw-config.lua b/lua/netrw-config.lua index 94b9fcd..8f8870d 100644 --- a/lua/netrw-config.lua +++ b/lua/netrw-config.lua @@ -1,46 +1,4 @@ local map = vim.keymap.set -local last_file_buf -local previous_file_buf - -local function is_real_file_buffer(buf) - return vim.api.nvim_buf_is_valid(buf) - and vim.bo[buf].buflisted - and vim.bo[buf].buftype == '' - and vim.bo[buf].filetype ~= 'netrw' - and vim.api.nvim_buf_get_name(buf) ~= '' -end - -local function is_netrw_buffer(buf) - if not vim.api.nvim_buf_is_valid(buf) then - return false - end - - return vim.bo[buf].filetype == 'netrw' or vim.api.nvim_buf_get_name(buf):match('NetrwTreeListing$') ~= nil -end - -local function switch_to_buffer(buf) - vim.cmd('buffer ' .. buf) -end - -local function switch_to_native_alternate() - pcall(vim.cmd, 'buffer #') -end - -local function jump_to_alternate_file() - local alternate = vim.fn.bufnr('#') - - if is_real_file_buffer(alternate) then - switch_to_buffer(alternate) - return - end - - if is_netrw_buffer(alternate) and is_real_file_buffer(previous_file_buf) then - switch_to_buffer(previous_file_buf) - return - end - - switch_to_native_alternate() -end -- Netrw configuration for file browsing -- Native Neovim file explorer (no plugins required) @@ -62,9 +20,9 @@ vim.g.netrw_alto = 0 -- 50% split when pressing 'p' vim.g.netrw_winsize = 50 --- Keep working directory unchanged when browsing (1 = don't change directory) --- Setting to 1 prevents netrw from changing vim's working directory -vim.g.netrw_keepdir = 1 +-- Keep the current directory and browsing directory synced +-- This makes netrw respect your current working directory +vim.g.netrw_keepdir = 0 -- Open files in the same window (replace netrw buffer) -- Options: 0=same window, 1=horizontal split, 2=vertical split, 3=new tab, 4=previous window @@ -82,44 +40,21 @@ vim.g.netrw_sizestyle = 'H' -- Netrw file explorer keymaps -- Open netrw in new tab at current file's directory -map('n', 'nt', function() +map('n', 'te', function() local current_file_dir = vim.fn.expand('%:p:h') vim.cmd('tabnew') vim.cmd('Explore ' .. vim.fn.fnameescape(current_file_dir)) -end, { desc = 'Netrw: Tab at current file dir', silent = true }) +end, { desc = 'Netrw: Tab explore (current file dir)', silent = true }) --- Open netrw in new tab at project root (stored at startup) -map('n', 'nT', function() +-- Open netrw in new tab at project root (cwd) +map('n', 'tE', function() vim.cmd('tabnew') - vim.cmd('Explore ' .. vim.fn.fnameescape(vim.g.project_root)) -end, { desc = 'Netrw: Tab at project root', silent = true }) - --- Open netrw in current window at project root (stored at startup) -map('n', 'nr', function() - vim.cmd('Explore ' .. vim.fn.fnameescape(vim.g.project_root)) -end, { desc = 'Netrw: Open at project root', silent = true }) - -map('n', '', jump_to_alternate_file, { desc = 'Buffer: Alternate file skipping netrw', silent = true }) -map('n', '', jump_to_alternate_file, { desc = 'Buffer: Alternate file skipping netrw', silent = true }) - -vim.api.nvim_create_autocmd('BufEnter', { - desc = 'Track recent real file buffers for alternate-buffer jumps', - callback = function(args) - local buf = args.buf - - if is_real_file_buffer(buf) and buf ~= last_file_buf then - previous_file_buf = last_file_buf - last_file_buf = buf - end - end, -}) - + vim.cmd('Explore ' .. vim.fn.fnameescape(vim.fn.getcwd())) +end, { desc = 'Netrw: Tab explore (project root)', silent = true }) -- Enable line numbers in netrw buffers vim.api.nvim_create_autocmd('FileType', { pattern = 'netrw', - desc = 'Configure netrw buffer-local options', callback = function() - vim.bo.buflisted = false vim.opt_local.number = true vim.opt_local.relativenumber = true end, diff --git a/lua/paper-tonic-modern/colors.lua b/lua/paper-tonic-modern/colors.lua index 7096388..a0a9cf7 100644 --- a/lua/paper-tonic-modern/colors.lua +++ b/lua/paper-tonic-modern/colors.lua @@ -1,6 +1,6 @@ -- Paper Tonic Modern - Color Palette -- Extracted from original Paper Tonic colorscheme --- Supports both light (paper-like) and dark modes +-- Light, paper-like theme with subtle colors local M = {} @@ -9,177 +9,107 @@ local M = {} -- 256: Integer 0-255 for 256-color terminals -- ansi: ANSI color name for basic 16-color terminals --- Detect current background mode -local is_dark = vim.o.background == 'dark' - -- ============================================================================ -- Background Colors -- ============================================================================ -if is_dark then - -- Dark mode: soft dark backgrounds - M.bg = {'#27292c', 234, 'black'} - M.bg_darkest = {'#ffffff', 255, 'white'} -- Inverted: lightest for strong contrast - M.bg_ui = {'#353535', 236, 'darkgray'} -else - -- Light mode: pure white paper - M.bg = {'#ffffff', 255, 'white'} - M.bg_darkest = {'#505050', 244, 'gray'} - M.bg_ui = {'#efefef', 0, 'darkgray'} -end +-- Main background: pure white paper +M.bg = {'#ffffff', 255, 'white'} + +-- Darkest background: used for very strong contrast elements +M.bg_darkest = {'#505050', 244, 'gray'} + +-- UI background: slightly off-white for UI elements (statusline, etc.) +M.bg_ui = {'#efefef', 0, 'darkgray'} -- ============================================================================ -- Highlight Backgrounds (general) -- ============================================================================ -if is_dark then - -- Dark mode: lighter backgrounds for highlights - M.bg_hl_strong = {"#3a3a3a", 237, "darkgray"} - M.bg_hl = {"#2a2a2a", 236, "darkgray"} - M.bg_hl_weak = {"#252525", 235, "darkgray"} - - -- Special highlight backgrounds (cyan/blue tones) - M.bg_hl_special_strong = {"#1a4a5a", 24, "darkblue"} - M.bg_hl_special = {"#0a3a4a", 23, "darkblue"} - M.bg_hl_special_weak = {"#1a3545", 23, "darkblue"} - - -- Alternative special highlight (green tones) - M.bg_hl_special_alt_strong = {"#1a5a2a", 28, "darkgreen"} - M.bg_hl_special_alt = {"#0a4a1a", 22, "darkgreen"} -else - -- Light mode: neutral gray tones - M.bg_hl_strong = {"#dddddd", 17, "white"} - M.bg_hl = {"#eeeeee", 250, "white"} - M.bg_hl_weak = {"#f7f2f2", 250, "white"} - - -- Special highlight backgrounds (cyan/blue tones) - M.bg_hl_special_strong = {"#a3e0ff", 17, "cyan"} - M.bg_hl_special = {"#d4f0ff", 250, "cyan"} - M.bg_hl_special_weak = {"#e0eaff", 250, "cyan"} - - -- Alternative special highlight (green tones) - M.bg_hl_special_alt_strong = {"#74f283", 17, "cyan"} - M.bg_hl_special_alt = {"#bff2cd", 250, "cyan"} -end +-- Selection/highlight backgrounds (neutral gray tones) +M.bg_hl_strong = {"#dddddd", 17, "white"} +M.bg_hl = {"#eeeeee", 250, "white"} +M.bg_hl_weak = {"#f7f2f2", 250, "white"} + +-- Special highlight backgrounds (cyan/blue tones - for LSP references, search, etc.) +M.bg_hl_special_strong = {"#a3e0ff", 17, "cyan"} +M.bg_hl_special = {"#d4f0ff", 250, "cyan"} +M.bg_hl_special_weak = {"#e0eaff", 250, "cyan"} + +-- Alternative special highlight (green tones - for diff additions, etc.) +M.bg_hl_special_alt_strong = {"#74f283", 17, "cyan"} +M.bg_hl_special_alt = {"#bff2cd", 250, "cyan"} -- ============================================================================ -- Status Backgrounds (error, success, modified, fail) -- ============================================================================ -if is_dark then - -- Dark mode: darker tinted backgrounds - M.bg_error = {'#4a2020', 52, 'darkred'} - M.bg_error_weak = {'#3a1a1a', 52, 'darkred'} - M.bg_success = {'#1a3a1a', 22, 'darkgreen'} - M.bg_modified = {'#1a1a3a', 17, 'darkblue'} - M.bg_fail = {'#3a1a1a', 52, 'darkred'} -else - -- Light mode: light tinted backgrounds - M.bg_error = {'#ffd7d7', 196, 'white'} - M.bg_error_weak = {'#ffefef', 196, 'white'} - M.bg_success = {'#e0ece0', 196, 'white'} - M.bg_modified = {'#e0e0ec', 196, 'white'} - M.bg_fail = {'#ece0e0', 196, 'white'} -end +-- Error backgrounds (red/pink tones) +M.bg_error = {'#ffd7d7', 196, 'white'} +M.bg_error_weak = {'#ffefef', 196, 'white'} + +-- Success background (green tone) +M.bg_success = {'#e0ece0', 196, 'white'} + +-- Modified background (blue tone) +M.bg_modified = {'#e0e0ec', 196, 'white'} + +-- Fail/warning background (red tone) +M.bg_fail = {'#ece0e0', 196, 'white'} -- ============================================================================ -- Foreground Colors (text) -- ============================================================================ -if is_dark then - -- Dark mode: light text (inverted from light mode) - M.fg_stronger = {'#e0e0e0', 253, 'white'} -- Lightest text - M.fg_strong = {'#c0c0c0', 250, 'white'} -- Light text - M.fg = {'#a0a0a0', 248, 'gray'} -- Normal text (default) - M.fg_weak = {'#808080', 244, 'gray'} -- Dimmer text (comments, less important) - M.fg_weaker = {'#606060', 241, 'darkgray'} -- Dimmest text (very subtle) - M.fg_exception = {'#d08080', 174, 'red'} -- Light reddish for errors/exceptions -else - -- Light mode: dark text on paper - M.fg_stronger = {'#444444', 236, 'darkgrey'} -- Darkest text - M.fg_strong = {'#666666', 236, 'darkgrey'} -- Dark text - M.fg = {'#8c8c8c', 244, 'gray'} -- Normal text (default) - M.fg_weak = {'#9d9d9d', 251, 'gray'} -- Light text (comments, less important) - M.fg_weaker = {'#bbbbbb', 251, 'gray'} -- Lightest text (very subtle) - M.fg_exception = {'#7c4444', 251, 'gray'} -- Reddish-brown for errors/exceptions -end +-- Main text colors (gray scale, strongest to weakest) +M.fg_stronger = {'#444444', 236, 'darkgrey'} -- Darkest text +M.fg_strong = {'#666666', 236, 'darkgrey'} -- Dark text +M.fg = {'#8c8c8c', 244, 'gray'} -- Normal text (default) +M.fg_weak = {'#9d9d9d', 251, 'gray'} -- Light text (comments, less important) +M.fg_weaker = {'#bbbbbb', 251, 'gray'} -- Lightest text (very subtle) + +-- Exception foreground (reddish-brown for errors/exceptions) +M.fg_exception = {'#7c4444', 251, 'gray'} -- ============================================================================ -- Status Foreground Colors (Git/Diff - muted natural tones) -- ============================================================================ -if is_dark then - -- Dark mode: lighter muted tones - M.success = {'#a0d0a0', 114, 'green'} -- Success/addition (muted green) - M.modified = {'#a0a0d0', 110, 'blue'} -- Modified/change (muted blue) - M.fail = {'#d0a0a0', 174, 'red'} -- Fail/deletion (muted red) -else - -- Light mode: natural muted colors - M.success = {'#89af89', 196, 'white'} -- Success/addition (muted green) - M.modified = {'#8989af', 196, 'white'} -- Modified/change (muted blue) - M.fail = {'#af8989', 196, 'white'} -- Fail/deletion (muted red) -end +-- Git/diff status indicators (used in statusline, signs, etc.) +-- These are muted, natural colors for git changes +M.success = {'#89af89', 196, 'white'} -- Success/addition (muted green) +M.modified = {'#8989af', 196, 'white'} -- Modified/change (muted blue) +M.fail = {'#af8989', 196, 'white'} -- Fail/deletion (muted red) -- ============================================================================ -- Quickfix/Location List Diagnostic Colors (Muted tones like git/diff) -- ============================================================================ -if is_dark then - -- Dark mode: lighter muted tones - M.qf_error = {'#d07070', 167, 'red'} -- Error (lighter muted red) - M.qf_warn = {'#d0a080', 173, 'yellow'} -- Warning (muted orange) - M.qf_info = {'#80b0d0', 110, 'blue'} -- Info (muted blue) - M.qf_hint = {'#80d0d0', 116, 'cyan'} -- Hint (lighter muted cyan) -else - -- Light mode: darker muted tones - M.qf_error = {'#af3f3f', 196, 'white'} -- Error (darker muted red for more contrast) - M.qf_warn = {'#af7f5f', 196, 'white'} -- Warning (muted orange) - M.qf_info = {'#5f8faf', 196, 'white'} -- Info (muted blue) - M.qf_hint = {'#5fafaf', 196, 'white'} -- Hint (lighter muted blue) -end +-- These are for quickfix/location list only - similar muted tone to git/diff +M.qf_error = {'#af3f3f', 196, 'white'} -- Error (darker muted red for more contrast) +M.qf_warn = {'#af7f5f', 196, 'white'} -- Warning (muted orange) +M.qf_info = {'#5f8faf', 196, 'white'} -- Info (muted blue) +M.qf_hint = {'#5fafaf', 196, 'white'} -- Hint (lighter muted blue) -- ============================================================================ --- Diagnostic/Alert Colors (Fluorescent/Neon - intentionally jarring) +-- Alert/Diagnostic Colors (Fluorescent/Neon - intentionally jarring) -- ============================================================================ -- These colors are designed to be NOTICED, not blend in with code --- Fluorescent/neon aesthetic --- In light mode: bright, synthetic, stands out on white paper ("highlighter marker") --- In dark mode: slightly toned down but still prominent +-- Fluorescent/neon aesthetic similar to bg_hl_special_alt colors +-- Think "highlighter marker" - bright, synthetic, stands out on white paper -if is_dark then - -- Dark mode: still bright but not as harsh - M.diag_error = {'#ff4488', 204, 'red'} -- Bright pink-red - M.diag_warn = {'#ff8833', 208, 'yellow'} -- Bright orange - M.diag_info = {'#44ccff', 81, 'cyan'} -- Bright cyan - M.diag_hint = {'#88ddff', 117, 'cyan'} -- Softer cyan - M.diag_hint_dark = {'#44aacc', 74, 'cyan'} -- Medium cyan - M.diag_weak = {'#ffaa66', 215, 'yellow'} -- Lighter orange - - -- Diagnostic backgrounds - M.bg_diag_error = {'#3a1a25', 52, 'darkred'} - M.bg_diag_warn = {'#3a2a1a', 58, 'brown'} - M.bg_diag_info = {'#1a2a3a', 17, 'darkblue'} - M.bg_diag_hint = {'#1a2f3a', 23, 'darkblue'} - - M.question = {'#44ccff', 81, 'cyan'} -else - -- Light mode: fluorescent colors for maximum visibility - M.diag_error = {'#ff0066', 197, 'red'} -- Hot pink-red (screams "error!") - M.diag_warn = {'#ff6600', 202, 'red'} -- Fluorescent orange (warnings) - M.diag_info = {'#00ccff', 45, 'cyan'} -- Bright fluorescent cyan (info) - M.diag_hint = {'#66e0ff', 81, 'cyan'} -- Softer fluorescent cyan (hint) - M.diag_hint_dark = {'#0099cc', 38, 'cyan'} -- Darker cyan for UI elements - M.diag_weak = {'#ff9933', 208, 'yellow'} -- Lighter orange (spelling, etc.) - - -- Diagnostic backgrounds - M.bg_diag_error = {'#ffe6f0', 224, 'white'} - M.bg_diag_warn = {'#fff0e6', 223, 'white'} - M.bg_diag_info = {'#e6f9ff', 195, 'white'} - M.bg_diag_hint = {'#f0fcff', 195, 'white'} - - M.question = {'#00ccff', 45, 'cyan'} -end +-- LSP Diagnostics - Fluorescent colors for maximum visibility +M.diag_error = {'#ff0066', 197, 'red'} -- Hot pink-red (screams "error!") +M.diag_warn = {'#ff6600', 202, 'red'} -- Fluorescent orange (warnings) +M.diag_info = {'#00ccff', 45, 'cyan'} -- Bright fluorescent cyan (info - more prominent) +M.diag_hint = {'#66e0ff', 81, 'cyan'} -- Softer fluorescent cyan (hint - less prominent) + +-- LSP Diagnostic backgrounds - Light tinted versions for highlighting code +M.bg_diag_error = {'#ffe6f0', 224, 'white'} -- Very light pink (for error backgrounds) +M.bg_diag_warn = {'#fff0e6', 223, 'white'} -- Very light orange (for warning backgrounds) +M.bg_diag_info = {'#e6f9ff', 195, 'white'} -- Very light cyan (for info backgrounds) +M.bg_diag_hint = {'#f0fcff', 195, 'white'} -- Very light cyan (for hint backgrounds) -- ============================================================================ -- Primary Accent Colors (brownish-red tones) @@ -187,19 +117,15 @@ end -- Primary accent: For "base" languages -- Used for: PHP, JavaScript, Python, etc. -if is_dark then - -- Dark mode: lighter brownish-red tones - M.primary_stronger = {"#d0a0a0", 181, "white"} - M.primary_strong = {"#c09090", 181, "white"} - M.primary = {"#b08080", 138, "gray"} - M.primary_weak = {"#a07070", 131, "darkgray"} -else - -- Light mode: darker brownish-red tones - M.primary_stronger = {"#7f4b4b", 236, "black"} - M.primary_strong = {"#5a4444", 236, "black"} - M.primary = {"#6b5555", 244, "gray"} - M.primary_weak = {"#7c6666", 248, "darkgray"} -end +-- Languages using primary: +-- - PHP: always primary (whether standalone or in tags within HTML) +-- - JavaScript: always primary (standalone or embedded) +-- - Python: always primary +-- Note: Both PHP and JS use primary; acceptable since embedded JS in PHP is discouraged +M.primary_stronger = {"#7f4b4b", 236, "black"} -- Darkest accent +M.primary_strong = {"#5a4444", 236, "black"} -- Dark accent +M.primary = {"#6b5555", 244, "gray"} -- Normal accent +M.primary_weak = {"#7c6666", 248, "darkgray"} -- Light accent -- ============================================================================ -- Language-Specific Color Palettes (for mixed-language contexts) @@ -214,49 +140,31 @@ end -- - HTML tags: c3 (blue) - everywhere, whether in .html or embedded in PHP -- - CSS rules: c2 (green) - everywhere, whether in .css or