diff --git a/docs/adrs/002.tabs-vim.themes.md b/docs/adrs/002.tabs-vim.themes.md index 952c425..3b92fc7 100644 --- a/docs/adrs/002.tabs-vim.themes.md +++ b/docs/adrs/002.tabs-vim.themes.md @@ -8,7 +8,12 @@ ## Decision -Expose mode colors via a single `g:tabs_vim_colors` dict. Each key is a lowercase mode name (`normal`, `insert`, `visual`, `replace`, `command`, `terminal`); each value is a four-element list `[guifg, guibg, ctermfg, ctermbg]`. Users may override any subset; omitted modes fall back to the built-in Dracula defaults. The dict is read once at plugin load after `colorscheme` is applied. +Expose all tab bar colors via a single `g:tabs_vim_colors` dict. Each key is a lowercase name; each value is a four-element list `[guifg, guibg, ctermfg, ctermbg]`. Users may override any subset; omitted keys fall back to the built-in Dracula defaults. The dict is read once at plugin load after `colorscheme` is applied. + +**Mode color keys:** `normal`, `insert`, `visual`, `replace`, `command`, `terminal` +**Tab bar chrome keys:** `tabline` (`TabLine`), `tabline_sel` (`TabLineSel`), `tabline_fill` (`TabLineFill`) + +The plugin applies all highlight groups — both its own `TabsVim_*` groups and the standard Vim `TabLine*` groups — so users need no separate `hi` declarations in their vimrc. ## Context @@ -42,7 +47,7 @@ tabs.vim sits between lightline (full palette control, many modes) and buftablin ## Consequences -- `g:tabs_vim_colors` is the single configuration point for all mode colors -- The plugin applies `hi` statements from the merged dict (user overrides + defaults) at load time -- If a user sets `TabsVim_*` highlight groups themselves *after* the plugin loads, those are respected as-is (plugin does not re-apply on colorscheme change in this phase) +- `g:tabs_vim_colors` is the single configuration point for all tab bar colors (mode pills and chrome) +- The plugin applies all `hi` statements from the merged dict (user overrides + defaults) at load time — no separate `hi TabLine*` declarations needed in the user's vimrc +- If a user sets `TabsVim_*` or `TabLine*` highlight groups themselves *after* the plugin loads, those are respected as-is (plugin does not re-apply on colorscheme change in this phase) - Phase 4 (Polish) may add `ColorScheme` autocmd re-application, but that is out of scope here diff --git a/docs/specs/tabs.vim.md b/docs/specs/tabs.vim.md index f0e09c0..477f1a2 100644 --- a/docs/specs/tabs.vim.md +++ b/docs/specs/tabs.vim.md @@ -1,7 +1,7 @@ # tabs.vim **Version:** 0.1.0 -**Last Updated:** 2026-04-03 +**Last Updated:** 2026-04-04 **Status:** Active Development --- @@ -131,22 +131,31 @@ All keybindings are configurable. Users can disable features (e.g., if they don' **4. Integrated Theming** Dracula color scheme is the built-in default; tab bar includes mode indicator (Normal/Insert/Visual/Replace/Command/Terminal) with context-aware highlighting. Users may override any or all mode colors via `g:tabs_vim_colors`. +**5. Vimrc Integration Boundary** +The plugin owns all behavior it directly triggers. Integration with third-party plugins (vim-flog, vim-fugitive, diff buffers) — for example, binding `q` to `:tabclose` in their buffer types — is intentionally left to the user's vimrc. These bindings are tab-aware but depend on optional external plugins; pulling them into tabs.vim would introduce undeclared dependencies and couple the plugin to unrelated workflows. + ### Color Configuration Contract -Mode colors are configurable via the `g:tabs_vim_colors` global dict. Each key is a lowercase mode name; each value is a four-element list `[guifg, guibg, ctermfg, ctermbg]`. Unspecified modes fall back to the built-in Dracula defaults. The dict is read once at plugin load time (after `colorscheme` is applied). +All tab bar colors are configurable via the `g:tabs_vim_colors` global dict. Each key is a lowercase name; each value is a four-element list `[guifg, guibg, ctermfg, ctermbg]`. Unspecified keys fall back to the built-in Dracula defaults. The dict is read once at plugin load time (after `colorscheme` is applied). + +The plugin owns the full tab bar and applies all highlight groups itself — no separate `hi TabLine*` declarations are needed in the user's vimrc. -**Supported keys:** `normal`, `insert`, `visual`, `replace`, `command`, `terminal` +**Mode color keys:** `normal`, `insert`, `visual`, `replace`, `command`, `terminal` +**Tab bar chrome keys:** `tabline`, `tabline_sel`, `tabline_fill` **Default (Dracula palette):** ```vim let g:tabs_vim_colors = { - \ 'normal': ['#282a36', '#bd93f9', 235, 141], - \ 'insert': ['#282a36', '#50fa7b', 235, 84 ], - \ 'visual': ['#282a36', '#ffb86c', 235, 215], - \ 'replace': ['#282a36', '#ff5555', 235, 203], - \ 'command': ['#282a36', '#bd93f9', 235, 141], - \ 'terminal': ['#282a36', '#8be9fd', 235, 117], + \ 'normal': ['#282a36', '#bd93f9', 235, 141], + \ 'insert': ['#282a36', '#50fa7b', 235, 84 ], + \ 'visual': ['#282a36', '#ffb86c', 235, 215], + \ 'replace': ['#282a36', '#ff5555', 235, 203], + \ 'command': ['#282a36', '#bd93f9', 235, 141], + \ 'terminal': ['#282a36', '#8be9fd', 235, 117], + \ 'tabline': ['#6272a4', 'NONE', 61, 'NONE'], + \ 'tabline_sel': ['#bd93f9', 'NONE', 141, 'NONE'], + \ 'tabline_fill': ['#6272a4', 'NONE', 61, 'NONE'], \ } ``` @@ -200,17 +209,17 @@ let g:tabs_vim_colors = { ## Features -| Feature | Description | Status | ADR | -|---------|-------------|--------|-----| -| **Tab Navigation** | Switch to next/prev tab with `` / `` | ⬜ | — | -| **Direct Tab Jump** | Jump to tab 1-9 with `[1-9]` | ⬜ | — | -| **Tab Creation** | Create new tab with `wt`, via file picker with `ft` | ⬜ | — | -| **Tab Closing** | Close current tab or all but current with `x` / `X` | ⬜ | — | -| **Tab Appearance** | Dracula default theme; user-configurable colors via `g:tabs_vim_colors` | ⬜ | ADR-002 | -| **File Tree Integration** | Open files in tabs from Fern file browser (`t` key) | ⬜ | — | -| **Git Integration** | Open git-related output (diffs, logs) in tabs | ⬜ | — | -| **Terminal in Tabs** | Spawn terminal windows in new tabs (separate from splits) | ⬜ | — | -| **Which-Key Support** | Tab commands exposed in `` menu hierarchy | ⬜ | — | +| Feature | Description | ADR | Done? | +|---------|-------------|-----|-------| +| **Tab Navigation** | Switch to next/prev tab with `` / `` | — | ✅ | +| **Direct Tab Jump** | Jump to tab 1-9 with `[1-9]` | — | ✅ | +| **Tab Creation** | Create new tab with `wt`, via file picker with `ft` | — | ✅ | +| **Tab Closing** | Close current tab or all but current with `x` / `X` | — | ✅ | +| **Tab Appearance** | Dracula default theme; user-configurable colors via `g:tabs_vim_colors` | ADR-002 | ✅ | +| **Terminal in Tabs** | Toggle split terminals and spawn tab terminals (`h/ts/tv/tt`) | — | ✅ | +| **File Tree Integration** | Open files in tabs from Fern file browser (`t` key) | — | ⬜ | +| **Git Integration** | Open git-related output (diffs, logs) in tabs | — | ⬜ | +| **Which-Key Support** | Tab commands exposed in `` menu hierarchy | — | ⬜ | --- @@ -233,3 +242,5 @@ None yet. | Date | Change | |------|--------| | 2026-04-03 | Initial SPEC: navigation, creation, theming | +| 2026-04-04 | Extend color config: plugin now owns TabLine/TabLineSel/TabLineFill via `tabline`, `tabline_sel`, `tabline_fill` keys | +| 2026-04-04 | Add Vimrc Integration Boundary pattern; mark completed features; align Features table to template | diff --git a/plugin/tabs.vim b/plugin/tabs.vim index e8a0873..1dcf118 100644 --- a/plugin/tabs.vim +++ b/plugin/tabs.vim @@ -178,12 +178,15 @@ endif " MODE COLORS — override any mode via g:tabs_vim_colors (see docs/specs/tabs.vim.md) " Each entry: [guifg, guibg, ctermfg, ctermbg] let s:tabs_vim_defaults = { - \ 'normal': ['#282a36', '#bd93f9', 235, 141], - \ 'insert': ['#282a36', '#50fa7b', 235, 84 ], - \ 'visual': ['#282a36', '#ffb86c', 235, 215], - \ 'replace': ['#282a36', '#ff5555', 235, 203], - \ 'command': ['#282a36', '#bd93f9', 235, 141], - \ 'terminal': ['#282a36', '#8be9fd', 235, 117], + \ 'normal': ['#282a36', '#bd93f9', 235, 141], + \ 'insert': ['#282a36', '#50fa7b', 235, 84 ], + \ 'visual': ['#282a36', '#ffb86c', 235, 215], + \ 'replace': ['#282a36', '#ff5555', 235, 203], + \ 'command': ['#282a36', '#bd93f9', 235, 141], + \ 'terminal': ['#282a36', '#8be9fd', 235, 117], + \ 'tabline': ['#6272a4', 'NONE', 61, 'NONE'], + \ 'tabline_sel': ['#bd93f9', 'NONE', 141, 'NONE'], + \ 'tabline_fill': ['#6272a4', 'NONE', 61, 'NONE'], \ } function! s:ApplyColors() abort @@ -201,6 +204,15 @@ function! s:ApplyColors() abort let l:n = (type(l:ov) == type([]) && len(l:ov) == 4) ? l:ov : s:tabs_vim_defaults['normal'] execute printf('hi TabsVim_Accent guifg=%s guibg=%s ctermfg=%s ctermbg=%s gui=bold cterm=bold', \ l:n[0], l:n[1], l:n[2], l:n[3]) + for [l:key, l:Group, l:bold] in [ + \ ['tabline', 'TabLine', 'NONE'], + \ ['tabline_sel', 'TabLineSel', 'bold'], + \ ['tabline_fill', 'TabLineFill', 'NONE']] + let l:ov = get(l:user, l:key, []) + let l:col = (type(l:ov) == type([]) && len(l:ov) == 4) ? l:ov : s:tabs_vim_defaults[l:key] + execute printf('hi %s guifg=%s guibg=%s ctermfg=%s ctermbg=%s gui=%s cterm=%s', + \ l:Group, l:col[0], l:col[1], l:col[2], l:col[3], l:bold, l:bold) + endfor endfunction call s:ApplyColors() diff --git a/skills-lock.json b/skills-lock.json index 02d5603..0f69f4d 100644 --- a/skills-lock.json +++ b/skills-lock.json @@ -9,7 +9,7 @@ "create-live-spec": { "source": "./docs/skills/create-live-spec", "sourceType": "local", - "computedHash": "9c83b94d12109ef8823e227b0e9e5d58a48eab636cee7da11a1b446098dcb474" + "computedHash": "36acce4b9f9e55a4427f547d151cf11705ccf011fb5ecb164b9b2327c73a8f54" } } }