From 5a40f441b001be2ae979470a78350e1e90478a04 Mon Sep 17 00:00:00 2001 From: Nicholas McDaniel Date: Wed, 5 Mar 2025 21:06:49 -0500 Subject: [PATCH] Initial commit --- LICENSE | 21 +++++ README.md | 6 ++ colors/coral.lua | 1 + lua/coral/colors.lua | 38 ++++++++++ lua/coral/highlights/init.lua | 23 ++++++ lua/coral/highlights/lsp.lua | 62 +++++++++++++++ lua/coral/highlights/nvim.lua | 114 ++++++++++++++++++++++++++++ lua/coral/highlights/plugins.lua | 12 +++ lua/coral/highlights/treesitter.lua | 92 ++++++++++++++++++++++ lua/coral/init.lua | 23 ++++++ lua/coral/themes.lua | 80 +++++++++++++++++++ 11 files changed, 472 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 colors/coral.lua create mode 100644 lua/coral/colors.lua create mode 100644 lua/coral/highlights/init.lua create mode 100644 lua/coral/highlights/lsp.lua create mode 100644 lua/coral/highlights/nvim.lua create mode 100644 lua/coral/highlights/plugins.lua create mode 100644 lua/coral/highlights/treesitter.lua create mode 100644 lua/coral/init.lua create mode 100644 lua/coral/themes.lua diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3c85e0f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Nicholas McDaniel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7012ae2 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Coral.nvim + +Coral is a theme built off of three primary colors, coral, blue, and gray. + +## Screenshot +![image](https://github.com/user-attachments/assets/763220c3-16fd-4726-97dc-af515cc9a6e0) diff --git a/colors/coral.lua b/colors/coral.lua new file mode 100644 index 0000000..e13bed6 --- /dev/null +++ b/colors/coral.lua @@ -0,0 +1 @@ +require('coral').load() diff --git a/lua/coral/colors.lua b/lua/coral/colors.lua new file mode 100644 index 0000000..a8f53ef --- /dev/null +++ b/lua/coral/colors.lua @@ -0,0 +1,38 @@ +local colors = { + -- Coral pink colors + coral0 = '#AA6666', + coral1 = '#C39393', + coral2 = '#D5B3B3', + + -- Blue-gray colors + blue0 = '#535F76', + blue1 = '#868F9F', + blue2 = '#BABFC8', + + gray0 = '#444444', + gray1 = '#696969', + gray2 = '#818181', + gray3 = '#b4b4b4', + gray4 = '#d9d9d9', + + -- Mainly used for error/warn/info + green = '#71995f', + red = '#B94343', + orange = '#FF8E61', + yellow = '#FDDB76', + special = '#6f92d4', + + -- UI + bg0 = '#060605', + bg1 = '#100f0e', + bg2 = '#272626' +} + +local M = {} + +function M.setup(config) + config = config or {} + return vim.tbl_extend('force', colors, config.override_colors or {}) +end + +return M diff --git a/lua/coral/highlights/init.lua b/lua/coral/highlights/init.lua new file mode 100644 index 0000000..64b0baf --- /dev/null +++ b/lua/coral/highlights/init.lua @@ -0,0 +1,23 @@ +local M = {} + +function M.setup(theme, config) + config = config or {} + + local highlights = {} + for _, highlight in ipairs({ 'nvim', 'treesitter', 'lsp', 'plugins' }) do + local mod = require('coral.highlights.' .. highlight) + for hl, spec in pairs(mod.setup(theme, config)) do + highlights[hl] = spec + end + end + + return highlights +end + +function M.apply(highlights) + for hl, spec in pairs(highlights) do + vim.api.nvim_set_hl(0, hl, spec) + end +end + +return M diff --git a/lua/coral/highlights/lsp.lua b/lua/coral/highlights/lsp.lua new file mode 100644 index 0000000..a7184b6 --- /dev/null +++ b/lua/coral/highlights/lsp.lua @@ -0,0 +1,62 @@ +local M = {} + +function M.setup(theme, config) + config = config or {} + + local res = { + ['@lsp.type.comment'] = { link = '@comment' }, + + ['@lsp.type.decorator'] = { link = '@attribute' }, + ['@lsp.typemod.decorator.defaultLibrary'] = { link = '@attribute.builtin' }, + + ['@lsp.type.enumMember'] = { link = '@constant' }, + ['@lsp.type.enumMember.defaultLibrary'] = { link = '@constant.builtin' }, + + ['@lsp.type.function'] = { link = '@function' }, + ['@lsp.typemod.function.definition'] = { link = '@function.definition' }, + ['@lsp.typemod.function.defaultLibrary'] = { link = '@function.builtin' }, + + ['@lsp.type.keyword'] = { link = '@keyword' }, + + ['@lsp.type.macro'] = { link = '@constant.macro' }, + + ['@lsp.type.method'] = { link = '@function.method' }, + + -- modifier? + + ['@lsp.type.namespace'] = { link = '@module' }, + ['@lsp.typemod.namespace.defaultLibrary'] = { link = '@module.builtin' }, + + ['@lsp.type.number'] = { link = '@number' }, + + ['@lsp.type.operator'] = { link = '@operator' }, + + ['@lsp.type.parameter'] = { link = '@variable.parameter' }, + + ['@lsp.type.property'] = { link = '@variable.member' }, + + ['@lsp.type.regexp'] = { link = '@string.regexp' }, + + ['@lsp.type.string'] = { link = '@string' }, + + ['@lsp.type.typeParameter'] = { link = '@type' }, -- TODO: Determine accuracy + + ['@lsp.type.variable'] = { link = '@variable' }, + ['@lsp.typemod.variable.defaultLibrary'] = { link = '@variable.builtin' } + } + + + -- Standard type definitions + local standardTypes = { 'class', 'enum', 'event', 'interface', 'struct', 'type' } + for _, ty in ipairs(standardTypes) do + res['@lsp.type.' .. ty] = { link = '@type' } + res['@lsp.typemod.' .. ty .. '.definition'] = { link = '@type.definition' } + res['@lsp.typemod.' .. ty .. '.defaultLibrary'] = { link = '@type.builtin' } + + res['@lsp.typemod.' .. ty .. '.deprecated'] = { fg = theme.syntax.deprecated } + end + + return res +end + +return M diff --git a/lua/coral/highlights/nvim.lua b/lua/coral/highlights/nvim.lua new file mode 100644 index 0000000..5cf7a20 --- /dev/null +++ b/lua/coral/highlights/nvim.lua @@ -0,0 +1,114 @@ +local M = {} + +function M.setup(theme, _config) + return { + Normal = { bg = theme.ui.bg1, fg = theme.ui.fg2 }, + Title = { fg = theme.ui.fg4 }, + Whitespace = { fg = theme.ui.fg0 }, + + Identifier = { link = '@type' }, + Function = { link = '@function.call' }, + Type = { link = '@type' }, + Variable = { link = '@variable' }, + Statement = { link = '@keyword' }, + Special = { fg = theme.keyword_special }, + Keyword = { link = '@keyword' }, + Conditional = { link = '@keyword' }, + Repeat = { link = '@keyword' }, + Label = { link = 'Special' }, + Exception = { link = 'Special' }, + PreProc = { link = '@keyword' }, + + Constant = { link = '@constant' }, + String = { link = '@string' }, + Character = { link = '@string' }, + Number = { link = '@number' }, + Boolean = { link = '@boolean' }, + Float = { link = '@number.float' }, + + Quote = { link = '@string' }, + Operator = { link = '@punctuation' }, + Delimiter = { link = '@punctuation' }, + MatchParen = { link = '@punctuation' }, + + Todo = { link = '@comment.todo' }, + Question = { link = '@comment.note' }, + Comment = { link = '@comment' }, + SpecialComment = { link = '@comment' }, + + + NonText = { fg = theme.ui.fg3 }, + + SignColumn = { bg = theme.ui.bg0, fg = theme.ui.fg1 }, + ColorColumn = { bg = theme.ui.bg2 }, + + CursorLine = { bg = theme.ui.bg2 }, + CursorColumn = { link = 'CursorLine' }, + + LineNr = { fg = theme.ui.fg0 }, + CursorLineNr = { fg = theme.ui.fg4 }, + + Cursor = { fg = theme.ui.bg0, bg = theme.ui.fg0 }, + lCursor = { link = 'Cursor' }, + CursorIM = { link = 'Cursor' }, + + Search = { fg = theme.search.fg, bg = theme.search.item }, + CurSearch = { fg = theme.search.fg, bg = theme.search.current }, + IncSearch = { link = 'CurSearch' }, + Substitute = { link = 'Search' }, + + DiffAdd = { fg = theme.diff.add }, + DiffDelete = { fg = theme.diff.remove }, + DiffChange = { fg = theme.diff.change }, + DiffText = { fg = theme.diff.change }, + + diffAdded = { link = 'DiffAdd' }, + diffRemoved = { link = 'DiffDelete' }, + diffChanged = { link = 'DiffChange' }, + diffOldFile = { link = 'DiffDelete' }, + diffNewFile = { link = 'DiffAdd' }, + + Error = { fg = theme.diagnostic.error }, + ModeMsg = { fg = theme.diagnostic.info }, + MoreMsg = { fg = theme.diagnostic.info }, + MsgArea = { fg = theme.diagnostic.info }, + ErrorMsg = { fg = theme.diagnostic.error }, + WarningMsg = { fg = theme.diagnostic.warn }, + NvimInternalError = { fg = theme.diagnostic.error }, + healthError = { fg = theme.diagnostic.error }, + healthSuccess = { fg = theme.diagnostic.ok }, + healthWarning = { fg = theme.diagnostic.warn }, + + StatusLine = { fg = theme.ui.fg3, bg = theme.ui.bg2 }, + StatusLineNC = { fg = theme.ui.fg2, bg = theme.ui.bg1 }, + + SpellBad = { undercurl = true, sp = theme.diagnostic.error }, + SpellCap = { undercurl = true, sp = theme.diagnostic.warn }, + SpellLocal = { undercurl = true, sp = theme.diagnostic.warn }, + SpellRare = { undercurl = true, sp = theme.diagnostic.warn }, + + DiagnosticError = { fg = theme.diagnostic.error }, + DiagnosticWarn = { fg = theme.diagnostic.warn }, + DiagnosticInfo = { fg = theme.diagnostic.info }, + DiagnosticHint = { fg = theme.diagnostic.info }, + DiagnosticOk = { fg = theme.diagnostic.ok }, + + DiagnosticVirtualTextError = { link = 'DiagnosticError' }, + DiagnosticVirtualTextWarn = { link = 'DiagnosticWarn' }, + DiagnosticVirtualTextInfo = { link = 'DiagnosticInfo' }, + DiagnosticVirtualTextHint = { link = 'DiagnosticHint' }, + + DiagnosticFloatingError = { link = 'DiagnosticError' }, + DiagnosticFloatingWarn = { link = 'DiagnosticWarn' }, + DiagnosticFloatingInfo = { link = 'DiagnosticInfo' }, + DiagnositcFloatingHint = { link = 'DiagnosicHint' }, + DiagnosticFloatingOk = { link = 'DiagnosticOk' }, + + DiagnositcSignError = { fg = theme.diagnostic.error }, + DiagnosticSignWarn = { fg = theme.diagnostic.warn }, + DiagnosticSignInfo = { fg = theme.diagnostic.info }, + DiagnosticSignHint = { fg = theme.diagnostic.info }, + } +end + +return M diff --git a/lua/coral/highlights/plugins.lua b/lua/coral/highlights/plugins.lua new file mode 100644 index 0000000..3bb22b6 --- /dev/null +++ b/lua/coral/highlights/plugins.lua @@ -0,0 +1,12 @@ +local M = {} + +function M.setup(theme) + return { + -- GitSigns + GitSignsAdd = { fg = theme.diff.add }, + GitSignsChange = { fg = theme.diff.change }, + GitSignsDelete = { fg = theme.diff.remove }, + } +end + +return M diff --git a/lua/coral/highlights/treesitter.lua b/lua/coral/highlights/treesitter.lua new file mode 100644 index 0000000..21e7b19 --- /dev/null +++ b/lua/coral/highlights/treesitter.lua @@ -0,0 +1,92 @@ +local M = {} + +function M.setup(theme, config) + config = config or {} + + local syntax = theme.syntax + local diff = theme.diff + + return { + ['@variable'] = { fg = syntax.variable }, + ['@variable.builtin'] = { fg = syntax.builtin }, + ['@variable.parameter'] = { fg = syntax.parameter }, + ['@variable.parameter.builtin'] = { link = '@variable.builtin' }, + ['@variable.member'] = { fg = syntax.property }, + + ['@constant'] = { fg = syntax.constant }, + ['@constant.builtin'] = { fg = syntax.builtin }, + ['@constant.macro'] = { fg = syntax.macro }, + + ['@module'] = { fg = syntax.module }, + ['@module.builtin'] = { link = '@module' }, + + ['@label'] = { fg = syntax.keyword_special }, + + ['@string'] = { fg = syntax.string }, + ['@string.documentation'] = { fg = syntax.string_special }, + ['@string.escape'] = { fg = syntax.string_special }, + ['@string.regexp'] = { fg = syntax.string_special }, + ['@string.special'] = { fg = syntax.string_special }, + + ['@character'] = { fg = syntax.string }, + ['@character.special'] = { fg = syntax.string_special }, + + ['@boolean'] = { fg = syntax.primitive }, + ['@number'] = { fg = syntax.primitive }, + ['@number.float'] = { link = '@number' }, + + ['@type'] = { fg = syntax.type }, + ['@type.builtin'] = { fg = syntax.builtin_type }, + ['@type.definition'] = { fg = syntax.type_definition }, + + ['@property'] = { fg = syntax.property }, + + ['@attribute'] = { fg = syntax.property }, + ['@attribute.builtin'] = { link = '@attribute' }, + + ['@function'] = { fg = syntax.function_definition }, + ['@function.builtin'] = { fg = syntax.builtin }, + ['@function.call'] = { fg = syntax.function_call }, + ['@function.macro'] = { fg = syntax.macro }, + ['@function.method'] = { link = '@function' }, + ['@function.method.call'] = { link = '@function.call' }, + + ['@constructor'] = { fg = syntax.function_definition }, + + ['@operator'] = { fg = syntax.punctuation }, + + ['@keyword'] = { fg = syntax.keyword }, + ['@keyword.return'] = { fg = syntax.keyword_special }, + ['@keyword.exception'] = { fg = syntax.keyword_special }, + ['@keyword.debug'] = { fg = syntax.keyword_special }, + ['@keyword.directive'] = { fg = syntax.keyword_special }, + ['@keyword.directive.define'] = { link = '@keyword.directive' }, + + ['@punctuation'] = { fg = syntax.punctuation }, + ['@punctuation.delimiter'] = { link = '@punctuation' }, + ['@punctuation.bracket'] = { link = '@punctuation' }, + ['@punctuation.special'] = { link = '@punctuation' }, + + ['@comment'] = { fg = syntax.comment }, + ['@comment.documentation'] = { fg = syntax.comment }, + + ['@comment.error'] = { fg = syntax.comment_error }, + ['@comment.warning'] = { fg = syntax.comment_warn }, + ['@comment.todo'] = { fg = syntax.comment_todo }, + ['@comment.note'] = { fg = syntax.comment_note }, + + -- TODO: More complete markup support + ['@markup'] = {}, + + ['@diff.plus'] = { fg = diff.add }, + ['@diff.minus'] = { fg = diff.remove }, + ['@diff.delta'] = { fg = diff.change }, + + ['@tag'] = { fg = syntax.type }, + ['@tag.builtin'] = { fg = syntax.builtin }, + ['@tag.attribute'] = { fg = syntax.property }, + ['@tag.delimiter'] = { fg = syntax.punctuation } + } +end + +return M; diff --git a/lua/coral/init.lua b/lua/coral/init.lua new file mode 100644 index 0000000..6347955 --- /dev/null +++ b/lua/coral/init.lua @@ -0,0 +1,23 @@ +local M = {} + +M.config = { + undercurl = true, + commentStyle = { italic = true } +} + +M.load = function() + if vim.g.colors_name then + vim.cmd('hi clear') + end + + vim.g.colors_name = 'coral' + vim.o.termguicolors = true + + local colors = require('coral.colors').setup(M.config) + local theme = require('coral.themes').setup(colors, M.config) + local highlights = require('coral.highlights').setup(theme, M.config) + + require('coral.highlights').apply(highlights) +end + +return M diff --git a/lua/coral/themes.lua b/lua/coral/themes.lua new file mode 100644 index 0000000..856ecbf --- /dev/null +++ b/lua/coral/themes.lua @@ -0,0 +1,80 @@ +local M = {} + +function M.setup(color, config) + config = config or {} + + local theme = {} + + theme.syntax = { + builtin = color.blue0, + variable = color.gray2, + parameter = color.gray4, + constant = color.blue1, + macro = color.coral2, + module = color.blue2, + primitive = color.blue1, + punctuation = color.gray1, + comment = color.gray0, + + type = color.blue1, + type_definition = color.blue1, + builtin_type = color.blue0, + + property = color.gray3, + + string = color.coral1, + string_special = color.coral2, + + function_definition = color.coral2, + function_call = color.coral2, + + keyword = color.coral0, + -- Used for important control flow: return, throw, labels + keyword_special = color.special, + + deprecated = color.gray1, + + -- Used for FIXME/TODO/NOTE comments + comment_error = color.red, + comment_warn = color.orange, + comment_todo = color.yellow, + comment_note = color.blue2, + } + + theme.diff = { + add = color.green, + remove = color.red, + change = color.orange + } + + theme.ui = { + bg0 = color.bg0, + bg1 = color.bg1, + bg2 = color.bg2, + + fg0 = color.gray0, + fg1 = color.gray1, + fg2 = color.gray2, + fg3 = color.gray3, + fg4 = color.gray4 + } + + theme.search = { + fg = color.gray0, + item = color.coral0, + current = color.coral2 + } + + theme.diagnostic = { + error = color.red, + warn = color.yellow, + info = color.blue2, + ok = color.green + } + + theme.special = color.special + + return theme +end + +return M