-- lua/oasis/theme_generator.lua local Config = require("oasis.config") -- Groups to give transparency if enabled local TRANSPARENT_GROUPS = { "Normal", "NormalNC", "NormalFloat", "SignColumn", "FoldColumn", "StatusLine", "StatusLineNC", "TabLine", "TabLineFill", "Pmenu", "PmenuSbar", "CursorLine", "ColorColumn", "FloatBorder", } ---Create the full highlight table for a palette. ---@param c OasisPalette Color palette ---@param light_mode boolean Whether palette is light mode ---@param theme {primary: string, primary_light: string, primary_strong: string, secondary: string, title?: string} ---@return OasisHighlightGroupMap highlights local function create_highlights(c, light_mode, theme) local match_paren_bg = Config.get().match_paren_bg ~= false -- stylua: ignore start local highlights = { -- Main Theme Colors (Highlights for plugins) OasisTitle = { fg=theme.title, bg="NONE" }, OasisStrongPrimary = { fg=theme.primary_strong, bg="NONE" }, OasisPrimary = { fg=theme.primary, bg="NONE" }, OasisLightPrimary = { fg=theme.primary_light, bg="NONE" }, OasisFloatPrimary = { fg=theme.primary, bg=c.ui.float.border.bg }, OasisSecondary = { fg=theme.secondary, bg="NONE" }, OasisFloatSecondary = { fg=theme.secondary, bg=c.ui.float.border.bg }, OasisAccent = { fg=c.theme.accent, bg="NONE" }, -- The following are the Neovim (as of 0.8.0-dev+100-g371dfb174) highlight -- groups, mostly used for styling UI elements. -- See :h highlight-groups ColorColumn = { fg=c.fg.core, bg=c.bg.mantle }, -- Columns set with 'colorcolumn' Conceal = { fg=c.fg.muted }, -- Placeholder characters substituted for concealed text (see 'conceallevel') Cursor = { fg=c.bg.core, bg=(light_mode and c.syntax.statement or c.terminal.yellow) }, -- Character under the cursor CurSearch = { fg=c.ui.match.fg, bg=c.ui.match.bg, bold=true }, -- Highlighting a search pattern under the cursor (see 'hlsearch') lCursor = { fg=c.bg.core, bg=c.syntax.exception }, -- Character under the cursor when |language-mapping| is used (see 'guicursor') CursorIM = "Cursor", -- Like Cursor, but used when in IME mode |CursorIM| CursorColumn = { bg=c.ui.cursor_line }, -- Screen-column at the cursor, when 'cursorcolumn' is set. CursorLine = { bg=c.ui.cursor_line }, -- Screen-line at the cursor, when 'cursorline' is set. Low-priority if foreground (ctermc.fg OR guifg) is not set. Added = { fg=c.diff.add }, -- Added line Changed = { fg=c.diff.change }, -- Changed line Removed = { fg=c.diff.delete }, -- Deleted line DiffAdd = { bg=c.diff.add }, -- Diff mode: Added line |diff.txt| DiffChange = { bg=c.diff.change }, -- Diff mode: Changed line |diff.txt| DiffDelete = { bg=c.diff.delete }, -- Diff mode: Deleted line |diff.txt| DiffText = { bg=c.diff.text }, -- Diff mode: Changed text within a changed line |diff.txt| Directory = { fg=c.ui.dir }, -- Directory names (and other special names in listings) TermCursor = { reverse=true }, -- Cursor in a focused terminal TermCursorNC = { reverse=true }, -- Cursor in an unfocusd terminal ErrorMsg = { fg=c.ui.diag.error.fg, bg=c.ui.diag.error.bg }, -- Error messages on the command line Folded = { fg=c.syntax.statement, bg=c.bg.surface }, -- Line used for closed folds FoldColumn = { fg=c.fg.muted, bg=c.bg.core }, -- 'foldcolumn' SignColumn = { fg=c.fg.muted, bg="NONE" }, -- Column where |signs| are displayed IncSearch = { fg=c.ui.match.fg, bg=c.ui.match.bg, bold=true }, -- 'incsearch' highlighting; also used for the text replaced with ":s///c" Search = { fg=c.ui.search.fg, bg=c.ui.search.bg, bold=true }, -- Last search pattern highlighting (see 'hlsearch'). Also used for similar items that need to stand out. Substitute = "Search", -- |:substitute| replacement text highlighting LineNr = { fg=c.fg.muted, bg=(c.bg.gutter or "NONE") }, -- Line number for ":number" and ":#" commands, and when 'number' or 'relativenumber' option is set. LineNrAbove = "LineNr", -- Line number for when the 'relativenumber' option is set, above the cursor line LineNrBelow = "LineNr", -- Line number for when the 'relativenumber' option is set, below the cursor line CursorLineNr = { fg=c.ui.line_number, bg=(c.bg.gutter or "NONE"), bold=true }, -- Like LineNr when 'cursorline' or 'relativenumber' is set for the cursor line. CursorLineFold = { bg=c.bg.core }, -- Like FoldColumn when 'cursorline' is set for the cursor line CursorLineSign = { bg="NONE" }, -- Like SignColumn when 'cursorline' is set for the cursor line MatchParen = { fg=c.ui.match_parent.fg, bg=(match_paren_bg and c.ui.match_parent.bg or "NONE"), bold=true, underline=true, reverse=match_paren_bg }, -- Character under the cursor or just before it, if it is a paired bracket, and its match. |pi_paren.txt| ModeMsg = { fg=c.syntax.statement, bold=true }, -- 'showmode' message (e.g., "-- INSERT -- ") MsgArea = { fg=c.syntax.statement }, -- Area for messages and cmdline MoreMsg = { fg=c.syntax.type, bold=true }, -- |more-prompt| NonText = { fg=c.ui.nontext }, -- '@' at the end of the window, characters from 'showbreak' and other non-existant characters. See also |hl-EndOfBuffer|. EndOfBuffer = "NonText", -- Filler lines (~) after the end of the buffer. By default, this is highlighted like |hl-NonText|. Normal = { fg=c.fg.core, bg=c.bg.core }, -- Normal text NormalNC = "Normal", -- normal text in non-current windows NormalFloat = { fg=c.ui.float.fg, bg=c.ui.float.bg }, -- Normal text in floating windows. FloatBorder = { fg=c.ui.float.border.fg, bg=c.ui.float.border.bg }, -- Border of floating windows. FloatTitle = { fg=c.ui.float.title, bg=c.ui.float.border.bg, bold=true }, -- Title of floating windows. Pmenu = "NormalFloat", -- Popup menu: Normal item. PmenuSel = { bg=c.ui.visual.bg, bold=true }, -- Popup menu: Selected item. PmenuMatch = { fg=c.theme.accent }, PmenuKind = "Pmenu", -- Popup menu: Normal item "kind" PmenuKindSel = "PmenuSel", -- Popup menu: Selected item "kind" PmenuExtra = "Pmenu", -- Popup menu: Normal item "extra text" PmenuExtraSel = "PmenuSel", -- Popup menu: Selected item "extra text" PmenuBorder = "FloatBorder", -- Popup menu: border of popup menu. PmenuSbar = { bg=c.bg.core }, -- Popup menu: Scrollbar. PmenuThumb = { bg=c.fg.muted }, -- Popup menu: Thumb of the scrollbar. Question = { fg=c.ui.diag.ok.fg, bold=true }, -- |hit-enter| prompt and yes/no questions QuickFixLine = { fg=c.bg.core, bg=c.syntax.statement }, -- Current |quickfix| item in the quickfix window. Combined with |hl-CursorLine| when the cursor is there. SpecialKey = { fg=c.syntax.type }, -- Unprintable characters: text displayed differently from what it really is. But not 'listchars' whitespace. |hl-Whitespace| SpellBad = { bg=c.bg.shadow, undercurl=true, sp=c.ui.diag.error.fg }, -- Word that is not recognized by the spellchecker. |spell| Combined with the highlighting used otherwise. SpellCap = { bg=c.bg.shadow, undercurl=true, sp=c.ui.diag.info.fg }, -- Word that should start with a capital. |spell| Combined with the highlighting used otherwise. SpellLocal = { bg=c.bg.shadow, undercurl=true, sp=c.ui.diag.warn.fg }, -- Word that is recognized by the spellchecker as one that is used in another region. |spell| Combined with the highlighting used otherwise. SpellRare = { bg=c.bg.shadow, undercurl=true, sp=c.ui.diag.hint.fg }, -- Word that is recognized by the spellchecker as one that is hardly ever used. |spell| Combined with the highlighting used otherwise. StatusLine = { fg=theme.primary_light, bg=c.bg.mantle }, -- Status line of current window StatusLineNC = { fg=c.fg.muted, bg=c.bg.mantle }, -- Status lines of not-current windows. Note: If this is equal to "StatusLine" Vim will use "^^^" in the status line of the current window. StatusLineTerm = "StatusLine", -- Status lines of not-current windows. Note: If this is equal to "StatusLine" Vim will use "^^^" in the status line of the current window. TabLine = { fg=c.ui.border, bg=c.bg.surface }, -- Tab pages line, not active tab page label TabLineFill = { fg=c.ui.border, bg=c.bg.surface }, -- Tab pages line, where there are no labels TabLineSel = { fg=c.bg.core, bg=theme.secondary }, -- Tab pages line, active tab page label MsgSeparator = "StatusLine", -- Separator for scrolled messages, `msgsep` flag of 'display' Title = { fg=c.ui.title, bold=true }, -- Titles for output from ":set all", ":autocmd" etc. VertSplit = { fg=c.ui.border, bg=c.bg.crust }, -- Column separating vertically split windows Visual = { bg=c.ui.visual.bg, fg = (c.ui.visual.fg or "NONE") }, -- Visual mode selection VisualNOS = { bg=c.ui.visual.bg }, -- Visual mode selection when vim is "Not Owning the Selection". WarningMsg = { fg=c.ui.diag.warn.fg, bold=true }, -- Warning messages Whitespace = "NonText", -- "nbsp", "space", "tab" and "trail" in 'listchars' Winseparator = "VertSplit", -- Separator between window splits. Inherts from |hl-VertSplit| by default, which it will replace eventually. WildMenu = { fg=c.bg.core, bg=c.ui.diag.warn.fg }, -- Current match in 'wildmenu' completion WinBar = { bold=true }, -- Window bar of current window WinBarNC = "WinBar", -- Window bar of not-current windows -- Common vim syntax groups used for all kinds of code and markup. -- Commented-out groups should chain up to their preferred (*) group -- by default. -- See :h group-name Comment = { fg=c.syntax.comment, italic=true }, -- Any comment Constant = { fg=c.syntax.constant }, -- (*) Any constant String = { fg=c.syntax.string }, -- A string constant: "this is a string" Character = "String", -- A character constant: 'c', '\n' Number = "Constant", -- A number constant: 234, 0xff Float = "Number", -- A floating point constant: 2.3e10 Boolean = { fg=c.syntax.constant, bold=true }, -- A boolean constant: TRUE, FALSE Identifier = { fg=c.syntax.identifier }, -- (*) Any variable name Function = { fg=c.syntax.func }, -- Function name (also: methods for classes) Statement = { fg=c.syntax.statement, bold=true }, -- (*) Any statement Keyword = { fg=c.syntax.identifier, bold=true }, -- any other keyword Conditional = { fg=c.syntax.conditional, bold=true }, -- if, then, else, endif, switch, etc. Repeat = "Conditional", -- for, do, while, etc. Label = "Conditional", -- case, default, etc. Operator = { fg=c.syntax.operator }, -- "sizeof", "+", "*", etc. Exception = { fg=c.syntax.exception, bold=true }, -- try, catch, throw PreProc = { fg=c.syntax.preproc, bold=true, italic=true }, -- (*) Generic Preprocessor Include = "PreProc", -- Preprocessor #include Define = "PreProc", -- Preprocessor #define PreCondit = "PreProc", -- Preprocessor #if, #else, #endif, etc. Macro = { fg=c.syntax.macro, italic=true, bold=true }, -- Macros Type = { fg=c.syntax.type }, -- (*) int, long, char, etc. StorageClass = { fg=c.syntax.type, bold=true }, -- static, register, volatile, etc. Structure = "Type", -- struct, union, enum, etc. Typedef = { fg=c.syntax.typedef, italic=true }, -- A typedef Special = { fg=c.syntax.special }, -- (*) Any special symbol SpecialChar = "Exception", -- Special character in a constant Tag = { fg=c.syntax.special, underline=true }, -- You can use CTRL-] on this Delimiter = { fg=c.syntax.delimiter }, -- Character that needs attention SpecialComment = { fg=c.syntax.special, bold=true, italic=true }, -- Special things inside a comment (e.g. '\n') Debug = "Constant", -- Debugging statements Underlined = { underline=true }, -- Text that stands out, HTML links Ignore = { fg=c.fg.muted }, -- Left blank, hidden |hl-Ignore| Error = { fg=c.bg.core, bg=c.ui.diag.error.fg, reverse=true }, -- Any erroneous construct Todo = { fg=c.bg.core, bg=c.ui.diag.warn.fg, bold=true }, -- Anything that needs extra attention; mostly the keywords TODO FIXME and XXX -- These groups are for the native LSP client and diagnostic system. Some -- other LSP clients may use these groups, or use their own. Consult your -- LSP client's documentation. -- See :h lsp-highlight, some groups may not be listed, submit a PR fix to lush-template! LspReferenceText = { bg=c.bg.surface } , -- Used for highlighting "text" references LspReferenceRead = { bg=c.bg.surface } , -- Used for highlighting "read" references LspReferenceWrite = { bg=c.bg.surface } , -- Used for highlighting "write" references LspInlayHint = { fg=c.ui.nontext, bg=c.bg.shadow, italic=true } , -- Used to color the virtual text of the codelens. See |nvim_buf_set_extmark()|. LspCodeLens = { fg=c.fg.muted } , -- Used to color the virtual text of the codelens. See |nvim_buf_set_extmark()|. LspCodeLensSeparator = { fg=c.fg.muted } , -- Used to color the seperator between two or more code lens. LspSignatureActiveParameter= { fg=c.bg.core, bg=c.syntax.constant } , -- Used to highlight the active parameter in the signature help. See |vim.lsp.handlers.signature_help()|. -- See :h diagnostic-highlights, some groups may not be listed DiagnosticError = { fg=c.ui.diag.error.fg } , -- Used as the base highlight group. Other Diagnostic highlights link to this by default (except Underline) DiagnosticWarn = { fg=c.ui.diag.warn.fg } , -- Used as the base highlight group. Other Diagnostic highlights link to this by default (except Underline) DiagnosticInfo = { fg=c.ui.diag.info.fg } , -- Used as the base highlight group. Other Diagnostic highlights link to this by default (except Underline) DiagnosticHint = { fg=c.ui.diag.hint.fg } , -- Used as the base highlight group. Other Diagnostic highlights link to this by default (except Underline) DiagnosticOk = { fg=c.ui.diag.ok.fg } , -- Used as the base highlight group. Other Diagnostic highlights link to this by default (except Underline) DiagnosticVirtualTextError = { fg=c.ui.diag.error.fg, bg=c.ui.diag.error.bg } , -- Used for "Error" diagnostic virtual text. DiagnosticVirtualTextWarn = { fg=c.ui.diag.warn.fg, bg=c.ui.diag.warn.bg } , -- Used for "Warn" diagnostic virtual text. DiagnosticVirtualTextInfo = { fg=c.ui.diag.info.fg, bg=c.ui.diag.info.bg } , -- Used for "Info" diagnostic virtual text. DiagnosticVirtualTextHint = { fg=c.ui.diag.hint.fg, bg=c.ui.diag.hint.bg } , -- Used for "Hint" diagnostic virtual text. DiagnosticVirtualTextOk = { fg=c.ui.diag.ok.fg, bg=c.ui.diag.ok.bg } , -- Used for "Ok" diagnostic virtual text. DiagnosticUnderlineError = { undercurl=true, sp=c.ui.diag.error.fg } , -- Used to underline "Error" diagnostics. DiagnosticUnderlineWarn = { undercurl=true, sp=c.ui.diag.warn.fg } , -- Used to underline "Warn" diagnostics. DiagnosticUnderlineInfo = { undercurl=true, sp=c.ui.diag.info.fg } , -- Used to underline "Info" diagnostics. DiagnosticUnderlineHint = { undercurl=true, sp=c.ui.diag.hint.fg } , -- Used to underline "Hint" diagnostics. DiagnosticUnderlineOk = { undercurl=true, sp=c.ui.diag.ok.fg } , -- Used to underline "Ok" diagnostics. DiagnosticFloatingError = "DiagnosticError" , -- Used to color "Error" diagnostic messages in diagnostics float. See |vim.diagnostic.open_float()| DiagnosticFloatingWarn = "DiagnosticWarn" , -- Used to color "Warn" diagnostic messages in diagnostics float. DiagnosticFloatingInfo = "DiagnosticInfo" , -- Used to color "Info" diagnostic messages in diagnostics float. DiagnosticFloatingHint = "DiagnosticHint" , -- Used to color "Hint" diagnostic messages in diagnostics float. DiagnosticFloatingOk = "DiagnosticOk" , -- Used to color "Ok" diagnostic messages in diagnostics float. DiagnosticSignError = "DiagnosticError" , -- Used for "Error" signs in sign column. DiagnosticSignWarn = "DiagnosticWarn" , -- Used for "Warn" signs in sign column. DiagnosticSignInfo = "DiagnosticInfo" , -- Used for "Info" signs in sign column. DiagnosticSignHint = "DiagnosticHint" , -- Used for "Hint" signs in sign column. DiagnosticSignOk = "DiagnosticOk" , -- Used for "Ok" signs in sign column. TreesitterContext = { fg=c.ui.float.fg, bg=c.bg.surface }, -- "NormalFloat" -- Tree-Sitter syntax groups. -- See :h treesitter-highlight-groups, some groups may not be listed, ["@parameter"] = { fg=c.syntax.parameter }, -- Identifier ["@variable"] = { fg=c.fg.core }, -- Identifier ["@variable.builtin"] = { fg=c.syntax.builtin_var }, -- Identifier ["@variable.parameter"] = "@parameter", -- Identifier ["@variable.css"] = "@parameter", -- Identifier ["@variable.member"] = { fg=c.syntax.identifier }, -- Identifier ["@text.literal"] = "Comment", -- Comment ["@text.reference"] = "Identifier", -- Identifier ["@text.title"] = "Title", -- Title ["@text.uri"] = "Underlined", -- Underlined ["@text.underline"] = "Underlined", -- Underlined ["@text.todo"] = "Todo", -- Todo ["@comment"] = "Comment", -- Comment ["@comment.error"] = { fg=c.ui.diag.error.fg, bg=c.ui.diag.error.bg, bold=true }, -- Comment (e.g. `WARNING`, `FIX`, `HACK`) ["@comment.warning"] = { fg=c.ui.diag.warn.fg, bg=c.ui.diag.warn.bg, bold=true }, -- Comment (e.g. `WARNING`, `FIX`, `HACK`) -- ["@comment.todo"] = {} -- Comment todo-type comments (e.g. `TODO`, `WIP`) ["@comment.note"] = { fg=c.ui.diag.info.fg, bg=c.ui.diag.info.bg, bold=true }, -- Comment (e.g. `NOTE`, `INFO`, `XXX`) ["@punctuation"] = { fg=c.syntax.punctuation }, -- Delimiter ["@punctuation.delimiter"] = { fg=c.syntax.punctuation }, -- Delimiter (e.g. `;`, `.`, `,`) ["@punctuation.bracket"] = { fg=c.syntax.bracket }, -- Delimiter (e.g. `()`, `{}`, `[]`) ["@punctuation.special"] = { fg=c.syntax.operator }, -- Delimiter (e.g. `{}` in string interpolation) ["@constant"] = "Constant", -- Constant ["@constant.builtin"] = { fg=c.syntax.builtin_const, bold=true }, -- Special ["@constant.macro"] = "Macro", -- Define ["@define"] = "Define", -- Define ["@macro"] = "Macro", -- Macro ["@string"] = "String", -- String ["@string.regexp"] = { fg=c.syntax.regex, italic=true }, -- SpecialChar ["@string.escape"] = "Exception", -- SpecialChar ["@string.special"] = "SpecialChar", -- (e.g., dates) ["@string.special.symbol"]= { fg=c.syntax.identifier }, ["@string.special.url"] = { fg=c.ui.diag.hint.fg, underline=true }, ["@character"] = "Character", -- Character ["@character.special"] = "SpecialChar", -- SpecialChar ["@number"] = "Number", -- Number ["@boolean"] = "Boolean", -- Boolean ["@float"] = "Float", -- Float ["@function"] = "Function", -- Function ["@function.builtin"] = { fg=c.syntax.builtin_func }, -- Special ["@function.macro"] = "Macro", -- Macro ["@method"] = "Function", -- Function ["@field"] = "Identifier", -- Identifier ["@property"] = "Identifier", -- Identifier ["@module"] = "Special", -- Special ["@module.builtin"] = "@variable.builtin", -- Special ["@constructor"] = "Type", -- Special (e.g. 'Map', 'Set', 'Error') ["@constructor.lua"] = "@punctuation.bracket", -- Special (e.g. {}) ["@conditional"] = "Conditional", -- Conditional ["@repeat"] = "Repeat", -- Repeat ["@label"] = "Label", -- Label ["@operator"] = { fg=c.syntax.operator, bold=true }, -- Operator ["@keyword"] = "Statement", -- Keyword misc not fitting into specific categories ["@keyword.coroutine"] = { fg=c.syntax.conditional }, -- Keyword coroutines (e.g. `go` in Go, `async/await` in Python) ["@keyword.operator"] = { fg=c.syntax.operator, bold=true }, -- Keyword English words (e.g. `and`, `or`) ["@keyword.import"] = "PreProc", -- Keyword (e.g. `import`, `from` in Python) ["@keyword.export"] = { fg=c.syntax.preproc, bold=true }, -- Keyword (e.g. `export`) ["@keyword.directive"] = "PreProc", -- Keyword (e.g. #define, #if) ["@keyword.return"] = { fg=c.syntax.exception, bold=true }, -- Keyword -- `return` and `yield` ["@keyword.exception"] = "Exception", -- Keyword (e.g. `throw`, `catch`) ["@keyword.luap"] = "Exception", -- Keyword ["@keyword.modifier"] = "Exception", -- Keyword (e.g. `!important`) ["@keyword.repeat"] = "Repeat", -- Keyword ["@keyword.function"] = { fg=c.syntax.statement }, -- Keyword ["@keyword.conditional"] = "Conditional", -- Keyword ["@exception"] = "Exception", -- Exception ["@attribute"] = "Macro", -- Special (e.g. 'Map', 'Set', 'Error') ["@attribute.css"] = { fg=c.syntax.exception, italic=true }, -- (e.g. `:hover`, `::before`) ["@type"] = "Type", -- Type ["@type.builtin"] = "Typedef", ["@type.definition"] = "Typedef", -- Typedef ["@type.jsdoc"] = "Typedef", -- Type ["@storageclass"] = "StorageClass", -- StorageClass ["@structure"] = "Structure", -- Structure ["@namespace"] = "@variable.builtin", -- Identifier ["@namespace.builtin"] = "@variable.builtin", -- Identifier ["@include"] = "Include", -- Include ["@preproc"] = "PreProc", -- PreProc ["@debug"] = "Debug", -- Debug ["@tag"] = "Label", -- Tag ["@tag.attribute"] = "Keyword", -- Tag ["@tag.delimiter"] = { fg=c.syntax.punctuation }, -- Tag ["@tag.html"] = "Statement", -- Html tag ["@tag.css"] = "Statement", -- Html tag in CSS ["@tag.builtin"] = "Conditional", -- Html tag e.g. `