commit 62e9c5d669567d086474b2b6863e0724c71c6c99 Author: Webhooked Date: Tue May 6 12:02:29 2025 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..124d5ef --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +images/ +.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e7f4bc7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Webhooked + +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..85bb9f4 --- /dev/null +++ b/README.md @@ -0,0 +1,285 @@ +
+

🌊 Kansō.nvim 🌊

+
+ +
+

+ Kansō is an elegant evolution of the original Kanagawa theme. +
+ A dark theme that invites focus, not attention. +

+
+ +
+ +[![Neovim](https://img.shields.io/badge/NeoVim-%2357A143.svg?&style=for-the-badge&logo=neovim&logoColor=white)](https://neovim.io/) +[![W3C](https://img.shields.io/badge/WCAG_2.1_|_AA-756891?logo=w3c&logoColor=fff&style=for-the-badge)](https://www.w3.org/TR/WCAG21/#contrast-minimum) + + +
+ +
+ +
+ +
+ +## ✨ Features + +- 🌈 Extensive support for `TreeSitter` syntax highlighting +- 🔌 Compatible with popular plugins out of the box +- ⚡ Compilation to lua byte code for fast startup times +- 🎨 Three beautiful theme variants to match your mood and environment +- 👁️ WCAG 2.1 AA compliant + +## 📦 Installation + +Download with your favorite package manager. + +```lua +-- Using Packer +use "webhooked/kanso.nvim" + +-- Using Lazy +{ + "webhooked/kanso.nvim", + lazy = false, + priority = 1000, +} +``` + +## 📋 Requirements + +- Terminal with truecolor support +- Terminal with undercurl support (optional) + +## 🚀 Usage + +As simple as writing: + +```vim +colorscheme kanso +``` + +Or in Lua: + +```lua +vim.cmd("colorscheme kanso") +``` + +## ⚙️ Configuration + +There is no need to call setup if you are ok with the defaults. + +```lua +-- Default options: +require('kanso').setup({ + compile = false, -- enable compiling the colorscheme + undercurl = true, -- enable undercurls + commentStyle = { italic = true }, + functionStyle = {}, + keywordStyle = { italic = true}, + statementStyle = {}, + typeStyle = {}, + transparent = false, -- do not set background color + dimInactive = false, -- dim inactive window `:h hl-NormalNC` + terminalColors = true, -- define vim.g.terminal_color_{0,17} + colors = { -- add/modify theme and palette colors + palette = {}, + theme = { zen = {}, pearl = {}, ink = {}, all = {} }, + }, + overrides = function(colors) -- add/modify highlights + return {} + end, + theme = "zen", -- Load "zen" theme + background = { -- map the value of 'background' option to a theme + dark = "zen", -- try "ink" ! + light = "pearl" + }, +}) + +-- setup must be called before loading +vim.cmd("colorscheme kanso") +``` + +
+💡 Important Notes + +**Compilation:** If you enable compilation, make sure to run `:KansōCompile` command every time you make changes to your config. + +```vim +" 1. Modify your config +" 2. Restart nvim +" 3. Run this command: +:KansōCompile +``` + +**Options:** Kansō adjusts to the value of some options. Make sure that the options `'laststatus'` and `'cmdheight'` are set **_before_** calling `setup`. + +
+ +## 🎨 Themes + +Kansō comes in three beautiful variants: + +- `Zen` (Dark) +- `Ink` (Dark) +- `Pearl` (Light) + +
+

✧ Zen ✧

+

Deep & rich dark theme for focused coding.

+ +

+ +

✧ Ink ✧

+

Balanced theme with elegant contrast.

+ +

+ +

✧ Pearl ✧

+

Light theme for daytime productivity.

+ +
+ +
+ +
+🔄 Switching Between Themes + +Themes can be changed in three ways: + +1. Setting `config.theme` to the desired theme. +2. Using the `background` option: + Any change to the value of `vim.o.background` will select the theme mapped by `config.background`. +3. Loading the colorscheme directly with: + +```lua +vim.cmd("colorscheme kanso-zen") +vim.cmd("colorscheme kanso-kage") +vim.cmd("colorscheme kanso-pearl") +``` + +or + +```lua +require("kanso").load("zen") +``` + +
+ +## 🧰 Customization + +In Kansō, there are _two_ kinds of colors: `PaletteColors` and `ThemeColors`; +`PaletteColors` are defined directly as RGB Hex strings, and have arbitrary names +that recall their actual color. Conversely, `ThemeColors` are named and grouped _semantically_ +on the basis of their actual function. + +In short, a `palette` defines all the available colors, while a `theme` maps the `PaletteColors` +to specific `ThemeColors` and the same palette color may be assigned to multiple theme colors. + +
+📝 Color Customization Example + +You can change _both_ theme or palette colors using `config.colors`. +All the palette color names can be found [here](lua/kanso/colors.lua), +while their usage by each theme can be found [here](lua/kanso/themes.lua). + +```lua +require('kanso').setup({ + ..., + colors = { + palette = { + -- change all usages of these colors + zen0 = "#000000", + fujiWhite = "#FFFFFF", + }, + theme = { + -- change specific usages for a certain theme, or for all of them + zen = { + ui = { + float = { + bg = "none", + }, + }, + }, + ink = { + syn = { + parameter = "yellow", + }, + }, + all = { + ui = { + bg_gutter = "none" + } + } + } + }, + ... +}) +``` + +
+ +
+🔧 Highlight Group Overrides + +You can also conveniently add/modify any `hlgroups` using the `config.overrides` option, allowing you to customize the looks of specific built-in elements, or any other external plugins that provides `hlgroups`. (See `:help highlight` for more information on `hlgroups`.) +Supported keywords are the same for `:h nvim_set_hl` `{val}` parameter. + +```lua +require('kanso').setup({ + ..., + overrides = function(colors) + return { + -- Assign a static color to strings + String = { fg = colors.palette.carpYellow, italic = true }, + -- theme colors will update dynamically when you change theme! + SomePluginHl = { fg = colors.theme.syn.type, bold = true }, + } + end, + ... +}) +``` + +
+ +## 🔄 Integration + +### Get palette and theme colors + +```lua +-- Get the colors for the current theme +local colors = require("kanso.colors").setup() +local palette_colors = colors.palette +local theme_colors = colors.theme + +-- Get the colors for a specific theme +local zen_colors = require("kanso.colors").setup({ theme = 'ink' }) +``` + +## 🧩 Extras + +
+ +- [Alacritty](extras/alacritty/) +- [Kitty](extras/kitty/) +- [Ghostty](extras/ghostty) +- [Wezterm](extras/wezterm/) +- [Kansō for VS Code](https://marketplace.visualstudio.com/items?itemName=webhooked.kanso-vscode) +- [Kansō for Zed](https://github.com/webhooked/kanso-zed) + +
+ +## 💎 Credits + +The theme is inspired by the Kanagawa theme. + +- [rebelot](https://github.com/rebelot/kanagawa.nvim) for the original Kanagawa Neovim theme + +## 🙏 Acknowledgements + +- [Kanagawa](https://github.com/rebelot/kanagawa.nvim) +- [Tokyonight](https://github.com/folke/tokyonight.nvim) +- [Gruvbox](https://github.com/morhetz/gruvbox) +- [Catppuccin](https://github.com/catppuccin/nvim) diff --git a/colors/kanso-ink.vim b/colors/kanso-ink.vim new file mode 100644 index 0000000..ddee091 --- /dev/null +++ b/colors/kanso-ink.vim @@ -0,0 +1 @@ +lua require("kanso").load "ink" diff --git a/colors/kanso-pearl.vim b/colors/kanso-pearl.vim new file mode 100644 index 0000000..1161499 --- /dev/null +++ b/colors/kanso-pearl.vim @@ -0,0 +1 @@ +lua require("kanso").load "pearl" diff --git a/colors/kanso-zen.vim b/colors/kanso-zen.vim new file mode 100644 index 0000000..c679302 --- /dev/null +++ b/colors/kanso-zen.vim @@ -0,0 +1 @@ +lua require("kanso").load "zen" diff --git a/colors/kanso.vim b/colors/kanso.vim new file mode 100644 index 0000000..c52409c --- /dev/null +++ b/colors/kanso.vim @@ -0,0 +1 @@ +lua require('kanso').load() diff --git a/extras/alacritty/kanso_ink.toml b/extras/alacritty/kanso_ink.toml new file mode 100644 index 0000000..7045ac8 --- /dev/null +++ b/extras/alacritty/kanso_ink.toml @@ -0,0 +1,37 @@ +# Kanso Ink Alacritty Colors + +[colors.primary] +background = '#14171d' +foreground = '#C5C9C7' + +[colors.normal] +black = '#14171d' +red = '#c4746e' +green = '#8a9a7b' +yellow = '#c4b28a' +blue = '#8ba4b0' +magenta = '#a292a3' +cyan = '#8ea4a2' +white = '#c8c093' + +[colors.bright] +black = '#A4A7A4' +red = '#e46876' +green = '#87a987' +yellow = '#e6c384' +blue = '#7fb4ca' +magenta = '#938aa9' +cyan = '#7aa89f' +white = '#C5C9C7' + +[colors.selection] +background = '#393B42' +foreground = '#C5C9C7' + +[[colors.indexed_colors]] +index = 16 +color = '#b6927b' + +[[colors.indexed_colors]] +index = 17 +color = '#b98d7b' diff --git a/extras/alacritty/kanso_pearl.toml b/extras/alacritty/kanso_pearl.toml new file mode 100644 index 0000000..f32ef50 --- /dev/null +++ b/extras/alacritty/kanso_pearl.toml @@ -0,0 +1,37 @@ +# Kanso Pearl Alacritty Colors + +[colors.primary] +background = '#f2f1ef' +foreground = '#545464' + +[colors.normal] +black = "#14171d" +red = "#c84053" +green = "#6f894e" +yellow = "#77713f" +blue = "#4d699b" +magenta = "#b35b79" +cyan = "#597b75" +white = "#545464" + +[colors.bright] +black = "#8a8980" +red = "#d7474b" +green = "#6e915f" +yellow = "#836f4a" +blue = "#6693bf" +magenta = "#624c83" +cyan = "#5e857a" +white = "#43436c" + +[colors.selection] +background = '#c9cbd1' +foreground = '#14171d' + +[[colors.indexed_colors]] +index = 16 +color = '#e98a00' + +[[colors.indexed_colors]] +index = 17 +color = '#e82424' diff --git a/extras/alacritty/kanso_zen.toml b/extras/alacritty/kanso_zen.toml new file mode 100644 index 0000000..7268535 --- /dev/null +++ b/extras/alacritty/kanso_zen.toml @@ -0,0 +1,37 @@ +# Kanso Zen Alacritty Colors + +[colors.primary] +background = '#090E13' +foreground = '#C5C9C7' + +[colors.normal] +black = '#090E13' +red = '#c4746e' +green = '#8a9a7b' +yellow = '#c4b28a' +blue = '#8ba4b0' +magenta = '#a292a3' +cyan = '#8ea4a2' +white = '#c8c093' + +[colors.bright] +black = '#A4A7A4' +red = '#e46876' +green = '#87a987' +yellow = '#e6c384' +blue = '#7fb4ca' +magenta = '#938aa9' +cyan = '#7aa89f' +white = '#C5C9C7' + +[colors.selection] +background = '#393B42' +foreground = '#C5C9C7' + +[[colors.indexed_colors]] +index = 16 +color = '#b6927b' + +[[colors.indexed_colors]] +index = 17 +color = '#b98d7b' diff --git a/extras/ghostty/kanso-ink b/extras/ghostty/kanso-ink new file mode 100644 index 0000000..4a20d4a --- /dev/null +++ b/extras/ghostty/kanso-ink @@ -0,0 +1,22 @@ +palette = 0=#14171d +palette = 1=#c4746e +palette = 2=#8a9a7b +palette = 3=#c4b28a +palette = 4=#8ba4b0 +palette = 5=#a292a3 +palette = 6=#8ea4a2 +palette = 7=#c8c093 +palette = 8=#a4a7a4 +palette = 9=#e46876 +palette = 10=#87a987 +palette = 11=#e6c384 +palette = 12=#7fb4ca +palette = 13=#938aa9 +palette = 14=#7aa89f +palette = 15=#c5c9c7 + +background = #14171d +foreground = #c5c9c7 +cursor-color = #c5c9c7 +selection-background = #393B42 +selection-foreground = #c5c9c7 diff --git a/extras/ghostty/kanso-pearl b/extras/ghostty/kanso-pearl new file mode 100644 index 0000000..9d77ff2 --- /dev/null +++ b/extras/ghostty/kanso-pearl @@ -0,0 +1,22 @@ +palette = 0=#24262D +palette = 1=#c84053 +palette = 2=#6f894e +palette = 3=#77713f +palette = 4=#4d699b +palette = 5=#b35b79 +palette = 6=#597b75 +palette = 7=#545464 +palette = 8=#6d6f6e +palette = 9=#d7474b +palette = 10=#6e915f +palette = 11=#836f4a +palette = 12=#6693bf +palette = 13=#624c83 +palette = 14=#5e857a +palette = 15=#43436c + +background = #f2f1ef +foreground = #24262D +cursor-color = #24262D +selection-background = #e2e1df +selection-foreground = #24262D diff --git a/extras/ghostty/kanso-zen b/extras/ghostty/kanso-zen new file mode 100644 index 0000000..48555d8 --- /dev/null +++ b/extras/ghostty/kanso-zen @@ -0,0 +1,22 @@ +palette = 0=#090E13 +palette = 1=#c4746e +palette = 2=#8a9a7b +palette = 3=#c4b28a +palette = 4=#8ba4b0 +palette = 5=#a292a3 +palette = 6=#8ea4a2 +palette = 7=#c8c093 +palette = 8=#a4a7a4 +palette = 9=#e46876 +palette = 10=#87a987 +palette = 11=#e6c384 +palette = 12=#7fb4ca +palette = 13=#938aa9 +palette = 14=#7aa89f +palette = 15=#c5c9c7 + +background = #090E13 +foreground = #c5c9c7 +cursor-color = #c5c9c7 +selection-background = #24262D +selection-foreground = #c5c9c7 diff --git a/extras/kitty/kanso_ink.conf b/extras/kitty/kanso_ink.conf new file mode 100644 index 0000000..ac85d6b --- /dev/null +++ b/extras/kitty/kanso_ink.conf @@ -0,0 +1,39 @@ +background #14171d +foreground #C5C9C7 +selection_background #24262D +selection_foreground #C5C9C7 +url_color #72A7BC +cursor #C5C9C7 +cursor_text_color #14171d + +# Tabs +active_tab_background #14171d +active_tab_foreground #C5C9C7 +inactive_tab_background #14171d +inactive_tab_foreground #A4A7A4 + +# normal +color0 #14171d +color1 #c4746e +color2 #8a9a7b +color3 #c4b28a +color4 #8ba4b0 +color5 #a292a3 +color6 #8ea4a2 +color7 #C8C093 + +# bright +color8 #A4A7A4 +color9 #E46876 +color10 #87a987 +color11 #E6C384 +color12 #7FB4CA +color13 #938AA9 +color14 #7AA89F +color15 #C5C9C7 + + +# extended colors +color16 #b6927b +color17 #b98d7b + diff --git a/extras/kitty/kanso_pearl.conf b/extras/kitty/kanso_pearl.conf new file mode 100644 index 0000000..0cb077c --- /dev/null +++ b/extras/kitty/kanso_pearl.conf @@ -0,0 +1,38 @@ +background #f2f1ef +foreground #24262D +selection_background #e2e1df +selection_foreground #24262D +url_color #73A7BC +cursor #24262D +cursor_text_color #f2f1ef + +# Tabs +active_tab_background #f2f1ef +active_tab_foreground #24262D +inactive_tab_background #f2f1ef +inactive_tab_foreground #6d6f6e + +# normal +color0 #24262D +color1 #c84053 +color2 #6f894e +color3 #77713f +color4 #4d699b +color5 #b35b79 +color6 #597b75 +color7 #545464 + +# bright +color8 #6d6f6e +color9 #d7474b +color10 #6e915f +color11 #836f4a +color12 #6693bf +color13 #624c83 +color14 #5e857a +color15 #43436c + + +# extended colors +color16 #cc6d00 +color17 #e82424 diff --git a/extras/kitty/kanso_zen.conf b/extras/kitty/kanso_zen.conf new file mode 100644 index 0000000..d73152d --- /dev/null +++ b/extras/kitty/kanso_zen.conf @@ -0,0 +1,39 @@ +background #090E13 +foreground #C5C9C7 +selection_background #393B42 +selection_foreground #C5C9C7 +url_color #72A7BC +cursor #C5C9C7 +cursor_text_color #090E13 + +# Tabs +active_tab_background #090E13 +active_tab_foreground #C5C9C7 +inactive_tab_background #090E13 +inactive_tab_foreground #A4A7A4 + +# normal +color0 #0d0c0c +color1 #c4746e +color2 #8a9a7b +color3 #c4b28a +color4 #8ba4b0 +color5 #a292a3 +color6 #8ea4a2 +color7 #C8C093 + +# bright +color8 #A4A7A4 +color9 #E46876 +color10 #87a987 +color11 #E6C384 +color12 #7FB4CA +color13 #938AA9 +color14 #7AA89F +color15 #C5C9C7 + + +# extended colors +color16 #b6927b +color17 #b98d7b + diff --git a/extras/wezterm/kanso-ink.lua b/extras/wezterm/kanso-ink.lua new file mode 100644 index 0000000..7f96609 --- /dev/null +++ b/extras/wezterm/kanso-ink.lua @@ -0,0 +1,40 @@ +local config = { + force_reverse_video_cursor = true, + colors = { + foreground = "#C5C9C7", + background = "#14171d", + + cursor_bg = "#14171d", + cursor_fg = "#C5C9C7", + cursor_border = "#C5C9C7", + + selection_fg = "#C5C9C7", + selection_bg = "#393B42", + + scrollbar_thumb = "#393B42", + split = "#393B42", + + ansi = { + "#14171d", + "#C4746E", + "#8A9A7B", + "#C4B28A", + "#8BA4B0", + "#A292A3", + "#8EA4A2", + "#A4A7A4", + }, + brights = { + "#A4A7A4", + "#E46876", + "#87A987", + "#E6C384", + "#7FB4CA", + "#938AA9", + "#7AA89F", + "#C5C9C7", + }, + }, +} + +return config diff --git a/extras/wezterm/kanso-zen.lua b/extras/wezterm/kanso-zen.lua new file mode 100644 index 0000000..9d48255 --- /dev/null +++ b/extras/wezterm/kanso-zen.lua @@ -0,0 +1,40 @@ +local config = { + force_reverse_video_cursor = true, + colors = { + foreground = "#C5C9C7", + background = "#090E13", + + cursor_bg = "#090E13", + cursor_fg = "#C5C9C7", + cursor_border = "#C5C9C7", + + selection_fg = "#C5C9C7", + selection_bg = "#24262D", + + scrollbar_thumb = "#24262D", + split = "#24262D", + + ansi = { + "#090E13", + "#C4746E", + "#8A9A7B", + "#C4B28A", + "#8BA4B0", + "#A292A3", + "#8EA4A2", + "#A4A7A4", + }, + brights = { + "#A4A7A4", + "#E46876", + "#87A987", + "#E6C384", + "#7FB4CA", + "#938AA9", + "#7AA89F", + "#C5C9C7", + }, + }, +} + +return config diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..e808bb7 Binary files /dev/null and b/icon.png differ diff --git a/kanso.png b/kanso.png new file mode 100644 index 0000000..0fa0f13 Binary files /dev/null and b/kanso.png differ diff --git a/kanso_ink.png b/kanso_ink.png new file mode 100644 index 0000000..e7747e3 Binary files /dev/null and b/kanso_ink.png differ diff --git a/kanso_pearl.png b/kanso_pearl.png new file mode 100644 index 0000000..d9cd716 Binary files /dev/null and b/kanso_pearl.png differ diff --git a/kanso_zen.png b/kanso_zen.png new file mode 100644 index 0000000..aa583d1 Binary files /dev/null and b/kanso_zen.png differ diff --git a/lua/kanso/colors.lua b/lua/kanso/colors.lua new file mode 100644 index 0000000..3fd15b4 --- /dev/null +++ b/lua/kanso/colors.lua @@ -0,0 +1,155 @@ +---@class PaletteColors +local palette = { + + -- Bg Shades + zen0 = "#090E13", + zen1 = "#1C1E25", + zen2 = "#24262D", + zen3 = "#393B42", + + -- Popup and Floats + zenBlue1 = "#223249", + zenBlue2 = "#2D4F67", + + -- Diff and Git + winterGreen = "#2B3328", + winterYellow = "#49443C", + winterRed = "#43242B", + winterBlue = "#252535", + autumnGreen = "#76946A", + autumnRed = "#C34043", + autumnYellow = "#DCA561", + + -- Diag + samuraiRed = "#E82424", + roninYellow = "#FF9E3B", + zenAqua1 = "#6A9589", + inkBlue = "#658594", + + -- Fg and Comments + oldWhite = "#C5C9C7", + fujiWhite = "#f2f1ef", + fujiGray = "#727169", + + oniViolet = "#957FB8", + oniViolet2 = "#b8b4d0", + crystalBlue = "#7E9CD8", + springViolet1 = "#938AA9", + springViolet2 = "#9CABCA", + springBlue = "#7FB4CA", + lightBlue = "#A3D4D5", + zenAqua2 = "#7AA89F", + + springGreen = "#98BB6C", + boatYellow1 = "#938056", + boatYellow2 = "#C0A36E", + carpYellow = "#E6C384", + + sakuraPink = "#D27E99", + zenRed = "#E46876", + peachRed = "#FF5D62", + surimiOrange = "#FFA066", + katanaGray = "#717C7C", + + inkBlack0 = "#14171d", + inkBlack1 = "#1f1f26", + inkBlack2 = "#24262D", + inkBlack3 = "#393B42", + + inkWhite = "#C5C9C7", + inkGreen = "#87a987", + inkGreen2 = "#8a9a7b", + inkPink = "#a292a3", + inkOrange = "#b6927b", + inkOrange2 = "#b98d7b", + inkGray = "#A4A7A4", + inkGray1 = "#9E9B93", + inkGray2 = "#75797f", + inkGray3 = "#5C6066", + inkBlue2 = "#8ba4b0", + inkViolet= "#8992a7", + inkRed = "#c4746e", + inkAqua = "#8ea4a2", + inkAsh = "#5C6068", + inkTeal = "#949fb5", + inkYellow = "#c4b28a",--"#a99c8b", + -- "#8a9aa3", + + pearlInk0 = "#24262D", + pearlInk1 = "#545464", + pearlInk2 = "#43436c", + pearlGray = "#e2e1df", + pearlGray2 = "#5C6068", + pearlGray3 = "#6D6D69", + pearlGray4 = "#9F9F99", + + pearlWhite0 = "#f2f1ef", + pearlWhite1 = "#e2e1df", + pearlWhite2 = "#dddddb", + pearlViolet1 = "#a09cac", + pearlViolet2 = "#766b90", + pearlViolet3 = "#c9cbd1", + pearlViolet4 = "#624c83", + pearlBlue1 = "#c7d7e0", + pearlBlue2 = "#b5cbd2", + pearlBlue3 = "#9fb5c9", + pearlBlue4 = "#4d699b", + pearlBlue5 = "#5d57a3", + pearlGreen = "#6f894e", + pearlGreen2 = "#6e915f", + pearlGreen3 = "#b7d0ae", + pearlPink = "#b35b79", + pearlOrange = "#cc6d00", + pearlOrange2 = "#e98a00", + pearlYellow ="#77713f", + pearlYellow2 = "#836f4a", + pearlYellow3 = "#de9800", + pearlYellow4 = "#f9d791", + pearlRed = "#c84053", + pearlRed2 = "#d7474b", + pearlRed3 = "#e82424", + pearlRed4 = "#d9a594", + pearlAqua = "#597b75", + pearlAqua2 = "#5e857a", + pearlTeal1 = "#4e8ca2", + pearlTeal2 = "#6693bf", + pearlTeal3 = "#5a7785", + pearlCyan = "#d7e3d8", +} + +local M = {} +--- Generate colors table: +--- * opts: +--- - colors: Table of personalized colors and/or overrides of existing ones. +--- Defaults to KansoConfig.colors. +--- - theme: Use selected theme. Defaults to KansoConfig.theme +--- according to the value of 'background' option. +---@param opts? { colors?: table, theme?: string } +---@return { theme: ThemeColors, palette: PaletteColors} +function M.setup(opts) + opts = opts or {} + local override_colors = opts.colors or require("kanso").config.colors + local theme = opts.theme or require("kanso")._CURRENT_THEME -- WARN: this fails if called before kanso.load() + + if not theme then + error("kanso.colors.setup(): Unable to infer `theme`. Either specify a theme or call this function after ':colorscheme kanso'") + end + + -- Add to and/or override palette_colors + local updated_palette_colors = vim.tbl_extend("force", palette, override_colors.palette or {}) + + -- Generate the theme according to the updated palette colors + local theme_colors = require("kanso.themes")[theme](updated_palette_colors) + + -- Add to and/or override theme_colors + local theme_overrides = vim.tbl_deep_extend("force", override_colors.theme["all"] or {}, override_colors.theme[theme] or {} ) + local updated_theme_colors = vim.tbl_deep_extend("force", theme_colors, theme_overrides) + -- return palette_colors AND theme_colors + + return { + theme = updated_theme_colors, + palette = updated_palette_colors, + } +end + +return M diff --git a/lua/kanso/highlights/editor.lua b/lua/kanso/highlights/editor.lua new file mode 100644 index 0000000..2788cd9 --- /dev/null +++ b/lua/kanso/highlights/editor.lua @@ -0,0 +1,201 @@ +-- local c = require("kanso.color") +local M = {} + +---@param colors KansoColors +---@param config? KansoConfig +function M.setup(colors, config) + local theme = colors.theme + config = config or require("kanso").config + + return { + -- ColorColumn Used for the columns set with 'colorcolumn'. + ColorColumn = { bg = theme.ui.bg_p1 }, + -- Conceal Placeholder characters substituted for concealed text (see 'conceallevel'). + Conceal = { fg = theme.ui.special, bold = true }, + -- CurSearch Used for highlighting a search pattern under the cursor (see 'hlsearch'). + CurSearch = { fg = theme.ui.fg, bg = theme.ui.bg_search, bold = true }, + -- Cursor Character under the cursor. + Cursor = { fg = theme.ui.cursor_fg, bg = theme.ui.cursor_bg }, + -- lCursor Character under the cursor when |language-mapping| is used (see 'guicursor'). + lCursor = { link = "Cursor" }, + -- CursorIM Like Cursor, but used when in IME mode. + CursorIM = { link = "Cursor" }, + -- CursorColumn Screen-column at the cursor, when 'cursorcolumn' is set. + CursorColumn = { link = "CursorLine" }, + -- CursorLine Screen-line at the cursor, when 'cursorline' is set. Low-priority if foreground (ctermfg OR guifg) is not set. + CursorLine = { bg = theme.ui.bg_p2 }, + -- Directory Directory names (and other special names in listings). + Directory = { fg = theme.syn.fun }, + -- DiffAdd Diff mode: Added line. |diff.txt| + DiffAdd = { bg = theme.diff.add }, + -- DiffChange Diff mode: Changed line. |diff.txt| + DiffChange = { bg = theme.diff.change }, + -- DiffDelete Diff mode: Deleted line. |diff.txt| + DiffDelete = { fg = theme.vcs.removed, bg = theme.diff.delete }, + -- DiffText Diff mode: Changed text within a changed line. |diff.txt| + DiffText = { bg = theme.diff.text }, + -- EndOfBuffer Filler lines (~) after the end of the buffer. By default, this is highlighted like |hl-NonText|. + EndOfBuffer = { fg = theme.ui.bg }, + -- TermCursor Cursor in a focused terminal. + -- TermCursorNC Cursor in an unfocused terminal. + -- ErrorMsg Error messages on the command line. + ErrorMsg = { fg = theme.diag.error }, + -- WinSeparator Separators between window splits. + WinSeparator = { fg = theme.ui.bg_m3, bg = config.dimInactive and theme.ui.bg_dim or "NONE" }, + VertSplit = { link = "WinSeparator" }, + -- Folded Line used for closed folds. + Folded = { fg = theme.ui.special, bg = theme.ui.bg_p1 }, + -- FoldColumn 'foldcolumn' + FoldColumn = { fg = theme.ui.nontext, bg = theme.ui.bg_gutter }, + -- SignColumn Column where |signs| are displayed. + SignColumn = { fg = theme.ui.special, bg = theme.ui.bg_gutter }, + -- IncSearch 'incsearch' highlighting; also used for the text replaced with ":s///c". + IncSearch = { fg = theme.ui.fg_reverse, bg = theme.diag.warning }, + -- Substitute |:substitute| replacement text highlighting. + Substitute = { fg = theme.ui.fg, bg = theme.vcs.removed }, + -- LineNr Line number for ":number" and ":#" commands, and when 'number' or 'relativenumber' option is set. + LineNr = { fg = theme.ui.cursor_line_nr_foreground, bg = theme.ui.none }, + -- LineNrAbove Line number for when the 'relativenumber' option is set, above the cursor line. + -- LineNrBelow Line number for when the 'relativenumber' option is set, below the cursor line. + -- CursorLineNr Like LineNr when 'cursorline' is set and 'cursorlineopt' contains "number" or is "both", for the cursor line. + CursorLineNr = { fg = theme.ui.cursor_line_nr_active_foreground, bg = theme.ui.none }, + -- CursorLineFold Like FoldColumn when 'cursorline' is set for the cursor line. + -- CursorLineSign Like SignColumn when 'cursorline' is set for the cursor line. + -- MatchParen Character under the cursor or just before it, if it is a paired bracket, and its match. |pi_paren.txt| + MatchParen = { fg = theme.diag.warning, bold = true }, + -- ModeMsg 'showmode' message (e.g., "-- INSERT --"). + ModeMsg = { fg = theme.diag.warning, bold = true }, + -- MsgArea Area for messages and cmdline. + MsgArea = vim.o.cmdheight == 0 and {link = 'StatusLine'} or { fg = theme.ui.fg_dim }, + -- MsgSeparator Separator for scrolled messages |msgsep|. + MsgSeparator = { bg = vim.o.cmdheight == 0 and theme.ui.bg or theme.ui.bg_m3 }, + -- MoreMsg |more-prompt| + MoreMsg = { fg = theme.diag.info }, + -- NonText '@' at the end of the window, characters from 'showbreak' and other characters that do not really exist in the text (e.g., ">" displayed when a double-wide character doesn't fit at the end of the line). See also |hl-EndOfBuffer|. + NonText = { fg = theme.ui.nontext }, + -- Normal Normal text. + Normal = { fg = theme.ui.fg, bg = not config.transparent and theme.ui.bg or "NONE" }, + -- NormalFloat Normal text in floating windows. + NormalFloat = { fg = theme.ui.float.fg, bg = theme.ui.float.bg }, + -- FloatBorder Border of floating windows. + FloatBorder = { fg = theme.ui.float.fg_border, bg = theme.ui.float.bg_border }, + -- FloatTitle Title of floating windows. + FloatTitle = { fg = theme.ui.special, bg = theme.ui.float.bg_border, bold = true }, + -- FloatFooter Footer of floating windows. + FloatFooter = { fg = theme.ui.nontext, bg = theme.ui.float.bg_border }, + -- NormalNC Normal text in non-current windows. + NormalNC = config.dimInactive and { fg = theme.ui.fg_dim, bg = theme.ui.bg_dim } or { link = "Normal" }, + -- Pmenu Popup menu: Normal item. + Pmenu = { fg = theme.ui.pmenu.fg, bg = theme.ui.pmenu.bg }, + -- PmenuSel Popup menu: Selected item. + PmenuSel = { fg = theme.ui.pmenu.fg_sel, bg = theme.ui.pmenu.bg_sel }, + -- PmenuKind Popup menu: Normal item "kind". + PmenuKind = { fg = theme.ui.fg_dim, bg = theme.ui.pmenu.bg }, + -- PmenuKindSel Popup menu: Selected item "kind". + PmenuKindSel = { fg = theme.ui.fg_dim, bg = theme.ui.pmenu.bg_sel }, + -- PmenuExtra Popup menu: Normal item "extra text". + PmenuExtra = { fg = theme.ui.special, bg = theme.ui.pmenu.bg }, + -- PmenuExtraSel Popup menu: Selected item "extra text". + PmenuExtraSel = { fg = theme.ui.special, bg = theme.ui.pmenu.bg_sel }, + -- PmenuSbar Popup menu: Scrollbar. + PmenuSbar = { bg = theme.ui.pmenu.bg_sbar }, + -- PmenuThumb Popup menu: Thumb of the scrollbar. + PmenuThumb = { bg = theme.ui.pmenu.bg_thumb }, + -- Question |hit-enter| prompt and yes/no questions. + Question = { link = "MoreMsg" }, + -- QuickFixLine Current |quickfix| item in the quickfix window. Combined with |hl-CursorLine| when the cursor is there. + QuickFixLine = { bg = theme.ui.bg_p1 }, + -- Search Last search pattern highlighting (see 'hlsearch'). Also used for similar items that need to stand out. + Search = { fg = theme.ui.fg, bg = theme.ui.bg_search }, + -- SpecialKey Unprintable characters: Text displayed differently from what it really is. But not 'listchars' whitespace. |hl-Whitespace| + SpecialKey = { fg = theme.ui.special }, + -- SpellBad Word that is not recognized by the spellchecker. |spell| Combined with the highlighting used otherwise. + SpellBad = { undercurl = config.undercurl, underline = not config.undercurl, sp = theme.diag.error }, + -- SpellCap Word that should start with a capital. |spell| Combined with the highlighting used otherwise. + SpellCap = { undercurl = config.undercurl, underline = not config.undercurl, sp = theme.diag.warning }, + -- SpellLocal Word that is recognized by the spellchecker as one that is used in another region. |spell| Combined with the highlighting used otherwise. + SpellLocal = { undercurl = config.undercurl, underline = not config.undercurl, sp = theme.diag.warning }, + -- SpellRare Word that is recognized by the spellchecker as one that is hardly ever used. |spell| Combined with the highlighting used otherwise. + SpellRare = { undercurl = config.undercurl, underline = not config.undercurl, sp = theme.diag.warning }, + -- StatusLine Status line of current window. + StatusLine = { fg = theme.ui.fg_dim, bg = theme.ui.bg_m3 }, + -- StatusLineNC Status lines of not-current windows. Note: If this is equal to "StatusLine", Vim will use "^^^" in the status line of the current window. + StatusLineNC = { fg = theme.ui.nontext, bg = theme.ui.bg_m3 }, + -- TabLine Tab pages line, not active tab page label. + TabLine = { bg = theme.ui.bg_m3, fg = theme.ui.special }, + -- TabLineFill Tab pages line, where there are no labels. + TabLineFill = { bg = theme.ui.bg }, + -- TabLineSel Tab pages line, active tab page label. + TabLineSel = { fg = theme.ui.fg_dim, bg = theme.ui.bg_p1 }, + -- Title Titles for output from ":set all", ":autocmd" etc. + Title = { fg = theme.syn.fun, bold = true }, + -- Visual Visual mode selection. + Visual = { bg = theme.ui.bg_visual }, + -- VisualNOS Visual mode selection when vim is "Not Owning the Selection". + VisualNOS = { link = "Visual" }, + -- WarningMsg Warning messages. + WarningMsg = { fg = theme.diag.warning }, + -- Whitespace "nbsp", "space", "tab", "multispace", "lead" and "trail" in 'listchars'. + Whitespace = { fg = theme.ui.whitespace }, + -- WildMenu Current match in 'wildmenu' completion. + WildMenu = { link = "Pmenu" }, + -- WinBar Window bar of current window. + WinBar = { fg = theme.ui.fg_dim, bg = "NONE" }, + -- WinBarNC Window bar of not-current windows. + WinBarNC = { fg = theme.ui.fg_dim, bg = config.dimInactive and theme.ui.bg_dim or "NONE" }, + + -- SignColumnSB = { link = "SignColumn" }, + -- NormalSB = { link = "Normal" }, + + debugPC = { bg = theme.diff.delete }, + debugBreakpoint = { fg = theme.syn.special1, bg = theme.ui.bg_gutter }, + + LspReferenceText = { bg = theme.ui.bg_p2 }, + LspReferenceRead = { link = "LspReferenceText" }, + LspReferenceWrite = { bg = theme.ui.bg_p2, underline = true }, + -- LspInlayHint = { link = "NonText"}, + + DiagnosticError = { fg = theme.diag.error }, + DiagnosticWarn = { fg = theme.diag.warning }, + DiagnosticInfo = { fg = theme.diag.info }, + DiagnosticHint = { fg = theme.diag.hint }, + DiagnosticOk = { fg = theme.diag.ok }, + + DiagnosticFloatingError = { fg = theme.diag.error }, + DiagnosticFloatingWarn = { fg = theme.diag.warning }, + DiagnosticFloatingInfo = { fg = theme.diag.info }, + DiagnosticFloatingHint = { fg = theme.diag.hint }, + DiagnosticFloatingOk = { fg = theme.diag.ok }, + + DiagnosticSignError = { fg = theme.diag.error, bg = theme.ui.bg_gutter }, + DiagnosticSignWarn = { fg = theme.diag.warning, bg = theme.ui.bg_gutter }, + DiagnosticSignInfo = { fg = theme.diag.info, bg = theme.ui.bg_gutter }, + DiagnosticSignHint = { fg = theme.diag.hint, bg = theme.ui.bg_gutter }, + + DiagnosticVirtualTextError = { link = "DiagnosticError" }, + DiagnosticVirtualTextWarn = { link = "DiagnosticWarn" }, + DiagnosticVirtualTextInfo = { link = "DiagnosticInfo" }, + DiagnosticVirtualTextHint = { link = "DiagnosticHint" }, + + DiagnosticUnderlineError = { undercurl = config.undercurl, underline = not config.undercurl, sp = theme.diag.error }, + DiagnosticUnderlineWarn = { undercurl = config.undercurl, underline = not config.undercurl, sp = theme.diag.warning }, + DiagnosticUnderlineInfo = { undercurl = config.undercurl, underline = not config.undercurl, sp = theme.diag.info }, + DiagnosticUnderlineHint = { undercurl = config.undercurl, underline = not config.undercurl, sp = theme.diag.hint }, + + LspSignatureActiveParameter = { fg = theme.diag.warning }, + LspCodeLens = { fg = theme.syn.comment }, + + -- vcs + diffAdded = { fg = theme.vcs.added }, + diffRemoved = { fg = theme.vcs.removed }, + diffDeleted = { fg = theme.vcs.removed }, + diffChanged = { fg = theme.vcs.changed }, + diffOldFile = { fg = theme.vcs.removed }, + diffNewFile = { fg = theme.vcs.added }, + -- diffFile = { fg = c.steelGray }, + -- diffLine = { fg = c.steelGray }, + -- diffIndexLine = { link = 'Identifier' }, + } +end + +return M diff --git a/lua/kanso/highlights/init.lua b/lua/kanso/highlights/init.lua new file mode 100644 index 0000000..2938862 --- /dev/null +++ b/lua/kanso/highlights/init.lua @@ -0,0 +1,37 @@ +local M = {} + +---@param highlights table +---@param termcolors table +function M.highlight(highlights, termcolors) + for hl, spec in pairs(highlights) do + vim.api.nvim_set_hl(0, hl, spec) + end + for i, tcolor in ipairs(termcolors) do + vim.g["terminal_color_" .. i - 1] = tcolor + end +end + +---@param colors KansoColors +---@param config? KansoConfig +function M.setup(colors, config) + config = config or require("kanso").config + + local highlights = {} + for _, highlight in ipairs({ "editor", "syntax", "treesitter", "lsp", "plugins" }) do + local mod = require("kanso.highlights." .. highlight) + for hl, spec in pairs(mod.setup(colors, config)) do + highlights[hl] = spec + end + end + + for hl, spec in pairs(config.overrides(colors)) do + if highlights[hl] and next(spec) then + highlights[hl].link = nil + end + highlights[hl] = vim.tbl_extend("force", highlights[hl] or {}, spec) + end + + return highlights +end + +return M diff --git a/lua/kanso/highlights/lsp.lua b/lua/kanso/highlights/lsp.lua new file mode 100644 index 0000000..b1b1075 --- /dev/null +++ b/lua/kanso/highlights/lsp.lua @@ -0,0 +1,60 @@ +local M = {} +---@param colors KansoColors +---@param config? KansoConfig +function M.setup(colors, config) + config = config or require("kanso").config + local theme = colors.theme + return { + -- ["@lsp.type.class"] = { link = "Structure" }, + -- ["@lsp.type.decorator"] = { link = "Function" }, + -- ["@lsp.type.enum"] = { link = "Structure" }, + -- ["@lsp.type.enumMember"] = { link = "Constant" }, + -- ["@lsp.type.function"] = { link = "Function" }, + -- ["@lsp.type.interface"] = { link = "Structure" }, + ["@lsp.type.macro"] = { link = "Macro" }, + ["@lsp.type.method"] = { link = "@function.method" }, -- Function + ["@lsp.type.namespace"] = { link = "@module" }, -- Structure + ["@lsp.type.parameter"] = { link = "@variable.parameter" }, -- Identifier + -- ["@lsp.type.property"] = { link = "Identifier" }, + -- ["@lsp.type.struct"] = { link = "Structure" }, + -- ["@lsp.type.type"] = { link = "Type" }, + -- ["@lsp.type.typeParameter"] = { link = "TypeDef" }, + ["@lsp.type.variable"] = { fg = "none" }, -- Identifier + ["@lsp.type.comment"] = { link = "Comment" }, -- Comment + + ["@lsp.type.const"] = { link = "Constant" }, + ["@lsp.type.comparison"] = { link = "Operator" }, + ["@lsp.type.bitwise"] = { link = "Operator" }, + ["@lsp.type.punctuation"] = { link = "Delimiter" }, + + ["@lsp.type.selfParameter"] = { link = "@variable.builtin" }, + -- ["@lsp.type.builtinConstant"] = { link = "@constant.builtin" }, + ["@lsp.type.builtinConstant"] = { link = "@constant.builtin" }, + ["@lsp.type.magicFunction"] = { link = "@function.builtin" }, + + ["@lsp.mod.readonly"] = { link = "Constant" }, + ["@lsp.mod.typeHint"] = { link = "Type" }, + -- ["@lsp.mod.defaultLibrary"] = { link = "Special" }, + -- ["@lsp.mod.builtin"] = { link = "Special" }, + + ["@lsp.typemod.operator.controlFlow"] = { link = "@keyword.exception" }, -- rust ? operator + ["@lsp.type.lifetime"] = { link = "Operator" }, + ["@lsp.typemod.keyword.documentation"] = { link = "Special" }, + ["@lsp.type.decorator.rust"] = { link = "PreProc" }, + + ["@lsp.typemod.variable.global"] = { link = "Constant" }, + ["@lsp.typemod.variable.static"] = { link = "Constant" }, + ["@lsp.typemod.variable.defaultLibrary"] = { link = "Special" }, + + ["@lsp.typemod.function.builtin"] = { link = "@function.builtin" }, + ["@lsp.typemod.function.defaultLibrary"] = { link = "@function.builtin" }, + ["@lsp.typemod.method.defaultLibrary"] = { link = "@function.builtin" }, + + ["@lsp.typemod.variable.injected"] = { link = "@variable" }, + + ["@lsp.typemod.function.readonly"] = { fg = theme.syn.fun, bold = true }, + } +end + +return M +--vim: fdm=marker diff --git a/lua/kanso/highlights/plugins.lua b/lua/kanso/highlights/plugins.lua new file mode 100644 index 0000000..3fc7d13 --- /dev/null +++ b/lua/kanso/highlights/plugins.lua @@ -0,0 +1,540 @@ +local M = {} + +---@param colors KansoColors +---@param config? KansoConfig +function M.setup(colors, config) + config = config or require("kanso").config + local theme = colors.theme + return { + -- Neovcs + -- NeovcsBranch = {}, + -- NeovcsRemote = {}, + -- NeovcsDiffDelete = { fg = theme.vcs.removed, bg = theme.diff.delete }, + -- NeovcsDiffAdd = { fg = theme.vcs.added, bg = theme.diff.add }, + -- NeovcsHunkHeader = { fg = theme.syn.identifier }, + -- NeovcsDiffContextHighlight = { bg = theme.diff.change }, + + -- vcsSigns + -- vcsSignsAdd = { link = "diffAdded" }, + -- vcsSignsChange = { link = "diffChanged" }, + -- vcsSignsDelete = { link = "diffDeleted" }, + -- vcsSignsDeleteLn = { bg = theme.diff.delete }, + + -- Gitsigns + GitSignsAdd = { fg = theme.vcs.added, bg = theme.ui.bg_gutter }, + GitSignsChange = { fg = theme.vcs.changed, bg = theme.ui.bg_gutter }, + GitSignsDelete = { fg = theme.vcs.removed, bg = theme.ui.bg_gutter }, + -- Neogit + NeogitDiffContextHighlight = { bg = theme.diff.change }, --[[ guibg=#333333 guifg=#b2b2b2 ]] + NeogitHunkHeader = { fg = theme.syn.fun }, --[[ guifg=#cccccc guibg=#404040 ]] + NeogitHunkHeaderHighlight = { fg = theme.syn.constant, bg = theme.diff.change }, --[[ guifg=#cccccc guibg=#4d4d4d ]] + NeogitDiffAddHighlight = { bg = theme.diff.add }, + NeogitDiffDeleteHighlight = { bg = theme.diff.delete }, + -- TreeSitter Extensions + TreesitterContext = { link = "Folded" }, + TreesitterContextLineNumber = { fg = theme.ui.special, bg = theme.ui.bg_gutter }, + -- Telescope + TelescopeBorder = { fg = theme.ui.float.fg_border, bg = theme.ui.bg }, + TelescopeTitle = { fg = theme.ui.special }, + TelescopeSelection = { link = "CursorLine" }, + TelescopeSelectionCaret = { link = "CursorLineNr" }, + TelescopeResultsClass = { link = "Structure" }, + TelescopeResultsStruct = { link = "Structure" }, + TelescopeResultsField = { link = "@field" }, + TelescopeResultsMethod = { link = "Function" }, + TelescopeResultsVariable = { link = "@variable" }, + -- NvimTree + NvimTreeNormal = { link = "Normal" }, + NvimTreeNormalNC = { link = "NvimTreeNormal" }, + NvimTreeRootFolder = { fg = theme.syn.identifier, bold = true }, + NvimTreeGitDirty = { fg = theme.vcs.changed }, + NvimTreeGitNew = { fg = theme.vcs.added }, + NvimTreeGitDeleted = { fg = theme.vcs.removed }, + NvimTreeGitStaged = { fg = theme.vcs.added }, + NvimTreeSpecialFile = { fg = theme.syn.special1 }, + -- NvimTreeIndentMarker = {}, + NvimTreeImageFile = { fg = theme.syn.special2 }, + NvimTreeSymlink = { link = "Type" }, + NvimTreeFolderName = { link = "Directory" }, + NvimTreeExecFile = { fg = theme.syn.string, bold = true }, + NvimTreeOpenedFile = { fg = theme.syn.special1, italic = true }, + NvimTreeWinSeparator = { link = "WinSeparator" }, + NvimTreeWindowPicker = { bg = theme.ui.bg_m1, fg = theme.syn.special1, bold = true }, + -- NeoTree + NeoTreeTabInactive = { link = "TabLine" }, + NeoTreeTabActive = { link = "TabLineSel" }, + NeoTreeTabSeparatorInactive = { link = "NeoTreeTabInactive" }, + NeoTreeTabSeparatorActive = { link = "NeoTreeTabActive" }, + NeoTreeRootName = { fg = theme.syn.identifier, bold = true }, + NeoTreeModified = { link = "String" }, + NeoTreeGitModified = { fg = theme.vcs.changed }, + NeoTreeGitAdded = { fg = theme.vcs.added }, + NeoTreeGitDeleted = { fg = theme.vcs.removed }, + NeoTreeGitStaged = { fg = theme.vcs.added }, + NeoTreeGitConflict = { fg = theme.diag.error }, + NeoTreeGitUntracked = { link = "NeoTreeGitModified", default = true }, + NeoTreeGitUnstaged = { link = "NeoTreeGitModified", default = true }, + NeoTreeIndentMarker = { link = "NonText" }, + -- WindowPicker + -- NvimWindowSwitch = { bg = theme.ui.bg_m3, fg = theme.diag.warning }, + -- NvimWindowSwitchNC = { link = "NvimWindowSwitch" }, + -- Dashboard + DashboardShortCut = { fg = theme.syn.special1 }, + DashboardHeader = { fg = theme.vcs.removed }, + DashboardCenter = { fg = theme.syn.identifier }, + DashboardFooter = { fg = theme.syn.comment }, + DashboardDesc = { fg = theme.syn.identifier }, + DashboardKey = { fg = theme.syn.special1 }, + DashboardIcon = { fg = theme.ui.special }, + -- Notify + NotifyBackground = { bg = theme.ui.bg }, + NotifyERRORBorder = { link = "DiagnosticError" }, + NotifyWARNBorder = { link = "DiagnosticWarn" }, + NotifyINFOBorder = { link = "DiagnosticInfo" }, + NotifyHINTBorder = { link = "DiagnosticHint" }, + NotifyDEBUGBorder = { link = "Debug" }, + NotifyTRACEBorder = { link = "Comment" }, + NotifyERRORIcon = { link = "DiagnosticError" }, + NotifyWARNIcon = { link = "DiagnosticWarn" }, + NotifyINFOIcon = { link = "DiagnosticInfo" }, + NotifyHINTIcon = { link = "DiagnosticHint" }, + NotifyDEBUGIcon = { link = "Debug" }, + NotifyTRACEIcon = { link = "Comment" }, + NotifyERRORTitle = { link = "DiagnosticError" }, + NotifyWARNTitle = { link = "DiagnosticWarn" }, + NotifyINFOTitle = { link = "DiagnosticInfo" }, + NotifyHINTTitle = { link = "DiagnosticHint" }, + NotifyDEBUGTitle = { link = "Debug" }, + NotifyTRACETitle = { link = "Comment" }, + -- Dap-UI + -- DapUIVariable = { link = "Normal" }, + DapUIScope = { link = "Special" }, -- guifg=#00F1F5" + DapUIType = { link = "Type" }, -- guifg=#D484FF" + -- DapUIValue = { link = "Normal" }, + DapUIModifiedValue = { fg = theme.syn.special1, bold = true }, -- guifg=#00F1F5 gui=bold" + DapUIDecoration = { fg = theme.ui.float.fg_border }, -- guifg=#00F1F5" + DapUIThread = { fg = theme.syn.identifier }, --guifg=#A9FF68" + DapUIStoppedThread = { fg = theme.syn.special1 }, --guifg=#00f1f5" + -- DapUIFrameName = { link = "Normal"}, + DapUISource = { fg = theme.syn.special2 }, -- guifg=#D484FF" + DapUILineNumber = { fg = theme.syn.special1 }, -- guifg=#00f1f5" + DapUIFloatBorder = { fg = theme.ui.float.fg_border }, -- guifg=#00F1F5" + DapUIWatchesEmpty = { fg = theme.diag.error }, -- guifg=#F70067" + DapUIWatchesValue = { fg = theme.syn.identifier }, -- guifg=#A9FF68" + DapUIWatchesError = { fg = theme.diag.error }, --guifg=#F70067" + DapUIBreakpointsPath = { link = "Directory" }, --guifg=#00F1F5" + DapUIBreakpointsInfo = { fg = theme.diag.info }, --guifg=#A9FF68" + DapUIBreakpointsCurrentLine = { fg = theme.syn.identifier, bold = true }, --guifg=#A9FF68 gui=bold" + -- DapUIBreakpointsLine = {}, -- DapUILineNumber" + DapUIBreakpointsDisabledLine = { link = "Comment" }, --guifg=#424242" + -- DapUICurrentFrameName = {}, -- DapUIBreakpointsCurrentLine" + DapUIStepOver = { fg = theme.syn.special1 }, --guifg=#00f1f5" + DapUIStepInto = { fg = theme.syn.special1 }, --guifg=#00f1f5" + DapUIStepBack = { fg = theme.syn.special1 }, --guifg=#00f1f5" + DapUIStepOut = { fg = theme.syn.special1 }, --guifg=#00f1f5" + DapUIStop = { fg = theme.diag.error }, --guifg=#F70067" + DapUIPlayPause = { fg = theme.syn.string }, --guifg=#A9FF68" + DapUIRestart = { fg = theme.syn.string }, --guifg=#A9FF68" + DapUIUnavailable = { fg = theme.syn.comment }, --guifg=#424242" + -- Floaterm + FloatermBorder = { fg = theme.ui.float.fg_border, bg = theme.ui.bg }, + -- NeoVim = {}, + healthError = { fg = theme.diag.error }, + healthSuccess = { fg = theme.diag.ok }, + healthWarning = { fg = theme.diag.warning }, + -- Cmp + CmpDocumentation = { link = "NormalFloat" }, + CmpDocumentationBorder = { link = "FloatBorder" }, + CmpCompletion = { link = "Pmenu" }, + CmpCompletionSel = { link = "PmenuSel" }, + CmpCompletionBorder = { fg = theme.ui.bg_search, bg = theme.ui.pmenu.bg }, + CmpCompletionThumb = { link = "PmenuThumb" }, + CmpCompletionSbar = { link = "PmenuSbar" }, + CmpItemAbbr = { fg = theme.ui.pmenu.fg }, + CmpItemAbbrDeprecated = { fg = theme.syn.comment, strikethrough = true }, + CmpItemAbbrMatch = { fg = theme.syn.fun }, + CmpItemAbbrMatchFuzzy = { link = "CmpItemAbbrMatch" }, + CmpItemKindDefault = { fg = theme.ui.fg_dim }, + CmpItemMenu = { fg = theme.ui.fg_dim }, + CmpGhostText = { fg = theme.syn.comment }, + + CmpItemKindText = { fg = theme.ui.fg }, + CmpItemKindMethod = { link = "@function.method" }, + CmpItemKindFunction = { link = "Function" }, + CmpItemKindConstructor = { link = "@constructor" }, + CmpItemKindField = { link = "@variable.member" }, + CmpItemKindVariable = { fg = theme.ui.fg_dim }, + CmpItemKindClass = { link = "Type" }, + CmpItemKindInterface = { link = "Type" }, + CmpItemKindModule = { link = "@module" }, + CmpItemKindProperty = { link = "@property" }, + CmpItemKindUnit = { link = "Number" }, + CmpItemKindValue = { link = "String" }, + CmpItemKindEnum = { link = "Type" }, + CmpItemKindKeyword = { link = "Keyword" }, + CmpItemKindSnippet = { link = "Special" }, + CmpItemKindColor = { link = "Special" }, + CmpItemKindFile = { link = "Directory" }, + CmpItemKindReference = { link = "Special" }, + CmpItemKindFolder = { link = "Directory" }, + CmpItemKindEnumMember = { link = "Constant" }, + CmpItemKindConstant = { link = "Constant" }, + CmpItemKindStruct = { link = "Type" }, + CmpItemKindEvent = { link = "Type" }, + CmpItemKindOperator = { link = "Operator" }, + CmpItemKindTypeParameter = { link = "Type" }, + CmpItemKindCopilot = { link = "String" }, + + -- blink.cmp + BlinkCmpMenu = { link = "Pmenu" }, + BlinkCmpMenuSelection = { link = "PmenuSel" }, + BlinkCmpMenuBorder = { fg = theme.ui.bg_search, bg = theme.ui.pmenu.bg }, + BlinkCmpScrollBarThumb = { link = "PmenuThumb" }, + BlinkCmpScrollBarGutter = { link = "PmenuSbar" }, + BlinkCmpLabel = { fg = theme.ui.pmenu.fg }, + BlinkCmpLabelMatch = { fg = theme.syn.fun }, + BlinkCmpLabelDetails = { fg = theme.syn.comment }, + BlinkCmpLabelDeprecated = { fg = theme.syn.comment, strikethrough = true }, + BlinkCmpGhostText = { fg = theme.syn.comment }, + BlinkCmpDoc = { link = "NormalFloat" }, + BlinkCmpDocBorder = { link = "FloatBorder" }, + BlinkCmpDocCursorLine = { link = "Visual"}, + BlinkCmpSignatureHelp = { link = "NormalFloat" }, + BlinkCmpSignatureHelpBorder = { link = "FloatBorder" }, + BlinkCmpSignatureHelpActiveParameter = { link = "LspSignatureActiveParameter"}, + + BlinkCmpKind = { fg = theme.ui.fg_dim }, + BlinkCmpKindText = { fg = theme.ui.fg }, + BlinkCmpKindMethod = { link = "@function.method" }, + BlinkCmpKindFunction = { link = "Function" }, + BlinkCmpKindConstructor = { link = "@constructor" }, + BlinkCmpKindField = { link = "@variable.member" }, + BlinkCmpKindVariable = { fg = theme.ui.fg_dim }, + BlinkCmpKindClass = { link = "Type" }, + BlinkCmpKindInterface = { link = "Type" }, + BlinkCmpKindModule = { link = "@module" }, + BlinkCmpKindProperty = { link = "@property" }, + BlinkCmpKindUnit = { link = "Number" }, + BlinkCmpKindValue = { link = "String" }, + BlinkCmpKindEnum = { link = "Type" }, + BlinkCmpKindKeyword = { link = "Keyword" }, + BlinkCmpKindSnippet = { link = "Special" }, + BlinkCmpKindColor = { link = "Special" }, + BlinkCmpKindFile = { link = "Directory" }, + BlinkCmpKindReference = { link = "Special" }, + BlinkCmpKindFolder = { link = "Directory" }, + BlinkCmpKindEnumMember = { link = "Constant" }, + BlinkCmpKindConstant = { link = "Constant" }, + BlinkCmpKindStruct = { link = "Type" }, + BlinkCmpKindEvent = { link = "Type" }, + BlinkCmpKindOperator = { link = "Operator" }, + BlinkCmpKindTypeParameter = { link = "Type" }, + BlinkCmpKindCopilot = { link = "String" }, + + -- IndentBlankline + IndentBlanklineChar = { fg = theme.ui.whitespace }, + IndentBlanklineSpaceChar = { fg = theme.ui.whitespace }, + IndentBlanklineSpaceCharBlankline = { fg = theme.ui.whitespace }, + IndentBlanklineContextChar = { fg = theme.ui.special }, + IndentBlanklineContextStart = { sp = theme.ui.special, underline = true }, + IblIndent = { fg = theme.ui.whitespace }, + IblWhitespace = { fg = theme.ui.whitespace }, + IblScope = { fg = theme.ui.special }, + -- Lazy + LazyProgressTodo = { fg = theme.ui.nontext }, + + -- Trouble + TroubleIndent = { fg = theme.ui.whitespace }, + TroublePos = { fg = theme.ui.special }, + + -- Nvim-Navic + NavicIconsFile = { link = "Directory" }, + NavicIconsModule = { link = "@module" }, + NavicIconsNamespace = { link = "@module" }, + NavicIconsPackage = { link = "@module" }, + NavicIconsClass = { link = "Type" }, + NavicIconsMethod = { link = "@function.method" }, + NavicIconsProperty = { link = "@property" }, + NavicIconsField = { link = "@variable.member" }, + NavicIconsConstructor = { link = "@constructor" }, + NavicIconsEnum = { link = "Type" }, + NavicIconsInterface = { link = "Type" }, + NavicIconsFunction = { link = "Function" }, + NavicIconsVariable = { link = "@variable" }, + NavicIconsConstant = { link = "Constant" }, + NavicIconsString = { link = "String" }, + NavicIconsNumber = { link = "Number" }, + NavicIconsBoolean = { link = "Boolean" }, + NavicIconsArray = { link = "Type" }, + NavicIconsObject = { link = "Type" }, + NavicIconsKey = { link = "Identifier" }, + NavicIconsNull = { link = "Type" }, + NavicIconsEnumMember = { link = "Constant" }, + NavicIconsStruct = { link = "Structure" }, + NavicIconsEvent = { link = "Structure" }, + NavicIconsOperator = { link = "Operator" }, + NavicIconsTypeParameter = { link = "Type" }, + NavicText = { fg = theme.ui.fg }, + NavicSeparator = { fg = theme.ui.fg }, + + -- Aerial icons + AerialFileIcon = { link = "Directory" }, + AerialModuleIcon = { link = "@module" }, + AerialNamespaceIcon = { link = "@module" }, + AerialPackageIcon = { link = "@module" }, + AerialClassIcon = { link = "Type" }, + AerialMethodIcon = { link = "@function.method" }, + AerialPropertyIcon = { link = "@property" }, + AerialFieldIcon = { link = "@variable.member" }, + AerialConstructorIcon = { link = "@constructor" }, + AerialEnumIcon = { link = "Type" }, + AerialInterfaceIcon = { link = "Type" }, + AerialFunctionIcon = { link = "Function" }, + AerialVariableIcon = { link = "@variable" }, + AerialConstantIcon = { link = "Constant" }, + AerialStringIcon = { link = "String" }, + AerialNumberIcon = { link = "Number" }, + AerialBooleanIcon = { link = "Boolean" }, + AerialArrayIcon = { link = "Type" }, + AerialObjectIcon = { link = "Type" }, + AerialKeyIcon = { link = "Identifier" }, + AerialNullIcon = { link = "Type" }, + AerialEnumMemberIcon = { link = "Constant" }, + AerialStructIcon = { link = "Structure" }, + AerialEventIcon = { link = "Structure" }, + AerialOperatorIcon = { link = "Operator" }, + AerialTypeParameterIcon = { link = "Type" }, + + -- Mini + MiniAnimateCursor = { reverse = true, nocombine = true }, + MiniAnimateNormalFloat = { link = "NormalFloat" }, + + MiniClueBorder = { link = "FloatBorder" }, + MiniClueDescGroup = { link = "DiagnosticFloatingWarn" }, + MiniClueDescSingle = { link = "NormalFloat" }, + MiniClueNextKey = { link = "DiagnosticFloatingHint" }, + MiniClueNextKeyWithPostkeys = { link = "DiagnosticFloatingError" }, + MiniClueSeparator = { link = "DiagnosticFloatingInfo" }, + MiniClueTitle = { link = "FloatTitle" }, + + MiniCompletionActiveParameter = { underline = true }, + + MiniCursorword = { underline = true }, + MiniCursorwordCurrent = { underline = true }, + + MiniDepsChangeAdded = { link = "diffAdded" }, + MiniDepsChangeRemoved = { link = "diffRemoved" }, + MiniDepsHint = { fg = theme.diag.hint }, + MiniDepsInfo = { fg = theme.diag.info }, + MiniDepsMsgBreaking = { fg = theme.diag.warning }, + MiniDepsPlaceholder = { link = "Comment" }, + MiniDepsTitle = { link = "Title" }, + MiniDepsTitleError = { link = "DiffDelete" }, + MiniDepsTitleSame = { link = "DiffText" }, + MiniDepsTitleUpdate = { link = "DiffAdd" }, + + MiniDiffSignAdd = { fg = theme.vcs.added, bg = theme.ui.bg_gutter }, + MiniDiffSignChange = { fg = theme.vcs.changed, bg = theme.ui.bg_gutter }, + MiniDiffSignDelete = { fg = theme.vcs.removed, bg = theme.ui.bg_gutter }, + MiniDiffOverAdd = { link = "DiffAdd" }, + MiniDiffOverChange = { link = "DiffText" }, + MiniDiffOverContext = { link = "DiffChange" }, + MiniDiffOverDelete = { link = "DiffDelete" }, + + MiniFilesBorder = { link = "FloatBorder" }, + MiniFilesBorderModified = { link = "DiagnosticFloatingWarn" }, + MiniFilesCursorLine = { link = "CursorLine" }, + MiniFilesDirectory = { link = "Directory" }, + MiniFilesFile = { fg = theme.ui.fg }, + MiniFilesNormal = { link = "NormalFloat" }, + MiniFilesTitle = { fg = theme.ui.special, bg = theme.ui.float.bg_border, bold = true }, + MiniFilesTitleFocused = { fg = theme.ui.fg, bg = theme.ui.float.bg_border, bold = true }, + + MiniHipatternsFixme = { fg = theme.ui.bg, bg = theme.diag.error, bold = true }, + MiniHipatternsHack = { fg = theme.ui.bg, bg = theme.diag.warning, bold = true }, + MiniHipatternsNote = { fg = theme.ui.bg, bg = theme.diag.info, bold = true }, + MiniHipatternsTodo = { fg = theme.ui.bg, bg = theme.diag.hint, bold = true }, + + MiniIconsAzure = { fg = theme.syn.special1 }, + MiniIconsBlue = { fg = theme.syn.fun }, + MiniIconsCyan = { fg = theme.syn.type }, + MiniIconsGreen = { fg = theme.syn.string }, + MiniIconsGrey = { fg = theme.ui.fg }, + MiniIconsOrange = { fg = theme.syn.constant }, + MiniIconsPurple = { fg = theme.syn.keyword }, + MiniIconsRed = { fg = theme.syn.special3 }, + MiniIconsYellow = { fg = theme.syn.identifier }, + + MiniIndentscopeSymbol = { fg = theme.syn.special1 }, + MiniIndentscopePrefix = { nocombine = true }, -- Make it invisible + + MiniJump = { link = "SpellRare" }, + + MiniJump2dDim = { link = "Comment" }, + MiniJump2dSpot = { fg = theme.syn.constant, bold = true, nocombine = true }, + MiniJump2dSpotAhead = { fg = theme.diag.hint, bg = theme.ui.bg_dim, nocombine = true }, + MiniJump2dSpotUnique = { fg = theme.syn.special1, bold = true, nocombine = true }, + + MiniMapNormal = { link = "NormalFloat" }, + MiniMapSymbolCount = { link = "Special" }, + MiniMapSymbolLine = { link = "Title" }, + MiniMapSymbolView = { link = "Delimiter" }, + + MiniNotifyBorder = { link = "FloatBorder" }, + MiniNotifyNormal = { link = "NormalFloat" }, + MiniNotifyTitle = { link = "FloatTitle" }, + + MiniOperatorsExchangeFrom = { link = "IncSearch" }, + + MiniPickBorder = { link = "FloatBorder" }, + MiniPickBorderBusy = { link = "DiagnosticFloatingWarn" }, + MiniPickBorderText = { link = "FloatTitle" }, + MiniPickIconDirectory = { link = "Directory" }, + MiniPickIconFile = { link = "MiniPickNormal" }, + MiniPickHeader = { link = "DiagnosticFloatingHint" }, + MiniPickMatchCurrent = { link = "CursorLine" }, + MiniPickMatchMarked = { link = "Visual" }, + MiniPickMatchRanges = { link = "DiagnosticFloatingHint" }, + MiniPickNormal = { link = "NormalFloat" }, + MiniPickPreviewLine = { link = "CursorLine" }, + MiniPickPreviewRegion = { link = "IncSearch" }, + MiniPickPrompt = { fg = theme.syn.fun, bg = theme.ui.float.bg_border }, + + MiniStarterCurrent = { nocombine = true }, + MiniStarterFooter = { fg = theme.syn.deprecated }, + MiniStarterHeader = { link = "Title" }, + MiniStarterInactive = { link = "Comment" }, + MiniStarterItem = { link = "Normal" }, + MiniStarterItemBullet = { link = "Delimiter" }, + MiniStarterItemPrefix = { fg = theme.diag.warning }, + MiniStarterSection = { fg = theme.diag.ok }, + MiniStarterQuery = { fg = theme.diag.info }, + + MiniStatuslineDevinfo = { fg = theme.ui.fg_dim, bg = theme.ui.bg_p1 }, + MiniStatuslineFileinfo = { fg = theme.ui.fg_dim, bg = theme.ui.bg_p1 }, + MiniStatuslineFilename = { fg = theme.ui.fg_dim, bg = theme.ui.bg_dim }, + MiniStatuslineInactive = { link = "StatusLineNC" }, + MiniStatuslineModeCommand = { fg = theme.ui.bg, bg = theme.syn.operator, bold = true }, + MiniStatuslineModeInsert = { fg = theme.ui.bg, bg = theme.diag.ok, bold = true }, + MiniStatuslineModeNormal = { fg = theme.ui.bg_m3, bg = theme.syn.fun, bold = true }, + MiniStatuslineModeOther = { fg = theme.ui.bg, bg = theme.syn.type, bold = true }, + MiniStatuslineModeReplace = { fg = theme.ui.bg, bg = theme.syn.constant, bold = true }, + MiniStatuslineModeVisual = { fg = theme.ui.bg, bg = theme.syn.keyword, bold = true }, + + MiniSurround = { link = "IncSearch" }, + + MiniTablineCurrent = { fg = theme.ui.fg_dim, bg = theme.ui.bg_p1, bold = true }, + MiniTablineFill = { link = "TabLineFill" }, + MiniTablineHidden = { fg = theme.ui.special, bg = theme.ui.bg_m3 }, + MiniTablineModifiedCurrent = { fg = theme.ui.bg_p1, bg = theme.ui.fg_dim, bold = true }, + MiniTablineModifiedHidden = { fg = theme.ui.bg_m3, bg = theme.ui.special }, + MiniTablineModifiedVisible = { fg = theme.ui.bg_m3, bg = theme.ui.special, bold = true }, + MiniTablineTabpagesection = { fg = theme.ui.fg, bg = theme.ui.bg_search, bold = true }, + MiniTablineVisible = { fg = theme.ui.special, bg = theme.ui.bg_m3, bold = true }, + + MiniTestEmphasis = { bold = true }, + MiniTestFail = { fg = theme.diag.error, bold = true }, + MiniTestPass = { fg = theme.diag.ok, bold = true }, + + MiniTrailspace = { bg = theme.vcs.removed }, + + NeotestAdapterName = { fg = theme.syn.special3, }, + NeotestDir = { fg = theme.syn.fun, }, + NeotestExpandMarker = { fg = theme.syn.punct, bold = true, }, + NeotestFailed = { fg = theme.diag.error }, + NeotestFile = { fg = theme.syn.fun, }, + NeotestFocused = { bold = true, underline = true, }, + NeotestIndent = { fg = theme.ui.special, bold = true, }, + NeotestMarked = { fg = theme.diag.warning, italic = true, }, + NeotestNamespace = { fg = theme.syn.fun, }, + NeotestPassed = { fg = theme.diag.ok }, + NeotestRunning = { fg = theme.vcs.changed, }, + NeotestWinSelect = { fg = theme.diag.hint }, + NeotestSkipped = { fg = theme.syn.special1 }, + NeotestTarget = { fg = theme.syn.special3 }, + NeotestTest = { fg = theme.ui.float.fg }, + NeotestUnknown = { fg = theme.syn.deprecated }, + NeotestWatching = { fg = theme.vcs.changed, }, + + SnacksPicker = { bg = theme.ui.bg }, + SnacksPickerTitle = { fg = theme.ui.fg, bg = theme.ui.bg }, + SnacksPickerBorder = { fg = theme.ui.bg }, + SnacksPickerNormal = { fg = theme.ui.fg, bg = theme.ui.bg }, + SnacksPickerMatch = { fg = theme.ui.fg }, + SnacksPickerCursor = { fg = theme.ui.bg, bg = theme.ui.bg }, + SnacksPickerPrompt = { fg = theme.ui.fg }, + SnacksPickerDim = { fg = theme.ui.fg_dim }, + SnacksInputIcon = { fg = theme.ui.fg, bg = theme.ui.bg }, + SnacksIndent = { fg = theme.ui.bg_gutter, bg = theme.ui.bg }, + SnacksIndentScope = { fg = theme.ui.bg, bg = theme.ui.bg }, + SnacksPickerInputBorder = { fg = theme.ui.bg, bg = theme.ui.bg }, + SnacksPickerInputTitle = { fg = theme.ui.bg, bg = theme.ui.bg }, + SnacksPickerBoxTitle = { fg = theme.ui.bg, bg = theme.ui.bg }, + SnacksPickerSelected = { fg = theme.ui.bg }, + SnacksPickerPickWinCurrent = { fg = theme.ui.fg, bg = theme.ui.bg, bold = true }, + SnacksPickerPickWin = { fg = theme.ui.fg, bg = theme.ui.bg_search, bold = true }, + + BufferLineBackground = { fg = theme.ui.none, bg = theme.ui.none }, + BufferLineBuffer = { fg = theme.ui.none, bg = theme.ui.none }, + BufferLineBufferSelected = { bg = theme.ui.none }, + BufferLineBufferVisible = { bg = theme.ui.none }, + BufferLineCloseButton = { bg = theme.ui.none }, + BufferLineCloseButtonSelected = { bg = theme.ui.none }, + BufferLineCloseButtonVisible = { bg = theme.ui.none }, + BufferLineDuplicate = { bg = theme.ui.none }, + BufferLineDuplicateSelected = { bg = theme.ui.none }, + BufferLineDuplicateVisible = { bg = theme.ui.none }, + BufferLineError = { bg = theme.ui.none, sp = theme.ui.none }, + BufferLineErrorDiagnostic = { bg = theme.ui.none, sp = theme.ui.none }, + BufferLineErrorDiagnosticSelected = { bg = theme.ui.none, sp = theme.ui.none }, + BufferLineErrorDiagnosticVisible = { bg = theme.ui.none }, + BufferLineErrorSelected = { bg = theme.ui.none, sp = theme.ui.none }, + BufferLineErrorVisible = { bg = theme.ui.none }, + BufferLineFill = { bg = theme.ui.none }, + BufferLineHint = { sp = theme.ui.none, bg = theme.ui.none }, + BufferLineHintDiagnostic = { sp = theme.ui.none, bg = theme.ui.none }, + BufferLineHintDiagnosticSelected = { bg = theme.ui.none, sp = theme.ui.none }, + BufferLineHintDiagnosticVisible = { bg = theme.ui.none }, + BufferLineHintSelected = { bg = theme.ui.none, sp = theme.ui.none }, + BufferLineHintVisible = { bg = theme.ui.none }, + BufferLineInfo = { sp = theme.ui.none, bg = theme.ui.none }, + BufferLineInfoDiagnostic = { sp = theme.ui.none, bg = theme.ui.none }, + BufferLineInfoDiagnosticSelected = { sp = theme.ui.none, bg = theme.ui.none }, + BufferLineInfoDiagnosticVisible = { bg = theme.ui.none }, + BufferLineInfoSelected = { bg = theme.ui.none, sp = theme.ui.none }, + BufferLineInfoVisible = { bg = theme.ui.none }, + BufferLineIndicatorSelected = { bg = theme.ui.none }, + BufferLineModified = { bg = theme.ui.none }, + BufferLineModifiedSelected = { bg = theme.ui.none }, + BufferLineModifiedVisible = { bg = theme.ui.none }, + BufferLineNumbers = { bg = theme.ui.none }, + BufferLineNumbersSelected = { bg = theme.ui.none }, + BufferLineNumbersVisible = { bg = theme.ui.none }, + BufferLineOffsetSeparator = { bg = theme.ui.none }, + BufferLineSeparator = { bg = theme.ui.none }, + BufferLineSeparatorSelected = { bg = theme.ui.none }, + BufferLineSeparatorVisible = { bg = theme.ui.none }, + BufferLineTab = { bg = theme.ui.none }, + BufferLinePick = { bg = theme.ui.none }, + BufferLinePickSelected = { bg = theme.ui.none }, + BufferLineDevIconLua = { bg = theme.ui.none }, + BufferLineDevIconLuaSelected = { bg = theme.ui.none }, + BufferLineDevIconLuaVisible = { bg = theme.ui.none }, + BufferLineDevIconLuaInactive = { bg = theme.ui.none }, + BufferLinePickVisible = { bg = theme.ui.none }, + BufferLineIndicatorVisible = { bg = theme.ui.none }, + BufferLineTabClose = { bg = theme.ui.none }, + BufferLineTabSelected = { bg = theme.ui.none }, + BufferLineTabSeparator = { bg = theme.ui.none }, + BufferLineTabSeparatorSelected = { bg = theme.ui.none }, + BufferLineTruncMarker = { bg = theme.ui.none }, + BufferLineWarning = { bg = theme.ui.none }, + BufferLineWarningDiagnostic = { bg = theme.ui.none }, + BufferLineWarningDiagnosticSelected = { bg = theme.ui.none }, + BufferLineWarningDiagnosticVisible = { bg = theme.ui.none }, + BufferLineWarningSelected = { bg = theme.ui.none }, + BufferLineWarningVisible = { bg = theme.ui.none }, + } +end + +return M diff --git a/lua/kanso/highlights/syntax.lua b/lua/kanso/highlights/syntax.lua new file mode 100644 index 0000000..d6ddb5f --- /dev/null +++ b/lua/kanso/highlights/syntax.lua @@ -0,0 +1,103 @@ +-- local c = require("kanso.color") +local M = {} + +---@param colors KansoColors +---@param config? KansoConfig +function M.setup(colors, config) + local theme = colors.theme + config = config or require("kanso").config + + return { + -- *Comment any comment + Comment = vim.tbl_extend("force", { fg = theme.syn.comment }, config.commentStyle), + + -- *Constant any constant + Constant = { fg = theme.syn.constant }, + -- String a string constant: "this is a string" + String = { fg = theme.syn.string }, + -- Character a character constant: 'c', '\n' + Character = { link = "String" }, + -- Number a number constant: 234, 0xff + Number = { fg = theme.syn.number }, + -- Boolean a boolean constant: TRUE, false + Boolean = { fg = theme.syn.constant }, + -- Float a floating point constant: 2.3e10 + Float = { link = "Number" }, + + -- *Identifier any variable name + Identifier = { fg = theme.syn.identifier }, + -- Function function name (also: methods for classes) + Function = vim.tbl_extend("force", { fg = theme.syn.fun }, config.functionStyle), + + -- *Statement any statement + Statement = vim.tbl_extend("force", { fg = theme.syn.statement }, config.statementStyle), + -- Conditional if, then, else, endif, switch, etc. + -- Repeat for, do, while, etc. + -- Label case, default, etc. + -- Operator "sizeof", "+", "*", etc. + Operator = { fg = theme.syn.operator }, + -- Keyword any other keyword + Keyword = vim.tbl_extend("force", { fg = theme.syn.keyword }, config.keywordStyle), + -- Exception try, catch, throw + Exception = { fg = theme.syn.special2 }, + + -- *PreProc generic Preprocessor + PreProc = { fg = theme.syn.preproc }, + -- Include preprocessor #include + -- Define preprocessor #define + -- Macro same as Define + -- PreCondit preprocessor #if, #else, #endif, etc. + + -- *Type int, long, char, etc. + Type = vim.tbl_extend("force", { fg = theme.syn.type }, config.typeStyle), + -- StorageClass static, register, volatile, etc. + -- Structure struct, union, enum, etc. + -- Typedef A typedef + + -- *Special any special symbol + Special = { fg = theme.syn.special1 }, + -- SpecialChar special character in a constant + -- Tag you can use CTRL-] on this + -- Delimiter character that needs attention + Delimiter = { fg = theme.syn.punct }, + -- SpecialComment special things inside a comment + -- Debug debugging statements + + -- *Underlined text that stands out, HTML links + Underlined = { fg = theme.syn.special1, underline = true }, + Bold = { bold = true }, + Italic = { italic = true }, + + -- *Ignore left blank, hidden |hl-Ignore| + Ignore = { link = "NonText" }, + + -- *Error any erroneous construct + Error = { fg = theme.diag.error }, + + -- *Todo anything that needs extra attention; mostly the keywords TODO FIXME WARNING and XXX + Todo = { fg = theme.ui.fg_reverse, bg = theme.diag.info, bold = true }, + + qfLineNr = { link = "lineNr" }, + qfFileName = { link = "Directory" }, + + -- htmlH1 = {}, + -- htmlH2 = {}, + + -- mkdHeading = {}, + -- mkdCode = {}, + -- mkdCodeDelimiter = {}, + -- mkdCodeStart = {}, + -- mkdCodeEnd = {}, + -- mkdLink = {}, + + -- markdownHeadingDelimiter = {}, + markdownCode = { fg = theme.syn.string }, + markdownCodeBlock = { fg = theme.syn.string }, + markdownEscape = { fg = "NONE" }, + -- markdownH1 = {}, + -- markdownH2 = {}, + -- markdownLinkText = {}, + } +end + +return M diff --git a/lua/kanso/highlights/treesitter.lua b/lua/kanso/highlights/treesitter.lua new file mode 100644 index 0000000..45c1efc --- /dev/null +++ b/lua/kanso/highlights/treesitter.lua @@ -0,0 +1,165 @@ +local M = {} + +---@param colors KansoColors +---@param config? KansoConfig +function M.setup(colors, config) + config = config or require("kanso").config + local theme = colors.theme + return { + -- @variable various variable names + ["@variable"] = { fg = theme.ui.fg }, + -- @variable.builtin (Special) built-in variable names (e.g. `this`, `self`) + ["@variable.builtin"] = { fg = theme.syn.special2, italic = true }, + -- @variable.parameter parameters of a function + ["@variable.parameter"] = { fg = theme.syn.parameter }, + -- @variable.parameter.builtin special parameters (e.g. `_`, `it`) + -- @variable.member object and struct fields + ["@variable.member"] = { fg = theme.syn.identifier }, + -- + -- @constant (Constant) constant identifiers + -- @constant.builtin built-in constant values + -- @constant.macro constants defined by the preprocessor + -- + -- @module (Structure) modules or namespaces + -- @module.builtin built-in modules or namespaces + -- @label `GOTO` and other labels (e.g. `label:` in C), including heredoc labels + -- + -- @string string literals + -- @string.documentation string documenting code (e.g. Python docstrings) + -- @string.regexp regular expressions + ["@string.regexp"] = { fg = theme.syn.regex }, + -- @string.escape escape sequences + ["@string.escape"] = { fg = theme.syn.regex }, + -- @string.special other special strings (e.g. dates) + -- @string.special.symbol symbols or atoms + ["@string.special.symbol"] = { fg = theme.syn.identifier }, + -- @string.special.path filenames + -- @string.special.url (Underlined) URIs (e.g. hyperlinks) + ["@string.special.url"] = { fg = theme.syn.special1, undercurl = true }, + -- @character character literals + -- @character.special special characters (e.g. wildcards) + -- + -- @boolean boolean literals + -- @number numeric literals + -- @number.float floating-point number literals + -- + -- @type type or class definitions and annotations + -- @type.builtin built-in types + -- @type.definition identifiers in type definitions (e.g. `typedef ` in C) + -- + -- @attribute attribute annotations (e.g. Python decorators, Rust lifetimes) + ["@attribute"] = { link = "Constant" }, + -- @attribute.builtin builtin annotations (e.g. `@property` in Python) + -- @property the key in key/value pairs + -- + -- @function function definitions + -- @function.builtin built-in functions + -- @function.call function calls + -- @function.macro preprocessor macros + -- + -- @function.method method definitions + -- @function.method.call method calls + -- + -- @constructor constructor calls and definitions + ["@constructor"] = { fg = theme.syn.special1 }, + ["@constructor.lua"] = { fg = theme.syn.keyword }, + -- @operator symbolic operators (e.g. `+`, `*`) + ["@operator"] = { link = "Operator" }, + -- + -- @keyword keywords not fitting into specific categories + -- @keyword.coroutine keywords related to coroutines (e.g. `go` in Go, `async/await` in Python) + -- @keyword.function keywords that define a function (e.g. `func` in Go, `def` in Python) + -- @keyword.operator operators that are English words (e.g. `and`, `or`) + ["@keyword.operator"] = { fg = theme.syn.operator }, + -- @keyword.import keywords for including modules (e.g. `import`, `from` in Python) + ["@keyword.import"] = { link = "PreProc" }, + -- @keyword.type keywords defining composite types (e.g. `struct`, `enum`) + -- @keyword.modifier keywords defining type modifiers (e.g. `const`, `static`, `public`) + -- @keyword.repeat keywords related to loops (e.g. `for`, `while`) + -- @keyword.return keywords like `return` and `yield` + ["@keyword.return"] = vim.tbl_extend("force", { fg = theme.syn.special3 }, config.keywordStyle), + -- @keyword.debug keywords related to debugging + -- @keyword.exception keywords related to exceptions (e.g. `throw`, `catch`) + ["@keyword.exception"] = vim.tbl_extend("force", { fg = theme.syn.special3 }, config.statementStyle), + + ["@keyword.luap"] = { link = "@string.regex" }, + -- + -- @keyword.conditional keywords related to conditionals (e.g. `if`, `else`) + -- @keyword.conditional.ternary ternary operator (e.g. `?`, `:`) + -- + -- @keyword.directive various preprocessor directives and shebangs + -- @keyword.directive.define preprocessor definition directives + -- + -- @punctuation.delimiter delimiters (e.g. `;`, `.`, `,`) + ["@punctuation.delimiter"] = { fg = theme.syn.punct }, + -- @punctuation.bracket brackets (e.g. `()`, `{}`, `[]`) + ["@punctuation.bracket"] = { fg = theme.syn.punct }, + -- @punctuation.special special symbols (e.g. `{}` in string interpolation) + ["@punctuation.special"] = { fg = theme.syn.special1 }, + -- + -- @comment line and block comments + -- @comment.documentation comments documenting code + -- + -- @comment.error error-type comments (e.g. `ERROR`, `FIXME`, `DEPRECATED`) + ["@comment.error"] = { fg = theme.ui.fg, bg = theme.diag.error, bold = true }, + -- @comment.warning warning-type comments (e.g. `WARNING`, `FIX`, `HACK`) + ["@comment.warning"] = { fg = theme.ui.fg_reverse, bg = theme.diag.warning, bold = true }, + -- @comment.todo todo-type comments (e.g. `TODO`, `WIP`) + -- @comment.note note-type comments (e.g. `NOTE`, `INFO`, `XXX`) + ["@comment.note"] = { fg = theme.ui.fg_reverse, bg = theme.diag.hint, bold = true }, + -- + -- @markup.strong bold text + ["@markup.strong"] = { bold = true }, + -- @markup.italic italic text + ["@markup.italic"] = { italic = true }, + -- @markup.strikethrough struck-through text + ["@markup.strikethrough"] = { strikethrough = true }, + -- @markup.underline underlined text (only for literal underline markup!) + ["@markup.underline"] = { underline = true }, + -- + -- @markup.heading headings, titles (including markers) + ["@markup.heading"] = { link = "Function" }, + -- @markup.heading.1 top-level heading + -- @markup.heading.2 section heading + -- @markup.heading.3 subsection heading + -- @markup.heading.4 and so on + -- @markup.heading.5 and so forth + -- @markup.heading.6 six levels ought to be enough for anybody + -- + -- @markup.quote block quotes + ["@markup.quote"] = { link = "@variable.parameter" }, + -- @markup.math math environments (e.g. `$ ... $` in LaTeX) + ["@markup.math"] = { link = "Constant" }, + -- @markup.environment environments (e.g. in LaTeX) + ["@markup.environment"] = { link = "Keyword" }, + -- + -- @markup.link text references, footnotes, citations, etc. + -- @markup.link.label link, reference descriptions + -- @markup.link.url URL-style links + ["@markup.link.url"] = { link = "@string.special.url" }, + -- @markup.raw literal or verbatim text (e.g. inline code) + ["@markup.raw"] = { link = "String" }, + -- @markup.raw.block literal or verbatim text as a stand-alone block + -- + -- @markup.list list markers + -- @markup.list.checked checked todo-style list markers + -- @markup.list.unchecked unchecked todo-style list markers + -- + -- @diff.plus added text (for diff files) + ["@diff.plus"] = { fg = theme.vcs.added }, + -- @diff.minus deleted text (for diff files) + ["@diff.minus"] = { fg = theme.vcs.removed }, + -- @diff.delta changed text (for diff files) + ["@diff.delta"] = { fg = theme.vcs.changed }, + -- + -- @tag XML-style tag names (e.g. in XML, HTML, etc.) + -- @tag.builtin XML-style tag names (e.g. HTML5 tags) + -- @tag.attribute XML-style tag attributes + ["@tag.attribute"] = { fg = theme.syn.identifier }, + -- @tag.delimiter XML-style tag delimiters + ["@tag.delimiter"] = { fg = theme.syn.punct }, + } +end + +return M +--vim: fdm=marker diff --git a/lua/kanso/init.lua b/lua/kanso/init.lua new file mode 100644 index 0000000..d4ef74a --- /dev/null +++ b/lua/kanso/init.lua @@ -0,0 +1,95 @@ +local M = {} + +---@alias ColorSpec string RGB Hex string +---@alias ColorTable table +---@alias KansoColorsSpec { palette: ColorTable, theme: ColorTable } +---@alias KansoColors { palette: PaletteColors, theme: ThemeColors } + +--- default config +---@class KansoConfig +M.config = { + undercurl = true, + commentStyle = { italic = true }, + functionStyle = {}, + keywordStyle = { italic = true }, + statementStyle = {}, + typeStyle = {}, + transparent = false, + dimInactive = false, + terminalColors = true, + colors = { theme = { zen = {}, pearl = {}, ink = {}, all = {} }, palette = {} }, + ---@type fun(colors: KansoColorsSpec): table + overrides = function() + return {} + end, + ---@type { dark: string, light: string } + background = { dark = "ink", light = "pearl" }, + theme = "ink", + compile = false, +} + +local function check_config(config) + local err + return not err +end + +--- update global configuration with user settings +---@param config? KansoConfig user configuration +function M.setup(config) + if check_config(config) then + M.config = vim.tbl_deep_extend("force", M.config, config or {}) + else + vim.notify("Kanso: Errors found while loading user config. Using default config.", vim.log.levels.ERROR) + end +end + +--- load the colorscheme +---@param theme? string +function M.load(theme) + local utils = require("kanso.utils") + + theme = theme or M.config.background[vim.o.background] or M.config.theme + M._CURRENT_THEME = theme + + if vim.g.colors_name then + vim.cmd("hi clear") + end + + vim.g.colors_name = "kanso" + vim.o.termguicolors = true + + if M.config.compile then + if utils.load_compiled(theme) then + return + end + + M.compile() + utils.load_compiled(theme) + else + local colors = require("kanso.colors").setup({ theme = theme, colors = M.config.colors }) + local highlights = require("kanso.highlights").setup(colors, M.config) + require("kanso.highlights").highlight(highlights, M.config.terminalColors and colors.theme.term or {}) + end +end + +function M.compile() + for theme, _ in pairs(require("kanso.themes")) do + local colors = require("kanso.colors").setup({ theme = theme, colors = M.config.colors }) + local highlights = require("kanso.highlights").setup(colors, M.config) + require("kanso.utils").compile(theme, highlights, M.config.terminalColors and colors.theme.term or {}) + end +end + +vim.api.nvim_create_user_command("KansoCompile", function() + for mod, _ in pairs(package.loaded) do + if mod:match("^kanso%.") then + package.loaded[mod] = nil + end + end + M.compile() + vim.notify("Kanso: compiled successfully!", vim.log.levels.INFO) + M.load(M._CURRENT_THEME) + vim.api.nvim_exec_autocmds("ColorScheme", { modeline = false }) +end, {}) + +return M diff --git a/lua/kanso/lib/color.lua b/lua/kanso/lib/color.lua new file mode 100644 index 0000000..24f5249 --- /dev/null +++ b/lua/kanso/lib/color.lua @@ -0,0 +1,84 @@ +local hsluv = require("kanso.lib.hsluv") + +---@class HSLuvColor +local Color = {} +local Color_mt = { + __index = Color, + __tostring = function(self) + return self:to_hex() + end, +} + +local function none_to_hex() + return "NONE" +end + +---Create a new HSLuv color object from a RGB hex string +---@param hex string Hex color +---@return HSLuvColor +function Color.new(hex) + if hex:lower() == "none" then + return setmetatable({ H = 0, S = 0, L = 0, to_hex = none_to_hex }, Color_mt) + end + local H, S, L = unpack(hsluv.hex_to_hsluv(hex)) + return setmetatable({ H = H, S = S, L = L }, Color_mt) +end + +function Color:to_rgb() + return hsluv.hsluv_to_rgb({ self.H, self.S, self.L }) +end + +function Color:to_hex() + return hsluv.hsluv_to_hex({ self.H, self.S, self.L }) +end + +local function blendRGB(a, b, r) + local c = {} + for i = 1, 3 do + c[i] = math.sqrt((1 - r) * math.pow(a[i], 2) + r * math.pow(b[i], 2)) + end + return c +end + +--- Blend Color with another color (hex) +---@param b string Hex color +---@param r number Blend ratio [0, 1] +---@return HSLuvColor +function Color:blend(b, r) + if b:lower() == "none" then + return self + end + local c = blendRGB(self:to_rgb(), hsluv.hex_to_rgb(b), r) + self.H, self.S, self.L = unpack(hsluv.rgb_to_hsluv(c)) + return self +end + +---@param r number Brighten ratio [-1, 1] +---@param bg? string background color, if light, r = -r +---@return HSLuvColor +function Color:brighten(r, bg) + if bg and bg:lower() == "none" then + return self + end + local bg_lightness = bg and hsluv.hex_to_hsluv(bg)[3] or 0 + r = bg_lightness > 50 and -r or r + + local lspace = r > 0 and 100 - self.L or self.L + self.L = self.L + lspace * r + return self +end + +---@param r number Saturate ratio [-1, 1] +---@return HSLuvColor +function Color:saturate(r) + local lspace = r > 0 and 100 - self.S or self.S + self.S = self.S + lspace * r + return self +end + +local M = {} +return setmetatable(M, { + __call = function(_, ...) + return Color.new(...) + end, +}) diff --git a/lua/kanso/lib/hsluv.lua b/lua/kanso/lib/hsluv.lua new file mode 100644 index 0000000..e076856 --- /dev/null +++ b/lua/kanso/lib/hsluv.lua @@ -0,0 +1,347 @@ +--[[ +Lua implementation of HSLuv and HPLuv color spaces +Homepage: http://www.hsluv.org/ + +Copyright (C) 2019 Alexei Boronine + +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. +]] + +local hsluv = {} + +local hexChars = "0123456789abcdef" + + +local distance_line_from_origin = function(line) + return math.abs(line.intercept) / math.sqrt((line.slope ^ 2) + 1) +end + +local length_of_ray_until_intersect = function(theta, line) + return line.intercept / (math.sin(theta) - line.slope * math.cos(theta)) +end + +hsluv.get_bounds = function(l) + local result = {}; + local sub2; + local sub1 = ((l + 16) ^ 3) / 1560896; + if sub1 > hsluv.epsilon then + sub2 = sub1; + else + sub2 = l / hsluv.kappa; + end + + for i = 1, 3 do + local m1 = hsluv.m[i][1]; + local m2 = hsluv.m[i][2]; + local m3 = hsluv.m[i][3]; + + for t = 0, 1 do + local top1 = (284517 * m1 - 94839 * m3) * sub2; + local top2 = (838422 * m3 + 769860 * m2 + 731718 * m1) * l * sub2 - 769860 * t * l; + local bottom = (632260 * m3 - 126452 * m2) * sub2 + 126452 * t; + table.insert(result, { + slope = top1 / bottom, + intercept = top2 / bottom + }) + end; + end; + return result +end + +hsluv.max_safe_chroma_for_l = function(l) + local bounds = hsluv.get_bounds(l); + local min = 1.7976931348623157e+308; + + for i = 1, 6 do + local length = distance_line_from_origin(bounds[i]); + if length >= 0 then + min = math.min(min, length); + end; + end; + return min; +end + +hsluv.max_safe_chroma_for_lh = function(l, h) + local hrad = h / 360 * math.pi * 2; + local bounds = hsluv.get_bounds(l); + local min = 1.7976931348623157e+308; + + for i = 1, 6 do + local bound = bounds[i]; + local length = length_of_ray_until_intersect(hrad, bound); + if length >= 0 then + min = math.min(min, length); + end; + end; + return min +end + +hsluv.dot_product = function(a, b) + local sum = 0; + for i = 1, 3 do + sum = sum + a[i] * b[i]; + end; + return sum +end + +hsluv.from_linear = function(c) + if c <= 0.0031308 then + return 12.92 * c + else + return 1.055 * (c ^ 0.416666666666666685) - 0.055 + end; +end + +hsluv.to_linear = function(c) + if c > 0.04045 then + return ((c + 0.055) / 1.055) ^ 2.4 + else + return c / 12.92 + end; +end + +hsluv.xyz_to_rgb = function(tuple) + return { + hsluv.from_linear(hsluv.dot_product(hsluv.m[1], tuple)), + hsluv.from_linear(hsluv.dot_product(hsluv.m[2], tuple)), + hsluv.from_linear(hsluv.dot_product(hsluv.m[3], tuple)) + } +end + +hsluv.rgb_to_xyz = function(tuple) + local rgbl = { + hsluv.to_linear(tuple[1]), + hsluv.to_linear(tuple[2]), + hsluv.to_linear(tuple[3]) + }; + return { + hsluv.dot_product(hsluv.minv[1], rgbl), + hsluv.dot_product(hsluv.minv[2], rgbl), + hsluv.dot_product(hsluv.minv[3], rgbl) + } +end + +hsluv.y_to_l = function(Y) + if Y <= hsluv.epsilon then + return Y / hsluv.refY * hsluv.kappa + else + return 116 * ((Y / hsluv.refY) ^ 0.333333333333333315) - 16 + end; +end + +hsluv.l_to_y = function(L) + if L <= 8 then + return hsluv.refY * L / hsluv.kappa + else + return hsluv.refY * (((L + 16) / 116) ^ 3) + end; +end + +hsluv.xyz_to_luv = function(tuple) + local X = tuple[1]; + local Y = tuple[2]; + local divider = X + 15 * Y + 3 * tuple[3]; + local varU = 4 * X; + local varV = 9 * Y; + if divider ~= 0 then + varU = varU / divider; + varV = varV / divider; + else + varU = 0; + varV = 0; + end + local L = hsluv.y_to_l(Y); + if L == 0 then + return { 0, 0, 0 } + end; + return { L, 13 * L * (varU - hsluv.refU), 13 * L * (varV - hsluv.refV) } +end + +hsluv.luv_to_xyz = function(tuple) + local L = tuple[1]; + local U = tuple[2]; + local V = tuple[3]; + if L == 0 then + return { 0, 0, 0 } + end; + local varU = U / (13 * L) + hsluv.refU; + local varV = V / (13 * L) + hsluv.refV; + local Y = hsluv.l_to_y(L); + local X = 0 - (9 * Y * varU) / ((((varU - 4) * varV) - varU * varV)); + return { X, Y, (9 * Y - 15 * varV * Y - varV * X) / (3 * varV) } +end + +hsluv.luv_to_lch = function(tuple) + local L = tuple[1]; + local U = tuple[2]; + local V = tuple[3]; + local C = math.sqrt(U * U + V * V); + local H + if C < 0.00000001 then + H = 0; + else + H = math.atan2(V, U) * 180.0 / 3.1415926535897932; + if H < 0 then + H = 360 + H; + end; + end; + return { L, C, H } +end + +hsluv.lch_to_luv = function(tuple) + local L = tuple[1]; + local C = tuple[2]; + local Hrad = tuple[3] / 360.0 * 2 * math.pi; + return { L, math.cos(Hrad) * C, math.sin(Hrad) * C }; +end + +hsluv.hsluv_to_lch = function(tuple) + local H = tuple[1]; + local S = tuple[2]; + local L = tuple[3]; + if L > 99.9999999 then + return { 100, 0, H } + end; + if L < 0.00000001 then + return { 0, 0, H } + end; + return { L, hsluv.max_safe_chroma_for_lh(L, H) / 100 * S, H } +end + +hsluv.lch_to_hsluv = function(tuple) + local L = tuple[1]; + local C = tuple[2]; + local H = tuple[3]; + local max_chroma = hsluv.max_safe_chroma_for_lh(L, H) + if L > 99.9999999 then + return { H, 0, 100 } + end; + if L < 0.00000001 then + return { H, 0, 0 } + end; + + return { H, C / max_chroma * 100, L } +end + +hsluv.hpluv_to_lch = function(tuple) + local H = tuple[1]; + local S = tuple[2]; + local L = tuple[3]; + if L > 99.9999999 then + return { 100, 0, H } + end; + if L < 0.00000001 then + return { 0, 0, H } + end; + return { L, hsluv.max_safe_chroma_for_l(L) / 100 * S, H } +end + +hsluv.lch_to_hpluv = function(tuple) + local L = tuple[1]; + local C = tuple[2]; + local H = tuple[3]; + if L > 99.9999999 then + return { H, 0, 100 } + end; + if L < 0.00000001 then + return { H, 0, 0 } + end; + return { H, C / hsluv.max_safe_chroma_for_l(L) * 100, L } +end + +hsluv.rgb_to_hex = function(tuple) + local h = "#"; + for i = 1, 3 do + local c = math.floor(tuple[i] * 255 + 0.5); + local digit2 = math.fmod(c, 16); + local x = (c - digit2) / 16; + local digit1 = math.floor(x); + h = h .. string.sub(hexChars, digit1 + 1, digit1 + 1) + h = h .. string.sub(hexChars, digit2 + 1, digit2 + 1) + end; + return h +end + +hsluv.hex_to_rgb = function(hex) + hex = string.lower(hex) + local ret = {} + for i = 0, 2 do + local char1 = string.sub(hex, i * 2 + 2, i * 2 + 2); + local char2 = string.sub(hex, i * 2 + 3, i * 2 + 3); + local digit1 = string.find(hexChars, char1) - 1 + local digit2 = string.find(hexChars, char2) - 1 + ret[i + 1] = (digit1 * 16 + digit2) / 255.0; + end; + return ret +end + +hsluv.lch_to_rgb = function(tuple) + return hsluv.xyz_to_rgb(hsluv.luv_to_xyz(hsluv.lch_to_luv(tuple))) +end + +hsluv.rgb_to_lch = function(tuple) + return hsluv.luv_to_lch(hsluv.xyz_to_luv(hsluv.rgb_to_xyz(tuple))) +end + +hsluv.hsluv_to_rgb = function(tuple) + return hsluv.lch_to_rgb(hsluv.hsluv_to_lch(tuple)) +end + +hsluv.rgb_to_hsluv = function(tuple) + return hsluv.lch_to_hsluv(hsluv.rgb_to_lch(tuple)) +end + +hsluv.hpluv_to_rgb = function(tuple) + return hsluv.lch_to_rgb(hsluv.hpluv_to_lch(tuple)) +end + +hsluv.rgb_to_hpluv = function(tuple) + return hsluv.lch_to_hpluv(hsluv.rgb_to_lch(tuple)) +end + +hsluv.hsluv_to_hex = function(tuple) + return hsluv.rgb_to_hex(hsluv.hsluv_to_rgb(tuple)) +end + +hsluv.hpluv_to_hex = function(tuple) + return hsluv.rgb_to_hex(hsluv.hpluv_to_rgb(tuple)) +end + +hsluv.hex_to_hsluv = function(s) + return hsluv.rgb_to_hsluv(hsluv.hex_to_rgb(s)) +end + +hsluv.hex_to_hpluv = function(s) + return hsluv.rgb_to_hpluv(hsluv.hex_to_rgb(s)) +end + +hsluv.m = { + { 3.240969941904521, -1.537383177570093, -0.498610760293 }, + { -0.96924363628087, 1.87596750150772, 0.041555057407175 }, + { 0.055630079696993, -0.20397695888897, 1.056971514242878 } +} +hsluv.minv = { + { 0.41239079926595, 0.35758433938387, 0.18048078840183 }, + { 0.21263900587151, 0.71516867876775, 0.072192315360733 }, + { 0.019330818715591, 0.11919477979462, 0.95053215224966 } +} +hsluv.refY = 1.0 +hsluv.refU = 0.19783000664283 +hsluv.refV = 0.46831999493879 +hsluv.kappa = 903.2962962 +hsluv.epsilon = 0.0088564516 + +return hsluv diff --git a/lua/kanso/themes.lua b/lua/kanso/themes.lua new file mode 100644 index 0000000..296e95b --- /dev/null +++ b/lua/kanso/themes.lua @@ -0,0 +1,416 @@ +local c = require("kanso.lib.color") + +--TODO: +--PreProc needs its own color +--parameter and field should be different +---@class SyntaxElements +---@field string ColorSpec +---@field variable ColorSpec +---@field number ColorSpec +---@field constant ColorSpec +---@field identifier ColorSpec +---@field parameter ColorSpec +---@field fun ColorSpec +---@field statement ColorSpec +---@field keyword ColorSpec +---@field operator ColorSpec +---@field preproc ColorSpec +---@field type ColorSpec +---@field regex ColorSpec +---@field deprecated ColorSpec +---@field comment ColorSpec +---@field punct ColorSpec +---@field special1 ColorSpec +---@field special2 ColorSpec +---@field special3 ColorSpec + +---@class DiagnosticsElements +---@field error ColorSpec +---@field ok ColorSpec +---@field warning ColorSpec +---@field info ColorSpec +---@field hint ColorSpec +-- +---@class DiffElements +---@field add ColorSpec +---@field delete ColorSpec +---@field change ColorSpec +---@field text ColorSpec + +---@class VCSElements +---@field added ColorSpec +---@field removed ColorSpec +---@field changed ColorSpec + +---@class UiElements +---@field none ColorSpec +---@field fg ColorSpec Default foreground +---@field fg_dim ColorSpec Dimmed foreground +---@field fg_reverse ColorSpec +---@field bg_dim ColorSpec Dimmed background +---@field bg_m3 ColorSpec +---@field bg_m2 ColorSpec +---@field bg_m1 ColorSpec +---@field bg ColorSpec Default background +---@field bg_p1 ColorSpec Lighter background ColorColumn, Folded, Gutter +---@field bg_p2 ColorSpec Lighter background Cursor{Line,Column}, TabLineSel (Selected Items) +---@field bg_gutter ColorSpec {Sign,Fold}Column, LineNr +---@field special ColorSpec SpecialKey +---@field nontext ColorSpec LineNr, NonText +---@field whitespace ColorSpec Whitespace +---@field bg_search ColorSpec +---@field bg_visual ColorSpec +---@field cursor_line_nr_foreground ColorSpec +---@field cursor_line_nr_active_foreground ColorSpec +---@field cursor_bg ColorSpec +---@field cursor_fg ColorSpec +---@field pmenu MenuElements +---@field float FloatElements + +---@class FloatElements +---@field fg ColorSpec +---@field bg ColorSpec +---@field fg_border ColorSpec +---@field bg_border ColorSpec + +---@class MenuElements +---@field bg ColorSpec +---@field fg ColorSpec +---@field fg_sel ColorSpec +---@field bg_sel ColorSpec +---@field bg_sbar ColorSpec +---@field bg_thumb ColorSpec + +---@class ThemeColors +---@field syn SyntaxElements +---@field diag DiagnosticsElements +---@field vcs VCSElements +---@field diff DiffElements +---@field ui UiElements +---@field term ColorSpec[] + +return { + ---@param palette PaletteColors + ---@return ThemeColors + zen = function(palette) + return { + ui = { + fg = palette.inkWhite, + fg_dim = palette.oldWhite, + fg_reverse = palette.zenBlue1, + + bg_dim = palette.zen0, + bg_gutter = palette.zen0, + + bg_m3 = palette.zen0, + bg_m2 = palette.zen0, + bg_m1 = palette.zen0, + bg = palette.zen0, + bg_p1 = palette.zen1, + bg_p2 = palette.zen2, + + special = palette.inkGray3, + whitespace = palette.inkAsh, + nontext = palette.inkAsh, + + bg_visual = palette.inkBlack2, + bg_search = palette.zenBlue2, + + cursor_line_nr_foreground = palette.inkGray3, + cursor_line_nr_active_foreground = palette.fujiWhite, + cursor_bg = palette.fujiWhite, + cursor_fg = palette.zen0, + + pmenu = { + fg = palette.fujiWhite, + fg_sel = "NONE", + bg = palette.zenBlue1, + bg_sel = palette.zenBlue2, + bg_thumb = palette.zenBlue2, + bg_sbar = palette.zenBlue1, + }, + + float = { + fg = palette.oldWhite, + bg = palette.zen0, + fg_border = palette.zen3, + bg_border = palette.zen0, + }, + }, + syn = { + string = palette.inkGreen2, + variable = "NONE", + number = palette.inkPink, + constant = palette.inkOrange, + identifier = palette.inkViolet, + parameter = palette.inkGray1, + fun = palette.inkBlue2, + statement = palette.inkViolet, + keyword = palette.inkViolet, + operator = palette.inkGray1, + preproc = palette.inkGray1, + type = palette.inkAqua, + regex = palette.inkRed, + deprecated = palette.katanaGray, + punct = palette.inkGray1, + comment = palette.inkGray2, + special1 = palette.inkYellow, + special2 = palette.inkViolet, + special3 = palette.inkViolet, + }, + diag = { + error = palette.samuraiRed, + ok = palette.springGreen, + warning = palette.roninYellow, + info = palette.inkBlue, + hint = palette.zenAqua1, + }, + diff = { + add = palette.winterGreen, + delete = palette.winterRed, + change = palette.winterBlue, + text = palette.winterYellow, + }, + vcs = { + added = palette.autumnGreen, + removed = palette.autumnRed, + changed = palette.autumnYellow, + }, + term = { + palette.zen0, -- black + palette.inkRed, -- red + palette.inkGreen2, -- green + palette.inkYellow, -- yellow + palette.inkBlue2, -- blue + palette.inkPink, -- magenta + palette.inkWhite, -- cyan + palette.oldWhite, -- white + palette.inkGray1, -- bright black + palette.zenRed, -- bright red + palette.inkGreen, -- bright green + palette.carpYellow, -- bright yellow + palette.springBlue, -- bright blue + palette.springViolet1, -- bright magenta + palette.zenAqua2, -- bright cyan + palette.inkWhite, -- bright white + palette.inkOrange, -- extended color 1 + palette.inkOrange2, -- extended color 2 + }, + } + end, + ---@param palette PaletteColors + ---@return ThemeColors + ink = function(palette) + return { + ui = { + fg = palette.inkWhite, + fg_dim = palette.oldWhite, + fg_reverse = palette.zenBlue1, + + bg_dim = palette.inkBlack0, + bg_gutter = palette.inkBlack0, + + bg_m3 = palette.inkBlack0, + bg_m2 = palette.inkBlack0, + bg_m1 = palette.inkBlack0, + bg = palette.inkBlack0, + bg_p1 = palette.inkBlack1, + bg_p2 = palette.inkBlack2, + + special = palette.inkGray3, + whitespace = palette.inkAsh, + nontext = palette.inkAsh, + + bg_visual = palette.inkBlack3, + bg_search = palette.zenBlue2, + + cursor_line_nr_foreground = palette.inkGray3, + cursor_line_nr_active_foreground = palette.fujiWhite, + cursor_bg = palette.fujiWhite, + cursor_fg = palette.inkBlack0, + + pmenu = { + fg = palette.fujiWhite, + fg_sel = "NONE", + bg = palette.zenBlue1, + bg_sel = palette.zenBlue2, + bg_thumb = palette.zenBlue2, + bg_sbar = palette.zenBlue1, + }, + + float = { + fg = palette.oldWhite, + bg = palette.inkBlack0, + fg_border = palette.inkBlack3, + bg_border = palette.inkBlack0, + }, + }, + syn = { + string = palette.inkGreen2, + variable = "NONE", + number = palette.inkPink, + constant = palette.inkOrange, + identifier = palette.inkViolet, + parameter = palette.inkGray1, + fun = palette.inkBlue2, + statement = palette.inkViolet, + keyword = palette.inkViolet, + operator = palette.inkGray1, + preproc = palette.inkGray1, + type = palette.inkAqua, + regex = palette.inkRed, + deprecated = palette.katanaGray, + punct = palette.inkGray1, + comment = palette.inkGray2, + special1 = palette.inkYellow, + special2 = palette.inkViolet, + special3 = palette.inkViolet, + }, + diag = { + error = palette.samuraiRed, + ok = palette.springGreen, + warning = palette.roninYellow, + info = palette.inkBlue, + hint = palette.zenAqua1, + }, + diff = { + add = palette.winterGreen, + delete = palette.winterRed, + change = palette.winterBlue, + text = palette.winterYellow, + }, + vcs = { + added = palette.autumnGreen, + removed = palette.autumnRed, + changed = palette.autumnYellow, + }, + term = { + palette.inkBlack0, -- black + palette.inkRed, -- red + palette.inkGreen2, -- green + palette.inkYellow, -- yellow + palette.inkBlue2, -- blue + palette.inkPink, -- magenta + palette.inkWhite, -- cyan + palette.oldWhite, -- white + palette.inkGray1, -- bright black + palette.zenRed, -- bright red + palette.inkGreen, -- bright green + palette.carpYellow, -- bright yellow + palette.springBlue, -- bright blue + palette.springViolet1, -- bright magenta + palette.zenAqua2, -- bright cyan + palette.inkWhite, -- bright white + palette.inkOrange, -- extended color 1 + palette.inkOrange2, -- extended color 2 + }, + } + end, + ---@param palette PaletteColors + ---@return ThemeColors + pearl = function(palette) + return { + ui = { + fg = palette.pearlInk0, + fg_dim = palette.pearlInk0, + fg_reverse = palette.pearlGray, + + bg_dim = palette.pearlWhite0, + bg_gutter = palette.pearlWhite0, + + bg_m3 = palette.pearlWhite0, + bg_m2 = palette.pearlWhite0, + bg_m1 = palette.pearlWhite0, + bg = palette.pearlWhite0, + bg_p1 = palette.pearlWhite1, + bg_p2 = palette.pearlWhite1, + + nontext = palette.pearlViolet1, + whitespace = palette.pearlViolet1, + special = palette.pearlViolet2, + + bg_visual = palette.pearlWhite2, + bg_search = palette.pearlBlue2, + + cursor_line_nr_foreground = palette.pearlGray4, + cursor_line_nr_active_foreground = palette.inkBlack2, + cursor_bg = palette.fujiWhite, + cursor_fg = palette.inkBlack2, + + pmenu = { + fg = palette.pearlInk2, + fg_sel = "NONE", -- This is important to make highlights pass-through + bg = palette.pearlBlue1, + bg_sel = palette.pearlBlue3, + bg_sbar = palette.pearlBlue1, + bg_thumb = palette.pearlBlue2, + }, + float = { + fg = palette.pearlInk2, + bg = palette.pearlWhite0, + fg_border = palette.pearlGray2, + bg_border = palette.pearlWhite0, + }, + }, + syn = { + string = palette.pearlGreen, + variable = "NONE", + number = palette.pearlPink, + constant = palette.pearlOrange, + identifier = palette.pearlViolet4, + parameter = palette.pearlBlue5, + fun = palette.pearlBlue4, + statement = palette.pearlViolet4, + keyword = palette.pearlViolet4, + operator = palette.pearlGray3, + preproc = palette.pearlGray2, + type = palette.pearlAqua, + regex = palette.pearlYellow2, + deprecated = palette.pearlGray3, + comment = palette.pearlGray3, + punct = palette.pearlGray3, + special1 = palette.pearlYellow2, + special2 = palette.pearlViolet4, + special3 = palette.pearlViolet4, + }, + vcs = { + added = palette.pearlGreen2, + removed = palette.pearlRed2, + changed = palette.pearlYellow3, + }, + diff = { + add = palette.pearlGreen3, + delete = palette.pearlRed4, + change = palette.pearlCyan, + text = palette.pearlYellow4, + }, + diag = { + error = palette.pearlRed3, + ok = palette.pearlGreen, + warning = palette.pearlOrange2, + info = palette.pearlTeal3, + hint = palette.pearlAqua2, + }, + term = { + palette.inkBlack2, -- black + palette.pearlRed, -- red + palette.pearlGreen, -- green + palette.pearlYellow, -- yellow + palette.pearlBlue4, -- blue + palette.pearlPink, -- magenta + palette.pearlAqua, -- cyan + palette.pearlInk0, -- white + palette.pearlGray3 , -- bright black + palette.pearlRed2, -- bright red + palette.pearlGreen2, -- bright green + palette.pearlYellow2, -- bright yellow + palette.pearlTeal2, -- bright blue + palette.pearlViolet4, -- bright magenta + palette.pearlAqua2, -- bright cyan + palette.pearlInk2, -- bright white + palette.pearlOrange2, -- extended color 1 + palette.pearlRed3, -- extended color 2 + }, + } + end, +} diff --git a/lua/kanso/utils.lua b/lua/kanso/utils.lua new file mode 100644 index 0000000..5932de0 --- /dev/null +++ b/lua/kanso/utils.lua @@ -0,0 +1,60 @@ +local M = {} +local PATH_SEP = vim.loop.os_uname().version:match("Windows") and "\\" or "/" + +local get_compiled_path = function(theme) + return table.concat({vim.fn.stdpath("state"), "kanso", theme .. "_compiled.lua"}, PATH_SEP) +end + +---@return string theme +function M.get_theme_from_bg_opt() + local config = require("kanso").config + return config.theme[vim.o.background] or config.theme.default +end + +---@param theme string +---@param highlights table +---@param termcolors table +function M.compile(theme, highlights, termcolors) + vim.loop.fs_mkdir(vim.fn.stdpath("state") .. PATH_SEP .. "kanso", 448) + + local fname = get_compiled_path(theme) + local file, err = io.open(fname, "wb") + if not file or err then + vim.notify("Kanso: Error writing " .. fname .. ":\n" .. err, vim.log.levels.ERROR) + return + end + + local lines = { + "require'kanso'.compiled = string.dump(function()", + "local g = vim.g", + "local nvim_set_hl = vim.api.nvim_set_hl", + } + local inspect = vim.inspect + for hl, spec in pairs(highlights) do + if next(spec) then + table.insert(lines, ('nvim_set_hl(0, "%s", %s)'):format(hl, inspect(spec):gsub("%s", ""))) + end + for i, tcolor in ipairs(termcolors) do + table.insert(lines, ('g["terminal_color_%d"] = "%s"'):format(i - 1, tcolor)) + end + end + table.insert(lines, "end)") + + local blob = table.concat(lines, "\n") + assert(loadstring(blob, "=(compile)"))() + file:write(require("kanso").compiled) + file:close() +end + +---@param theme string +---@return boolean status +function M.load_compiled(theme) + local f = loadfile(get_compiled_path(theme)) + if f then + f() + return true + end + return false +end + +return M diff --git a/lua/lualine/themes/kanso.lua b/lua/lualine/themes/kanso.lua new file mode 100644 index 0000000..a130c49 --- /dev/null +++ b/lua/lualine/themes/kanso.lua @@ -0,0 +1,43 @@ +local theme = require("kanso.colors").setup().theme + +local kanso = {} + +kanso.normal = { + a = { bg = theme.syn.fun, fg = theme.ui.bg }, + b = { bg = theme.diff.change, fg = theme.syn.fun }, + c = { bg = theme.ui.bg, fg = theme.ui.fg }, +} + +kanso.insert = { + a = { bg = theme.diag.ok, fg = theme.ui.bg }, + b = { bg = theme.ui.bg, fg = theme.diag.ok }, +} + +kanso.command = { + a = { bg = theme.syn.operator, fg = theme.ui.bg }, + b = { bg = theme.ui.bg, fg = theme.syn.operator }, +} + +kanso.visual = { + a = { bg = theme.syn.keyword, fg = theme.ui.bg }, + b = { bg = theme.ui.bg, fg = theme.syn.keyword }, +} + +kanso.replace = { + a = { bg = theme.syn.constant, fg = theme.ui.bg }, + b = { bg = theme.ui.bg, fg = theme.syn.constant }, +} + +kanso.inactive = { + a = { bg = theme.ui.bg, fg = theme.ui.fg_dim }, + b = { bg = theme.ui.bg, fg = theme.ui.fg_dim }, + c = { bg = theme.ui.bg, fg = theme.ui.fg_dim }, +} + +if vim.g.kanso_lualine_bold then + for _, mode in pairs(kanso) do + mode.a.gui = "bold" + end +end + +return kanso diff --git a/showcase.png b/showcase.png new file mode 100644 index 0000000..cab1332 Binary files /dev/null and b/showcase.png differ