Modern Neovim colorscheme partially based on Jason W Ryan's miromiro: https://www.vim.org/scripts/script.php?script_id=3815
Highlights are organized by modules (core, LSP/Tree‑sitter, plugins) with a clean setup API, plugin toggles, and a simple validator used in CI.
- Modular highlight groups: core UI, syntax, diagnostics, LSP, Tree‑sitter
- Plugin integrations (toggleable): telescope, cmp, gitsigns, indent‑blankline/ibl, mini.indentscope, which‑key, neo‑tree, nvim‑tree, dap, dap‑ui, trouble, notify, treesitter‑context, hop, rainbow‑delimiters, obsidian, diffview, fidget, toggleterm, dashboard‑nvim, heirline, oil.nvim, blink.cmp, leap.nvim, flash.nvim, nvim‑ufo, nvim‑bqf, glance.nvim, barbecue.nvim, vim‑illuminate, hlslens.nvim, virt‑column.nvim, nvim‑dap‑virtual‑text, mini.pick, snacks.nvim, fzf‑lua
- Setup options: transparent backgrounds, terminal ANSI colors, extended style categories (keywords/functions/types/operators/numbers/booleans/constants/punctuation)
- Diagnostics with optional virtual text background (blend)
- Overrides via table or function (receives palette)
- Validator script and GitHub Actions workflow
See the full history in CHANGELOG.md and the thematic overview in RELEASE_NOTES.md (Russian: RELEASE_NOTES.ru.md).
lazy.nvim
{
'neg-serg/neg.nvim',
lazy = false,
priority = 1000,
config = function()
require('neg').setup({
-- Pick a preset (optional): 'soft' | 'hard' | 'pro' | 'writing' | 'accessibility' | 'focus' | 'presentation'
preset = nil,
-- Operators coloring (default: families): 'families' | 'mono'
operator_colors = 'families',
-- Transparency: boolean for global, or table for zones
-- transparent = true,
transparent = { float = false, sidebar = false, statusline = false },
terminal_colors = true,
diagnostics_virtual_bg = false,
diagnostics_virtual_bg_blend = 15,
styles = {
comments = 'italic',
keywords = 'none',
functions = 'none',
strings = 'none',
variables = 'none',
types = 'none',
operators = 'none',
numbers = 'none',
booleans = 'none',
constants = 'none',
punctuation = 'none',
},
plugins = {
cmp = true,
telescope = true,
git = true,
gitsigns = true,
noice = true,
obsidian = true,
rainbow = true,
headline = true,
indent = true,
which_key = true,
nvim_tree = false,
neo_tree = true,
dap = true,
dapui = true,
trouble = true,
notify = true,
treesitter_context = true,
hop = true,
},
overrides = function(colors)
return {
NormalFloat = { bg = 'NONE' },
CursorLine = { underline = true },
}
end,
})
vim.cmd.colorscheme('neg')
end,
}vim‑plug
Plug 'neg-serg/neg.nvim'
lua << EOF
require('neg').setup({})
EOF
colorscheme negAll options are optional. Defaults are shown below.
require('neg').setup({
saturation = 100, -- global saturation scale 0..100 (100 = original, 0 = grayscale)
alpha_overlay = 0, -- global soft backgrounds alpha 0..30 (Search/CurSearch/Visual & DiagnosticVirtualText)
transparent = false, -- boolean or { float, sidebar, statusline }
-- transparent = { float = false, sidebar = false, statusline = false },
terminal_colors = true, -- set 16 ANSI terminal colors
preset = nil, -- 'soft' | 'hard' | 'pro' | 'writing' | 'accessibility' | 'focus' | 'presentation' | nil
operator_colors = 'families', -- 'families' for subtle per-family hues, 'mono' for single operator color, or 'mono+' for a slightly stronger single accent
number_colors = 'ramp', -- numbers coloring: 'mono' or ramp presets 'ramp' (balanced, default) | 'ramp-soft' | 'ramp-strong'
ui = {
core_enhancements = true, -- define extra baseline UI groups (Whitespace, EndOfBuffer, PmenuMatch*, FloatShadow*, Cursor*, ...)
dim_inactive = false, -- dim NormalNC/WinBarNC and LineNr in inactive windows (window-local winhighlight mapping)
mode_accent = true, -- change CursorLine/StatusLine accents by mode (Normal/Insert/Visual)
focus_caret = true, -- boost CursorLine visibility if overall contrast is low
soft_borders = false, -- lighten WinSeparator/FloatBorder to reduce visual noise
float_panel_bg = false, -- use slightly lighter panel-like background for NormalFloat (off by default)
auto_transparent_panels = true, -- when terminal background is transparent and float transparency is off, give floats/panels a subtle backdrop
diff_focus = true, -- stronger Diff* backgrounds when any window is in :diff mode
light_signs = false, -- soften sign icons (DiagnosticSign*, GitSigns*) without changing hue
diag_pattern = 'none', -- diagnostics pattern preset: 'none' | 'minimal' | 'strong'
lexeme_cues = 'off', -- functions underline; types underline+bold (off|minimal|strong)
thick_cursor = false, -- thicker CursorLine/CursorLineNr for TUI
outlines = false, -- active/inactive window outlines via winhighlight
reading_mode = false, -- near-monochrome syntax with clearer structure
search_visibility = 'default', -- 'default' | 'soft' | 'strong'
screenreader_friendly = false, -- minimize dynamic accents and colored backgrounds
telescope_accents = false, -- enhanced accents for Telescope (matching/selection/borders)
path_separator_blue = false, -- blue path separators (Startify/Navic/WhichKey)
path_separator_color = nil, -- optional '#rrggbb' or palette key when path_separator_blue = true
selection_model = 'kitty', -- 'default' (theme) or 'kitty' (match kitty selection colors)
accessibility = { -- independent toggles
deuteranopia = false, -- shift additions to blue‑ish hue; keep warnings distinct
-- removed: strong_tui_cursor
achromatopsia = false, -- monochrome/high-contrast assist; reduce reliance on hue; boosts Folded/ColorColumn visibility
hc = 'off', -- high‑contrast pack for achromatopsia: 'off' | 'soft' | 'strong'
},
},
treesitter = {
extras = true, -- apply subtle extra captures (math/environment, string.template, boolean true/false, nil/null, decorator/annotation, declaration/static/abstract links)
punct_family = false, -- differentiate punctuation families (parenthesis/brace vs bracket) with subtle hues
},
styles = {
comments = 'italic', -- 'italic' | 'bold' | 'underline' | 'undercurl' | 'none' | combos
keywords = 'none',
functions = 'none',
strings = 'none',
variables = 'none',
types = 'none',
operators = 'none',
numbers = 'none',
booleans = 'none',
constants = 'none',
punctuation = 'none',
},
plugins = { -- set to false to disable integration
cmp = true,
telescope = true,
git = true,
gitsigns = true,
bufferline = true,
noice = true,
obsidian = true,
rainbow = true,
headline = true,
indent = true, -- indent-blankline/ibl + mini.indentscope
which_key = true,
nvim_tree = false, -- disabled by default if using neo-tree
neo_tree = true,
dap = true,
dapui = true,
trouble = true,
notify = true,
treesitter_context = true,
hop = true,
-- phase 1 additions
diffview = true,
fidget = true,
toggleterm = true,
dashboard = true,
heirline = true,
oil = true,
blink = true,
leap = true,
flash = true,
ufo = true,
bqf = true,
-- phase 2 additions
glance = true,
barbecue = true,
illuminate = true,
hlslens = true,
virt_column = true,
dap_virtual_text = true,
mini_pick = true,
snacks = true,
-- additional supported plugins
alpha = true,
mini_statusline = true,
mini_tabline = true,
todo_comments = true,
navic = true,
lspsaga = true,
neotest = true,
harpoon = true,
treesitter_playground = true,
startify = true,
overseer = true,
},
overrides = nil, -- table or function(colors) -> table
diagnostics_virtual_bg = false, -- virtual text with soft background
diagnostics_virtual_bg_blend = 15, -- used when mode = 'blend' (0..100; larger = more transparent)
diagnostics_virtual_bg_mode = 'blend', -- 'blend' | 'alpha' | 'lighten' | 'darken'
diagnostics_virtual_bg_strength = 0.15, -- strength for alpha/lighten/darken (0..1)
})When multiple post‑processing features are enabled, neg.nvim applies them in a predictable order to avoid clashes:
- Accessibility tweaks first (deuteranopia/achromatopsia, then high‑contrast pack
hc) - Diagnostics virtual backgrounds (if enabled)
- Global soft backgrounds alpha (
alpha_overlayfor Search/CurSearch/Visual/VirtualText) - Selection model (theme default vs kitty)
- User overrides last (
overridestable or function)
The palette now exposes descriptive aliases without the fg_ prefix. Old short names remain for compatibility, but new names are recommended for overrides and custom recipes.
-
Base/backgrounds
norm→default_colorbclr→bg_defaultdark→dark_colordrk2→dark_secondary_colorwhit→white_colorculc→bg_cursorcolumncomm→comment_color
-
Syntax/categories
lit1→literal1_colorlit2→literal2_colorlit3→literal3_colorops1→keyword1_colorops2→keyword2_colorops3→keyword3_colorops4→keyword4_colorotag→tag_colorlstr→string_colorincl→include_colordlim→delimiter_colorblod→red_blood_colorviolet→violet_colorhigh→highlight_colordarkhigh→highlight_dark_colorvar→variable_colorfunc→function_color
-
Diff/diagnostics
dadd→diff_add_colordchg→diff_change_colordred→diff_delete_colordwarn→warning_color
-
UI and misc
visu→bg_visualclin→bg_cursorlinepmen→pmenu_colorcsel→search_colorcmpdef→cmp_default_coloriden→identifier_colorlbgn→preproc_light_colordbng→preproc_dark_colordnorm→bg_selection_dim
-
Shades/rainbow
col1..col24→shade_01..shade_24br1..br7→rainbow_1..rainbow_7
Prefix note: fg_* aliases (e.g. fg_warning, fg_diff_delete) remain for backward compatibility and map 1:1 to the new names (e.g. warning_color, diff_delete_color). Prefer the descriptive names going forward.
Convenience aliases exposed for overrides and UI tuning:
- Float/panels:
bg_float,bg_panel,border_color - Severities:
success_color,error_color,info_color,hint_color - Accents:
accent_primary,accent_secondary,accent_tertiary
Built-in style presets you can use via preset option or :NegPreset:
- soft: default, subtle accents, italic comments
- hard: higher contrast accents; makes keywords/functions/types/constants/booleans/numbers bold,
Titlebold - pro: no italics anywhere (disables italics for comments, inlay hints, code lens, and markup italics)
- writing: Markdown-first; bold headings/strong, italic emphasis
- accessibility: higher contrast, minimal italics, stronger lines/separators and line numbers; disables soft diagnostic virtual backgrounds
- focus: dim inactive windows (stronger NormalNC/WinBarNC), soften separators/borders for less visual noise
- presentation: brighter accents with more visible
CursorLine/CursorLineNrand emphasized search/title
Usage examples:
require('neg').setup({ preset = 'hard' })
-- or on the fly:
-- :NegPreset hard
-- :NegPreset none -- clear preset| Preset | Aim | Changes | Notes |
|---|---|---|---|
| soft | Subtle defaults | Keep defaults; italic comments | Baseline look |
| hard | Higher contrast accents | Makes keywords/functions/types/constants/booleans/numbers bold; Title bold | Good for code presentations |
| pro | No italics | Disables italics for comments, inlay hints, code lens, markup italics | Pair with lexeme_cues=minimal if desired |
| writing | Emphasize markup | Bold headings/strong; italic emphasis; Title bold | For Markdown/prose |
| accessibility | Higher UI contrast | Disables diagnostic virtual BG; stronger LineNr/Separators; clearer CursorLine/ColorColumn/Visual; no italic comments | Combine with ui.accessibility.* and :NegHc |
| focus | Reduce noise, focus current window | Sets ui.dim_inactive=true, ui.soft_borders=true |
Good for many splits |
| presentation | Brighter accents | Stronger CursorLine/CursorLineNr; Title and Search emphasized | For demos and talks |
| none | No preset | No extra changes | Use explicit options only |
-- Focus with soft borders
require('neg').setup({ preset = 'focus', ui = { soft_borders = true } })
-- Presentation with neutral Telescope (no extra accents)
require('neg').setup({ preset = 'presentation', ui = { telescope_accents = false } })
-- Accessibility with soft high‑contrast pack
require('neg').setup({ preset = 'accessibility', ui = { accessibility = { achromatopsia = true, hc = 'soft' } } })
-- Pro (no italics) with mono operators
require('neg').setup({ preset = 'pro', operator_colors = 'mono' })- :NegToggleTransparent — toggle transparency and re‑apply the theme
- :NegToggleTransparentZone {float|sidebar|statusline} — toggle transparency for a specific zone
- :NegPreset {soft|hard|pro|writing|accessibility|focus|presentation|none} — apply a style preset (or clear with 'none')
- :NegReload — re‑apply highlights using the current config
- :NegInfo — show a short summary of current options, including diagnostics virtual background (enabled/mode/strength/blend)
- :NegDiagBgMode {blend|alpha|lighten|darken|off|on} — set diagnostics virtual text background mode (or turn off/on)
- :NegDiagBgStrength {0..1} — set strength for alpha/lighten/darken modes
- :NegDiagBgBlend {0..100} — set blend value when mode = 'blend'
- :NegDiagSoft — quick softer virtual text background (blend ≈ 20)
- :NegDiagStrong — quick stronger virtual text background (blend ≈ 10)
- :NegOperatorColors {families|mono|mono+} — switch operator coloring mode at runtime
- :NegNumberColors {mono|ramp|ramp-soft|ramp-strong} — switch number coloring mode/preset
- :NegSaturation {0..100} — set global saturation (100 = original, 0 = grayscale)
- :NegAlpha {0..30} — set global soft backgrounds alpha (Search/CurSearch/Visual/VirtualText)
- :NegModeAccent {on|off|toggle} — enable/disable or toggle mode-aware accents for CursorLine/StatusLine
- :NegSoftBorders {on|off|toggle} — enable/disable or toggle soft borders (WinSeparator/FloatBorder)
- :NegFloatBg {on|off|toggle} — float background model (Normal vs slightly lighter panel-like bg)
- :NegFocusCaret {on|off|toggle} — boost CursorLine contrast when overall contrast is low
- :NegLightSigns {on|off|toggle} — enable/disable or toggle light sign icons (DiagnosticSign*/GitSigns*)
- :NegSelection {default|kitty} — set selection model (kitty by default)
- :NegDimInactive {on|off|toggle} — dim inactive windows
- :NegDiffFocus {on|off|toggle} — stronger Diff* backgrounds in :diff
- :NegPunctFamily {on|off|toggle} — enable/disable or toggle punctuation family differentiation
- :NegTelescopeAccents {on|off|toggle} — toggle enhanced Telescope accents (matching/selection/borders)
- :NegPathSep {on|off|toggle} — toggle blue path separators (Telescope/Startify/Navic/WhichKey)
- :NegPathSepColor {#rrggbb|palette_key|default} — set/reset path separator color (used when blue is on)
- :NegAccessibility {feature} {on|off|toggle} — toggle accessibility features (deuteranopia|achromatopsia)
- :NegDiagPattern {none|minimal|strong} — set diagnostics pattern preset
- :NegLexemeCues {off|minimal|strong} — set lexeme cues
- :NegThickCursor {on|off|toggle} — thicker CursorLine/CursorLineNr
- :NegOutlines {on|off|toggle} — window outlines
- :NegScreenreader {on|off|toggle} — screenreader-friendly mode
- :NegReadingMode {on|off|toggle} — near-monochrome reading mode
- :NegSearchVisibility {default|soft|strong} — search/cursearch visibility
- :NegHc {off|soft|strong} — high-contrast pack presets
- :NegContrast {Group|@capture} [vs {Group|#rrggbb}] [--target AA|AAA] [apply] [--json] [--notify=off|on] — print contrast ratio; can output JSON and apply suggested :hi
- :NegExport [all|core|diff|diagnostics|syntax|hints] [--json] [--notify=off|on] — export highlights (choose sections; JSON output available)
- :NegScenario {focus|presentation|screenreader|tui|gui|accessibility} — apply a curated set of toggles quickly
- :NegScenarioSave {name} — save current config as a named scenario (session memory)
- :NegScenarioList — list built‑in and user scenarios
- :NegScenarioDelete {name} — delete a saved user scenario
- :NegScenarioExport {name|current} [--json] [--notify=off|on] — export scenario JSON (wrapped as { name, scenario })
- :NegScenarioImport {@/path|JSON} [--merge|--replace] [--notify=off|on] — import scenario from JSON string or file
- :NegScenarioWrite [@/path] [--notify=off|on] — write user scenarios to file (default: stdpath('config')/neg/scenarios.json)
- :NegScenarioRead [@/path] [--merge|--replace] [--notify=off|on] — read scenarios from file into memory
- :NegPlugins [enabled|disabled|all] [filter] [--json] [--notify=off|on] — print plugin integrations (filter by state/substring; JSON output and notify control)
- :NegPluginsSuggest [--json] [--notify=off|on] — print a ready
plugins = { ... }block by scanning lazy plugins
Defaults: all listed integrations are enabled unless noted. Toggle by setting plugins.<key> = false in setup.
- Pickers:
telescope,fzf_lua,mini_pick,snacks(on) - Completion:
cmp,blink(on) - Git & Diff:
git,gitsigns,diffview(on) - Files & Dashboards:
neo_tree(on),nvim_tree(off),oil(on),startify(on),alpha(on),dashboard(on) - Status/Tab/Winbar:
bufferline,mini_statusline,mini_tabline,heirline,barbecue,navic,navbuddy(on) - LSP/UI:
lspsaga,noice,notify,treesitter_context,treesitter_playground,glance,illuminate,hlslens(on) - Navigation/Motion:
hop,leap,flash,harpoon,rainbow(on) - Diagnostics/Tasks:
trouble,todo_comments,overseer(on) - Debug:
dap,dapui,dap_virtual_text,bqf(on) - Structure/Indent:
indent,virt_column,ufo(on) - Notes/Testing:
obsidian,neotest,which_key,toggleterm(on)
| Command | Effect | Default |
|---|---|---|
| `:NegModeAccent {on | off | toggle}` |
| `:NegFocusCaret {on | off | toggle}` |
| `:NegDimInactive {on | off | toggle}` |
| `:NegDiffFocus {on | off | toggle}` |
| `:NegSoftBorders {on | off | toggle}` |
| `:NegFloatBg {on | off | toggle}` |
| `:NegLightSigns {on | off | toggle}` |
| `:NegTelescopeAccents {on | off | toggle}` |
| `:NegPathSep {on | off | toggle}` |
| `:NegPathSepColor {#hex | key | default}` |
| `:NegSelection {default | kitty}` | Selection model (theme vs kitty) |
| `:NegPunctFamily {on | off | toggle}` |
| `:NegReadingMode {on | off | toggle}` |
| `:NegOutlines {on | off | toggle}` |
| `:NegThickCursor {on | off | toggle}` |
| `:NegSearchVisibility {default | soft | strong}` |
| `:NegScreenreader {on | off | toggle}` |
| `:NegAccessibility {deuteranopia | achromatopsia}` | Toggle accessibility features |
| `:NegHc {off | soft | strong}` |
| `:NegDiagPattern {none | minimal | strong}` |
:NegDiagSoft / :NegDiagStrong |
Quick soft/strong DiagnosticVirtualText bg | off |
By default, selection matches kitty. To use the theme selection instead:
- Option:
ui.selection_model = 'default' - Command:
:NegSelection default
Colors used (from palette):
selection_bg = '#0d1824'selection_fg = '#367bbf'
Notes:
- Keep
alpha_overlay = 0for an exact kitty match (alpha overlay softens backgrounds). - You can override
selection_bg/fgviaoverridesif you prefer different shades.
Quick overrides examples:
-- Custom kitty-like selection colors
require('neg').setup({
ui = { selection_model = 'kitty' },
overrides = {
Visual = { bg = '#101a28', fg = '#62a0ff', bold = false, underline = false },
VisualNOS = { bg = '#101a28', fg = '#62a0ff' },
},
})
-- Or compute from palette
require('neg').setup({
ui = { selection_model = 'kitty' },
overrides = function(colors)
return {
Visual = { bg = colors.selection_bg, fg = '#5fb0ff' },
}
end,
})Floats default to the exact same background as Normal (no tint). If you prefer a slightly lighter panel‑like background:
- Option:
ui.float_panel_bg = true - Command:
:NegFloatBg on
This sets NormalFloat bg to palette.bg_panel (derived from base bg). Toggle with :NegFloatBg toggle.
Quick overrides examples:
-- Slightly darker panel border and custom float bg
require('neg').setup({
ui = { float_panel_bg = true },
overrides = {
NormalFloat = { bg = '#0f131a' },
FloatBorder = { fg = '#1a1f29' },
},
})
-- Or base on palette values
require('neg').setup({
ui = { float_panel_bg = true },
overrides = function(colors)
return {
NormalFloat = { bg = colors.bg_panel },
FloatBorder = { fg = colors.border_color },
}
end,
})- CursorLine (mode_accent, focus_caret, thick_cursor)
- Order: mode accents → focus caret → thick cursor. Thick cursor makes CursorLine stronger after accents; screenreader may later stabilize it.
- Tip: for fully stable visuals (no dynamic changes), disable
ui.mode_accentandui.focus_caret, or enable:NegScreenreader on.
- WinSeparator/FloatBorder (soft_borders, outlines)
- Soft borders lightens
WinSeparator/FloatBorderglobally; outlines remapWinSeparatorper‑window to active/inactive variants. - Outcome: outlines take precedence for
WinSeparator; soft borders still affectFloatBorder.
- Soft borders lightens
- Dim inactive vs outlines
ui.dim_inactivemaps onlyLineNr(and base NormalNC/WinBarNC) per window and does not overrideWinSeparatormappings; outlines keep precedence for separators.
- Diff backgrounds (diff_focus, screenreader)
- Diff focus strengthens
Diff*bgs in:diff; screenreader clears that strengthening for calmer output.
- Diff focus strengthens
- Telescope + borders
- Telescope borders link to
WinSeparator: with outlines on, Telescope adopts active/inactive border tint per window; with soft borders on (no outlines) borders stay softly lightened.
- Telescope borders link to
- Selection, alpha overlay, diagnostics virtual bg
- Apply order (see “Apply Order”): diagnostics virtual bg → alpha overlay → selection model. If your Visual looks too soft, reduce
alpha_overlayor use:NegSearchVisibility.
- Apply order (see “Apply Order”): diagnostics virtual bg → alpha overlay → selection model. If your Visual looks too soft, reduce
- Calm presentation (brighter but not noisy)
require('neg').setup({
preset = 'presentation',
number_colors = 'ramp-soft',
ui = {
soft_borders = true,
diff_focus = false,
search_visibility = 'soft',
telescope_accents = false,
},
})- High contrast (achromatopsia, strong)
require('neg').setup({
preset = 'accessibility',
alpha_overlay = 0,
ui = {
mode_accent = false,
focus_caret = false,
soft_borders = false,
diag_pattern = 'strong',
accessibility = {
achromatopsia = true,
hc = 'strong',
},
},
})
-- Runtime shorthand:
-- :NegAccessibility achromatopsia on | :NegHc strong | :NegDiagPattern strong- Minimum dynamics (stable visuals)
require('neg').setup({
alpha_overlay = 0,
operator_colors = 'mono',
number_colors = 'mono',
ui = {
mode_accent = false,
focus_caret = false,
diff_focus = false,
outlines = false,
screenreader_friendly = true,
},
})-
Terminal (TUI)
- When: terminal usage without transparency; want crisp selection (kitty) and calmer signs.
- Changes: disables alpha overlay, enables thicker cursor and light signs, keeps neutral borders and diff focus.
-- Tip: ensure Neovim uses truecolor: :set termguicolors
require('neg').setup({
alpha_overlay = 0,
ui = {
thick_cursor = true,
soft_borders = false,
float_panel_bg = false,
diff_focus = true,
light_signs = true,
outlines = false,
telescope_accents = false,
selection_model = 'kitty',
},
})-
GUI (Neovide/Goneovim, etc.)
- When: GUI frontends; prefer soft borders and panel floats with mild accents.
- Changes: soft borders + panel float bg, light alpha overlay, optional Telescope accents.
require('neg').setup({
saturation = 95,
alpha_overlay = 6,
ui = {
soft_borders = true,
float_panel_bg = true,
telescope_accents = true,
dim_inactive = false,
outlines = false,
selection_model = 'kitty',
focus_caret = true,
},
})-
Bright presentation
- When: live demos/projectors where accents need to read from a distance.
- Changes: presentation preset, stronger numbers and search, disables dynamic accents.
require('neg').setup({
preset = 'presentation',
number_colors = 'ramp-strong',
operator_colors = 'mono+',
ui = {
mode_accent = false,
focus_caret = false,
soft_borders = true,
search_visibility = 'strong',
telescope_accents = false,
diff_focus = false,
},
})-
Screenreader‑friendly
- When: screenreader users or anyone preferring very stable visuals.
- Changes: stabilizes accents, achromatopsia + soft high‑contrast, no diff focus.
require('neg').setup({
alpha_overlay = 0,
ui = {
screenreader_friendly = true,
mode_accent = false,
focus_caret = false,
diff_focus = false,
search_visibility = 'soft',
selection_model = 'kitty',
accessibility = {
achromatopsia = true,
hc = 'soft',
},
},
})-
Terminal + kitty + blue path separators (zsh‑like)
- When: TUI with kitty‑style selection and blue path separators like zsh.
- Changes: kitty selection + blue path separators (configurable color or palette key).
require('neg').setup({
ui = {
selection_model = 'kitty',
path_separator_blue = true,
-- optional custom color (hex or palette key):
-- path_separator_color = 'include_color', -- or '#22aaff'
},
})
-- Runtime: :NegPathSep on | :NegPathSepColor include_colorYou can override any highlight groups:
require('neg').setup({
overrides = {
Normal = { fg = '#c0c0c0' },
NormalFloat = { bg = 'NONE' },
}
})or provide a function that receives the palette:
require('neg').setup({
overrides = function(c)
return { DiagnosticUnderlineWarn = { undercurl = true, sp = c.warning_color } }
end
})- No italics anywhere (alternative to
preset = 'pro'):
require('neg').setup({
overrides = function()
return {
Comment = { italic = false },
LspInlayHint = { italic = false },
LspCodeLens = { italic = false },
['@markup.italic'] = { italic = false },
}
end,
})- Transparent floats and sidebars (alternative to
transparent = { ... }):
require('neg').setup({
overrides = {
NormalFloat = { bg = 'NONE' },
Pmenu = { bg = 'NONE' },
FloatBorder = { bg = 'NONE' },
NvimTreeNormal = { bg = 'NONE' },
NeoTreeNormal = { bg = 'NONE' },
TroubleNormal = { bg = 'NONE' },
}
})- Softer/more visible virtual text background (per severity):
require('neg').setup({
overrides = function(c)
return {
DiagnosticVirtualTextError = { bg = c.diff_delete_color, blend = 12 },
DiagnosticVirtualTextWarn = { bg = c.warning_color, blend = 12 },
DiagnosticVirtualTextInfo = { bg = c.preproc_light_color, blend = 12 },
DiagnosticVirtualTextHint = { bg = c.identifier_color, blend = 12 },
}
end,
})- Stronger line numbers and separators:
require('neg').setup({
overrides = {
CursorLineNr = { bold = true },
WinSeparator = { fg = '#1c2430' },
}
})- LSP inlay hints color tweak:
require('neg').setup({
overrides = function(c)
return { LspInlayHint = { fg = c.comment_color } }
end,
})- gitsigns color tweak:
require('neg').setup({
overrides = function()
return {
GitSignsAdd = { fg = '#2ecc71' },
GitSignsChange = { fg = '#3498db' },
GitSignsDelete = { fg = '#e74c3c' },
}
end,
})You can use the color helpers from neg.util to derive colors on the fly in your overrides. This is helpful for subtle backgrounds, undercurls or tuned floats.
- Subtle diagnostic backgrounds via alpha blending on top of your theme background:
local U = require('neg.util')
require('neg').setup({
overrides = function(c)
return {
DiagnosticVirtualTextError = { bg = U.alpha(c.diff_delete_color, c.bg_default, 0.16) },
DiagnosticVirtualTextWarn = { bg = U.alpha(c.warning_color, c.bg_default, 0.14) },
DiagnosticVirtualTextInfo = { bg = U.alpha(c.preproc_light_color, c.bg_default, 0.12) },
DiagnosticVirtualTextHint = { bg = U.alpha(c.identifier_color, c.bg_default, 0.12) },
}
end,
})- Lighten/darken for selection or floats:
local U = require('neg.util')
require('neg').setup({
overrides = function(c)
return {
Visual = { bg = U.darken(c.bg_default, 6) }, -- darker selection
NormalFloat = { bg = U.lighten('#111d26', 8) }, -- soften float background
}
end,
})- Fine‑tuned undercurl hues (slightly darker than the base):
local U = require('neg.util')
require('neg').setup({
overrides = function(c)
return {
DiagnosticUnderlineError = { undercurl = true, sp = U.darken(c.diff_delete_color, 8) },
DiagnosticUnderlineWarn = { undercurl = true, sp = U.darken(c.warning_color, 6) },
}
end,
})- telescope.nvim, nvim-cmp
- gitsigns.nvim, gitgutter (basic), diff, diffview.nvim
- indent‑blankline/ibl, mini.indentscope
- mini.statusline, mini.tabline
- which‑key.nvim
- neo‑tree, nvim‑tree
- bufferline.nvim
- lualine.nvim (theme = 'neg')
- nvim‑dap, dap‑ui, nvim‑dap‑virtual‑text
- trouble.nvim
- nvim‑notify
- treesitter‑context
- hop.nvim, rainbow‑delimiters
- obsidian.nvim
- alpha‑nvim
- startify, dashboard‑nvim
- todo‑comments.nvim
- lspsaga.nvim
- overseer.nvim
- neotest
- harpoon
- nvim‑navic
- treesitter‑playground
- heirline.nvim (theme via palette)
- oil.nvim
- blink.cmp
- leap.nvim, flash.nvim
- nvim‑ufo
- nvim‑bqf
- telescope.nvim
- Groups:
TelescopeMatching,TelescopeSelection,TelescopeBorder,TelescopePreviewBorder,TelescopePromptBorder,TelescopeResultsBorder - Transparent float zone also covers:
TelescopeNormal,TelescopePreviewNormal,TelescopePromptNormal,TelescopeResultsNormal, and the corresponding*Border - mason.nvim
- Transparent float zone also covers:
MasonNormal,MasonBorder
- Transparent float zone also covers:
- lazy.nvim
- Transparent float zone also covers:
LazyNormal,LazyBorder
- Transparent float zone also covers:
- nvim-cmp
- Groups:
CmpItemKind*(extended kinds: Text/Class/Module/Field/Constructor/Enum/Unit/Value/EnumMember/Constant/Struct/Event/Operator/TypeParameter/Snippet/Color/File/Reference/Folder) - Transparent float zone also covers:
CmpDocumentation,CmpDocumentationBorder
- Groups:
- gitsigns.nvim
- Groups:
GitSignsAdd,GitSignsAddNr,GitSignsAddLn,GitSignsChange,GitSignsChangeNr,GitSignsChangeLn,GitSignsDelete,GitSignsDeleteNr,GitSignsDeleteLn,GitSignsTopdelete,GitSignsChangedelete,GitSignsUntracked,GitSignsCurrentLineBlame
- Groups:
- gitgutter/diff
- Groups:
GitGutterAdd,GitGutterChangeDelete,GitGutterChange,GitGutterDelete,DiffAdd,DiffChange,DiffDelete,DiffText,DiffAdded,DiffRemoved,diffAdded,diffChanged,diffRemoved,diffLine,diffNewFile,diffOldFile,diffOldLine
- Groups:
- indent‑blankline/ibl/mini.indentscope
- Groups:
IndentBlanklineChar,IndentBlanklineSpaceChar,IndentBlanklineSpaceCharBlankline,IndentBlanklineContextChar,IndentBlanklineContextStart,IblIndent,IblWhitespace,IblScope,MiniIndentscopeSymbol,MiniIndentscopePrefix
- Groups:
- which‑key.nvim
- Groups:
WhichKey,WhichKeyGroup,WhichKeyDesc,WhichKeySeparator,WhichKeyFloat,WhichKeyBorder,WhichKeyValue
- Groups:
- neo‑tree
- Groups:
NeoTreeNormal,NeoTreeNormalNC,NeoTreeRootName,NeoTreeDirectoryIcon,NeoTreeDirectoryName,NeoTreeCursorLine,NeoTreeGitAdded,NeoTreeGitModified,NeoTreeGitDeleted,NeoTreeDimText - Transparent float zone also covers:
NeoTreeFloatNormal,NeoTreeFloatBorder
- Groups:
- nvim‑tree
- Groups:
NvimTreeNormal,NvimTreeNormalNC,NvimTreeFolderIcon,NvimTreeFolderName,NvimTreeOpenedFolderName,NvimTreeRootFolder,NvimTreeIndentMarker,NvimTreeCursorLine,NvimTreeGitDirty,NvimTreeGitNew,NvimTreeGitDeleted
- Groups:
- symbols-outline.nvim
- Transparent sidebar zone also covers:
SymbolsOutlineNormal
- Transparent sidebar zone also covers:
- aerial.nvim
- Transparent sidebar zone also covers:
AerialNormal
- Transparent sidebar zone also covers:
- nvim‑dap
- Groups:
DebugBreakpoint,DebugBreakpointCondition,DebugBreakpointRejected,DebugStopped,DebugLogPoint,DebugPC
- Groups:
- dap‑ui
- Groups:
DapUIFloatNormal,DapUIFloatBorder,DapUIVariable,DapUIDecoration,DapUIScope,DapUIType,DapUIValue,DapUILineNumber,DapUIBreakpointsPath,DapUIBreakpointsLine,DapUIBreakpointsCurrentLine,DapUIBreakpointsDisabledLine,DapUIPlayPause,DapUIRestart,DapUIStop,DapUIUnavailable,DapUIWinSelect
- Groups:
- trouble.nvim
- Groups:
TroubleNormal,TroubleText,TroubleCount,TroubleFoldIcon,TroubleLocation,TroubleFilename,TroubleIndent,TroubleSignError,TroubleSignWarning,TroubleSignInformation,TroubleSignHint
- Groups:
- nvim‑notify
- Groups:
NotifyBackground, plusNotify{ERROR|WARN|INFO|DEBUG|TRACE}{Border|Icon|Title}
- Groups:
- treesitter‑context
- Groups:
TreesitterContext,TreesitterContextLineNumber,TreesitterContextSeparator
- Groups:
- hop.nvim
- Groups:
HopNextKey,HopNextKey1,HopNextKey2,HopUnmatched
- Groups:
- rainbow‑delimiters
- Groups:
RainbowDelimiterRed,RainbowDelimiterYellow,RainbowDelimiterBlue,RainbowDelimiterOrange,RainbowDelimiterGreen,RainbowDelimiterViolet,RainbowDelimiterCyan
- Groups:
- obsidian.nvim
- alpha‑nvim
- startify / startify
- todo‑comments.nvim
- lspsaga.nvim
- overseer.nvim
- lspsaga.nvim
- overseer.nvim
- neotest
- harpoon
- nvim‑navic
- navbuddy
- treesitter‑playground
- Groups:
ObsidianExtLinkIcon,ObsidianRefText,ObsidianBullet,ObsidianImportant,ObsidianTilde,ObsidianRightArrow,ObsidianDone,ObsidianTodo,ObsidianHighlightText,ObsidianBlockID,ObsidianTag
- Groups:
- headline.nvim
- Groups:
Headline1,Headline2,CodeBlock,Dash
- Groups:
- noice.nvim
- Groups:
NoiceCursor,NoiceCmdLine, popup/cmdline menu (NoiceCmdlinePopup,NoiceCmdlinePopupBorder,NoicePopup,NoicePopupBorder,NoicePopupmenu,NoicePopupmenuBorder); transparent float zone also coversNoicePopup,NoicePopupmenu,NoiceCmdlinePopup
- Groups:
- dressing.nvim
- Transparent float zone also covers:
DressingInput,DressingInputBorder,DressingSelect,DressingSelectBorder
- Transparent float zone also covers:
- fzf-lua
- Groups:
FzfLuaNormal,FzfLuaBorder,FzfLuaTitle,FzfLuaCursorLine,FzfLuaMatch - Transparent float zone also covers: preview (
FzfLuaPreviewNormal,FzfLuaPreviewBorder,FzfLuaPreviewTitle)
- Groups:
- Theme looks mixed or not applied sometimes
- Ensure only one colorscheme is active. If using multiple themes, remove extra
colorschemecalls. - With lazy.nvim, set a high
priority(e.g. 1000) andlazy = falsefor this plugin. - Run
:colorscheme negafter your UI plugins load if something overrides highlights late.
- Ensure only one colorscheme is active. If using multiple themes, remove extra
- Transparency seems not applied
- Terminal must support transparency (or set GUI background).
transparentsets highlight backgrounds toNONE, it does not change the terminal background. - For specific areas, use
transparent = { float = true, sidebar = true, statusline = true }or the command:NegToggleTransparentZone. - Check your overrides — they have the last word. Use
:NegInfoto inspect active options.
- Terminal must support transparency (or set GUI background).
- Overriding a linked group has no effect
- When a group
links to another, its own attrs are ignored. Provide attributes in youroverridesto break the link (Neovim will clear the link when attrs are set). - Example:
NormalFloat = { bg = 'NONE' }will override any previous link.
- When a group
- Colors look off
- Add
:set termguicolorsto your config and keepterminal_colors = true(or tune them in overrides).
- Add
- Treesitter/LSP highlight mismatch
- Use
:Inspecton a token to see active captures. Some captures differ between Neovim 0.9/0.10 and parsers. - This colorscheme links common modern captures; update Neovim/parsers if something is missing.
- Use
- Diagnostics are too strong/too soft
- Disable colored virtual backgrounds with
diagnostics_virtual_bg = falseor tunediagnostics_virtual_bg_blend. - Or override individual severities.
- Disable colored virtual backgrounds with
- Italics not visible
- Your terminal font might not support italics. Try a GUI (Neovide) or a font that supports italics.
- Light background?
- This is a dark theme.
set background=lightis not supported at the moment.
- This is a dark theme.
- How do I use it with
:colorscheme?- The plugin provides
colors/neg.lua. Use:colorscheme negafterrequire('neg').setup(...).
- The plugin provides
- How do I disable a specific plugin integration?
- Set its flag to
falseunderplugins.
- Set its flag to
- Can I customize the palette?
- Use
overridesfor highlight groups andrequire('neg.palette')if you need palette colors. Direct palette overrides are not exposed yet.
- Use
- How do I toggle presets/transparency on the fly?
- Use
:NegPreset soft|hard|pro|writing|noneand:NegToggleTransparent/:NegToggleTransparentZone {float|sidebar|statusline}.
- Use
- A plugin's group is not covered — what do I do?
- Add an
overridesentry for that group. PRs to add more integrations are welcome.
- Add an
-
Locally:
./scripts/validate.sh -
Strict mode (treat WARN as errors):
NEG_VALIDATE_STRICT=1 ./scripts/validate.sh -
GitHub Actions:
.github/workflows/validate.yml -
Optional contrast check:
NEG_VALIDATE_CONTRAST=1 NEG_VALIDATE_CONTRAST_MIN=3.0 ./scripts/validate.sh- Reports warnings if contrast ratio (fg vs bg) is below the threshold.
- Tip: enable only when tuning colors; strict mode will fail on warnings.
-
Verbose summary:
NEG_VALIDATE_VERBOSE=1 ./scripts/validate.shprints a short coverage line. -
Coverage listing (optional):
NEG_VALIDATE_LIST=1— print all defined groups asDEF: <name>linesNEG_VALIDATE_LIST_FILTER='^CmpItem'— filter names by Lua patternNEG_VALIDATE_LIST_LIMIT=200— limit number of printed names
-
Module stats & duplicates:
NEG_VALIDATE_MODULE_STATS=1— per‑module group countsNEG_VALIDATE_DUP_SOURCES=1— show duplicate group sources (module names)
- bufferline.nvim
- Groups:
BufferLine*(fill, background, selected/visible buffers, tabs, separators, modified/duplicate markers, indicators, close buttons)
- Groups:
- lualine.nvim
- Theme:
require('lualine').setup({ options = { theme = 'neg' } })
- Theme:





