From 1afbbb449aa0254823dbe1932e3cbb51886ff9fe Mon Sep 17 00:00:00 2001
From: Webhooked <9132742+webhooked@users.noreply.github.com>
Date: Sat, 31 Jan 2026 16:23:13 +0100
Subject: [PATCH] feat: add minimal mode for reduced color palette
Add new `minimal` config option that provides a cleaner, more focused
color scheme with fewer distinct colors:
- Variables/constants: white
- Functions/methods: blue
- Types: aqua
- Keywords/statements: gray
- Operators: yellow
- Brackets/punctuation: gray
- Properties/members: violet
---
README.md | 39 +++++++++++++++++++++++++++++
lua/kanso/highlights/lsp.lua | 8 +++---
lua/kanso/highlights/syntax.lua | 16 ++++++------
lua/kanso/highlights/treesitter.lua | 37 +++++++++++++++++++++------
lua/kanso/init.lua | 6 +++++
5 files changed, 86 insertions(+), 20 deletions(-)
diff --git a/README.md b/README.md
index 65ecd23..ecb234a 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,7 @@
- ⚡ Compilation to lua byte code for fast startup times
- 🎨 Four beautiful theme variants to match your mood and environment
- 🔆 Saturated mode for enhanced syntax highlighting visibility
+- 🎯 Minimal mode for a reduced color palette
- 👁️ WCAG 2.1 AA compliant
## 📦 Installation
@@ -99,6 +100,7 @@ require('kanso').setup({
light = "pearl" -- try "zen", "mist" or "ink" !
},
foreground = "default", -- "default" or "saturated" (can also be a table like background)
+ minimal = false, -- reduced color palette for a more minimal look
})
-- setup must be called before loading
@@ -211,6 +213,43 @@ The saturation adjustment only affects syntax highlighting colors (strings, keyw
+## 🎯 Minimal Mode
+
+Kansō supports a minimal mode that reduces the color palette for a cleaner, more focused coding experience. This mode uses fewer distinct colors while maintaining readability and visual hierarchy.
+
+
+🔳 Using Minimal Mode
+
+Enable minimal mode in your configuration:
+
+```lua
+require('kanso').setup({
+ minimal = true,
+})
+```
+
+When enabled, the color scheme changes to:
+
+| Element | Color |
+|---------|-------|
+| Variables, Constants | White (foreground) |
+| Parameters | Gray |
+| Functions, Methods | Blue |
+| Types | Aqua |
+| Keywords, Statements | Gray |
+| Operators (`=`, `+`, `*`, etc.) | Yellow |
+| Brackets, Punctuation | Gray |
+| Properties, Members | Violet |
+| Strings | Green |
+| Numbers | Pink |
+
+This mode is ideal for:
+- Reducing visual noise while coding
+- Users who prefer a more monochromatic aesthetic
+- Minimizing distractions during focused work sessions
+
+
+
## 🧰 Customization
In Kansō, there are _two_ kinds of colors: `PaletteColors` and `ThemeColors`;
diff --git a/lua/kanso/highlights/lsp.lua b/lua/kanso/highlights/lsp.lua
index 5aaf300..35a158b 100644
--- a/lua/kanso/highlights/lsp.lua
+++ b/lua/kanso/highlights/lsp.lua
@@ -9,15 +9,15 @@ function M.setup(colors, config)
-- ["@lsp.type.decorator"] = { link = "Function" },
-- ["@lsp.type.enum"] = { link = "Structure" },
-- ["@lsp.type.enumMember"] = { link = "Constant" },
- -- ["@lsp.type.function"] = { link = "Function" },
+ ["@lsp.type.function"] = { link = "Function" },
-- ["@lsp.type.interface"] = { link = "Structure" },
["@lsp.type.macro"] = { link = "Macro" },
- ["@lsp.type.method"] = { link = "@function.method" }, -- Function
+ ["@lsp.type.method"] = { link = "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.type"] = { link = "Type" },
-- ["@lsp.type.typeParameter"] = { link = "TypeDef" },
["@lsp.type.variable"] = { fg = "none" }, -- Identifier
["@lsp.type.comment"] = { link = "Comment" }, -- Comment
@@ -52,7 +52,7 @@ function M.setup(colors, config)
["@lsp.typemod.variable.injected"] = { link = "@variable" },
- ["@lsp.typemod.function.readonly"] = { fg = theme.syn.fun, bold = config.bold },
+ ["@lsp.typemod.function.readonly"] = { link = "Function" },
}
end
diff --git a/lua/kanso/highlights/syntax.lua b/lua/kanso/highlights/syntax.lua
index d419c19..e72fb4f 100644
--- a/lua/kanso/highlights/syntax.lua
+++ b/lua/kanso/highlights/syntax.lua
@@ -12,7 +12,7 @@ function M.setup(colors, config)
Comment = vim.tbl_extend("force", { fg = theme.syn.comment }, not config.italics and {} or config.commentStyle),
-- *Constant any constant
- Constant = { fg = theme.syn.constant },
+ Constant = { fg = config.minimal and theme.ui.fg or theme.syn.constant },
-- String a string constant: "this is a string"
String = { fg = theme.syn.string },
-- Character a character constant: 'c', '\n'
@@ -20,29 +20,29 @@ function M.setup(colors, config)
-- Number a number constant: 234, 0xff
Number = { fg = theme.syn.number },
-- Boolean a boolean constant: TRUE, false
- Boolean = { fg = theme.syn.constant },
+ Boolean = { fg = config.minimal and theme.ui.fg or theme.syn.constant },
-- Float a floating point constant: 2.3e10
Float = { link = "Number" },
-- *Identifier any variable name
- Identifier = { fg = theme.syn.identifier },
+ Identifier = { fg = config.minimal and theme.ui.fg or 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),
+ Statement = vim.tbl_extend("force", { fg = config.minimal and theme.syn.operator or 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 },
+ Operator = { fg = config.minimal and theme.syn.special1 or theme.syn.operator },
-- Keyword any other keyword
- Keyword = vim.tbl_extend("force", { fg = theme.syn.keyword }, not config.italics and {} or config.keywordStyle),
+ Keyword = vim.tbl_extend("force", { fg = config.minimal and theme.syn.operator or theme.syn.keyword }, not config.italics and {} or config.keywordStyle),
-- Exception try, catch, throw
Exception = { fg = theme.syn.special2 },
-- *PreProc generic Preprocessor
- PreProc = { fg = theme.syn.preproc },
+ PreProc = { fg = config.minimal and theme.syn.operator or theme.syn.preproc },
-- Include preprocessor #include
-- Define preprocessor #define
-- Macro same as Define
@@ -59,7 +59,7 @@ function M.setup(colors, config)
-- SpecialChar special character in a constant
-- Tag you can use CTRL-] on this
-- Delimiter character that needs attention
- Delimiter = { fg = theme.syn.punct },
+ Delimiter = { fg = config.minimal and theme.syn.operator or theme.syn.punct },
-- SpecialComment special things inside a comment
-- Debug debugging statements
diff --git a/lua/kanso/highlights/treesitter.lua b/lua/kanso/highlights/treesitter.lua
index 5d42578..252712d 100644
--- a/lua/kanso/highlights/treesitter.lua
+++ b/lua/kanso/highlights/treesitter.lua
@@ -9,9 +9,9 @@ function M.setup(colors, config)
-- @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 = config.italics },
+ ["@variable.builtin"] = { fg = config.minimal and theme.ui.fg or theme.syn.special2, italic = config.italics },
-- @variable.parameter parameters of a function
- ["@variable.parameter"] = { fg = theme.syn.parameter },
+ ["@variable.parameter"] = { fg = config.minimal and theme.syn.operator or theme.syn.parameter },
-- @variable.parameter.builtin special parameters (e.g. `_`, `it`)
-- @variable.member object and struct fields
["@variable.member"] = { fg = theme.syn.identifier },
@@ -44,21 +44,29 @@ function M.setup(colors, config)
-- @number.float floating-point number literals
--
-- @type type or class definitions and annotations
+ ["@type"] = { link = "Type" },
-- @type.builtin built-in types
+ ["@type.builtin"] = { fg = theme.syn.type },
-- @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
+ ["@property"] = { fg = theme.syn.identifier },
--
-- @function function definitions
+ ["@function"] = { link = "Function" },
-- @function.builtin built-in functions
+ ["@function.builtin"] = { link = "Function" },
-- @function.call function calls
+ ["@function.call"] = { link = "Function" },
-- @function.macro preprocessor macros
--
-- @function.method method definitions
+ ["@function.method"] = { link = "Function" },
-- @function.method.call method calls
+ ["@function.method.call"] = { link = "Function" },
--
-- @constructor constructor calls and definitions
["@constructor"] = { fg = theme.syn.special1 },
@@ -68,38 +76,51 @@ function M.setup(colors, config)
--
-- @keyword keywords not fitting into specific categories
-- @keyword.coroutine keywords related to coroutines (e.g. `go` in Go, `async/await` in Python)
+ ["@keyword.coroutine"] = { fg = config.minimal and theme.syn.identifier or theme.syn.keyword },
-- @keyword.function keywords that define a function (e.g. `func` in Go, `def` in Python)
+ ["@keyword.function"] = { fg = config.minimal and theme.syn.identifier or theme.syn.keyword },
-- @keyword.operator operators that are English words (e.g. `and`, `or`)
- ["@keyword.operator"] = { fg = theme.syn.operator },
+ ["@keyword.operator"] = { fg = config.minimal and theme.syn.special1 or 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.modifier"] = { fg = config.minimal and theme.syn.identifier or theme.syn.keyword },
+ -- @keyword.storage keywords for storage class (e.g. `const`, `let`, `var`)
+ ["@keyword.storage"] = { fg = config.minimal and theme.syn.identifier or theme.syn.keyword },
+ -- @storageclass static, register, volatile, const, etc.
+ ["@storageclass"] = { fg = config.minimal and theme.syn.identifier or theme.syn.keyword },
+ -- TypeScript/JavaScript specific keywords (const, let, var, etc.)
+ ["@keyword.typescript"] = { fg = config.minimal and theme.syn.identifier or theme.syn.keyword },
+ ["@keyword.javascript"] = { fg = config.minimal and theme.syn.identifier or theme.syn.keyword },
+ ["@keyword.tsx"] = { fg = config.minimal and theme.syn.identifier or theme.syn.keyword },
+ ["@keyword.jsx"] = { fg = config.minimal and theme.syn.identifier or theme.syn.keyword },
-- @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 },
+ { fg = config.minimal and theme.syn.identifier or theme.syn.special3 },
not config.italics and {} or 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.exception"] = vim.tbl_extend("force", { fg = config.minimal and theme.syn.operator or theme.syn.special3 }, config.statementStyle),
["@keyword.luap"] = { link = "@string.regex" },
--
-- @keyword.conditional keywords related to conditionals (e.g. `if`, `else`)
+ ["@keyword.conditional"] = { fg = config.minimal and theme.syn.identifier or theme.syn.keyword },
-- @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.delimiter"] = { fg = config.minimal and theme.syn.operator or theme.syn.punct },
-- @punctuation.bracket brackets (e.g. `()`, `{}`, `[]`)
- ["@punctuation.bracket"] = { fg = theme.syn.punct },
+ ["@punctuation.bracket"] = { fg = config.minimal and theme.syn.operator or theme.syn.punct },
-- @punctuation.special special symbols (e.g. `{}` in string interpolation)
- ["@punctuation.special"] = { fg = theme.syn.special1 },
+ ["@punctuation.special"] = { fg = config.minimal and theme.syn.operator or theme.syn.special1 },
--
-- @comment line and block comments
-- @comment.documentation comments documenting code
diff --git a/lua/kanso/init.lua b/lua/kanso/init.lua
index ed8a54c..1f84538 100644
--- a/lua/kanso/init.lua
+++ b/lua/kanso/init.lua
@@ -11,6 +11,7 @@ M.config = {
bold = true,
italics = true,
undercurl = true,
+ minimal = false,
commentStyle = { italic = true },
functionStyle = {},
keywordStyle = { italic = true },
@@ -48,6 +49,11 @@ function M.setup(config)
else
vim.notify("Kanso: Errors found while loading user config. Using default config.", vim.log.levels.ERROR)
end
+
+ -- Reload colorscheme if already active to apply new config
+ if vim.g.colors_name == "kanso" then
+ M.load(M._EXPLICIT_THEME)
+ end
end
--- load the colorscheme