1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-05 05:12:05 -04:00

New neovim theme engine (#1985)

* feat(matugen)!: rework completely neovim's theme engine

* fix: link to neovim theme plugin

* fix: expect AvengeMedia/base46 instead of Silzinc/base46
This commit is contained in:
Jonas Bloch
2026-03-13 18:37:16 +01:00
committed by GitHub
parent ce93f22669
commit 7e1d808d70
8 changed files with 1315 additions and 727 deletions

View File

@@ -477,6 +477,11 @@ Singleton {
property bool matugenTemplateEmacs: true
property bool matugenTemplateZed: true
property var matugenTemplateNeovimSettings: ({
"dark": { "baseTheme": "github_dark", "harmony": 0.5 },
"light": { "baseTheme": "github_light", "harmony": 0.5 }
})
property bool showDock: false
property bool dockAutoHide: false
property bool dockSmartAutoHide: false

View File

@@ -292,6 +292,13 @@ var SPEC = {
matugenTemplateEmacs: { def: true },
matugenTemplateZed: { def: true },
matugenTemplateNeovimSettings: {
def: {
dark: { baseTheme: "github_dark", harmony: 0.5 },
light: { baseTheme: "github_light", harmony: 0.5 }
}
},
showDock: { def: false },
dockAutoHide: { def: false },
dockSmartAutoHide: { def: false },

View File

@@ -2568,18 +2568,96 @@ Item {
onToggled: checked => SettingsData.set("matugenTemplateFoot", checked)
}
SettingsDivider {
visible: neovimThemeToggle.visible && neovimThemeToggle.checked
}
SettingsToggleRow {
id: neovimThemeToggle
tab: "theme"
tags: ["matugen", "neovim", "terminal", "template"]
settingKey: "matugenTemplateNeovim"
text: "neovim"
description: getTemplateDescription("nvim", I18n.tr("Requires lazy plugin manager", "neovim template description"))
description: getTemplateDescription("nvim", I18n.tr("Required plugin: ") + "https://github.com/AvengeMedia/base46")
descriptionColor: getTemplateDescriptionColor("nvim")
visible: SettingsData.runDmsMatugenTemplates
checked: SettingsData.matugenTemplateNeovim
onToggled: checked => SettingsData.set("matugenTemplateNeovim", checked)
}
SettingsDropdownRow {
text: I18n.tr("Dark mode base")
tab: "theme"
tags: ["matugen", "neovim", "terminal", "template"]
settingKey: "matugenTemplateNeovimSettings"
description: "Base to derive dark theme from"
visible: neovimThemeToggle.visible && neovimThemeToggle.checked
currentValue: SettingsData.matugenTemplateNeovimSettings?.dark?.baseTheme ?? "github_dark"
options: ["aquarium", "ashes", "aylin", "ayu_dark", "bearded-arc", "carbonfox", "catppuccin", "chadracula", "chadracula-evondev", "chadtain", "chocolate", "darcula-dark", "dark_horizon", "decay", "default-dark", "doomchad", "eldritch", "embark", "everblush", "everforest", "falcon", "flexoki", "flouromachine", "gatekeeper", "github_dark", "gruvbox", "gruvchad", "hiberbee", "horizon", "jabuti", "jellybeans", "kanagawa", "kanagawa-dragon", "material-darker", "material-deep-ocean", "melange", "midnight_breeze", "mito-laser", "monekai", "monochrome", "mountain", "neofusion", "nightfox", "nightlamp", "nightowl", "nord", "obsidian-ember", "oceanic-next", "onedark", "onenord", "oxocarbon", "palenight", "pastelDark", "pastelbeans", "penumbra_dark", "poimandres", "radium", "rosepine", "rxyhn", "scaryforest", "seoul256_dark", "solarized_dark", "solarized_osaka", "starlight", "sweetpastel", "tokyodark", "tokyonight", "tomorrow_night", "tundra", "vesper", "vscode_dark", "wombat", "yoru", "zenburn"]
enableFuzzySearch: true
onValueChanged: value => {
const settings = SettingsData.matugenTemplateNeovimSettings;
settings.dark.baseTheme = value;
SettingsData.set("matugenTemplateNeovimSettings", settings);
}
}
SettingsDropdownRow {
text: I18n.tr("Light mode base")
tab: "theme"
tags: ["matugen", "neovim", "terminal", "template"]
settingKey: "matugenTemplateNeovimSettings"
description: "Base to derive light theme from"
visible: neovimThemeToggle.visible && neovimThemeToggle.checked
currentValue: SettingsData.matugenTemplateNeovimSettings?.light?.baseTheme ?? "github_light"
options: ["ayu_light", "blossom_light", "catppuccin-latte", "default-light", "everforest_light", "flex-light", "flexoki-light", "github_light", "gruvbox_light", "material-lighter", "nano-light", "oceanic-light", "one_light", "onenord_light", "penumbra_light", "rosepine-dawn", "seoul256_light", "solarized_light", "sunrise_breeze", "vscode_light"]
enableFuzzySearch: true
onValueChanged: value => {
const settings = SettingsData.matugenTemplateNeovimSettings;
settings.light.baseTheme = value;
SettingsData.set("matugenTemplateNeovimSettings", settings);
}
}
SettingsSliderRow {
text: I18n.tr("Dark mode harmony")
tags: ["matugen", "neovim", "terminal", "template"]
settingKey: "matugenTemplateNeovimSettings"
description: "How much should the base dark theme be tinted"
visible: neovimThemeToggle.visible && neovimThemeToggle.checked
minimum: 0
maximum: 100
value: (SettingsData.matugenTemplateNeovimSettings?.dark?.harmony ?? 0.5) * 100
defaultValue: 50
onSliderValueChanged: value => {
const settings = SettingsData.matugenTemplateNeovimSettings;
settings.dark.harmony = value / 100;
SettingsData.set("matugenTemplateNeovimSettings", settings);
}
}
SettingsSliderRow {
text: I18n.tr("Light mode harmony")
tags: ["matugen", "neovim", "terminal", "template"]
settingKey: "matugenTemplateNeovimSettings"
description: "How much should the base light theme be tinted"
visible: neovimThemeToggle.visible && neovimThemeToggle.checked
minimum: 0
maximum: 100
value: (SettingsData.matugenTemplateNeovimSettings?.light?.harmony ?? 0.5) * 100
defaultValue: 50
onSliderValueChanged: value => {
const settings = SettingsData.matugenTemplateNeovimSettings;
settings.light.harmony = value / 100;
SettingsData.set("matugenTemplateNeovimSettings", settings);
}
}
SettingsDivider {
visible: neovimThemeToggle.visible && neovimThemeToggle.checked
}
SettingsToggleRow {
tab: "theme"
tags: ["matugen", "alacritty", "terminal", "template"]

View File

@@ -1,3 +1,3 @@
[templates.dmsneovim]
input_path = 'SHELL_DIR/matugen/templates/neovim.lua'
output_path = 'CONFIG_DIR/nvim/lua/plugins/dankcolors.lua'
output_path = 'CONFIG_DIR/nvim/colors/dms.lua'

View File

@@ -1,40 +1,83 @@
return {
{
"RRethy/base16-nvim",
priority = 1000,
config = function()
require('base16-colorscheme').setup({
local present, base46 = pcall(require, "base46")
if not present or not base46._DMS_SUPPORT then
vim.notify(
"base46 plugin not found or incorrect, make sure to install AvengeMedia/base46",
vim.log.levels.ERROR,
{ title = "dms integration" }
)
return
end
base00 = '{{colors.background.dark.hex}}',
base01 = '{{colors.surface_container_low.dark.hex}}',
base02 = '{{colors.surface_container.dark.hex}}',
base03 = '{{dank16.color8.dark.hex}}',
base0B = '{{dank16.color3.dark.hex}}',
base04 = '{{dank16.color7.default.hex}}',
base05 = '{{dank16.color15.default.hex}}',
base06 = '{{dank16.color15.default.hex}}',
base07 = '{{dank16.color15.default.hex}}',
base08 = '{{dank16.color9.default.hex}}',
base09 = '{{dank16.color9.default.hex}}',
base0A = '{{dank16.color12.default.hex}}',
base0C = '{{dank16.color14.default.hex}}',
base0D = '{{dank16.color12.default.hex}}',
base0E = '{{dank16.color13.default.hex}}',
base0F = '{{dank16.color13.default.hex}}',
})
local config_home = vim.env.XDG_CONFIG_HOME
if config_home == nil or #config_home == 0 then
config_home = vim.fs.joinpath(vim.env.HOME, ".config")
end
local settings_file_path = vim.fs.joinpath(config_home, "DankMaterialShell", "settings.json")
local settings_file = io.open(settings_file_path, "r")
if settings_file == nil then
vim.notify(
"cannnot read dms settings file at '" .. settings_file_path .. "'",
vim.log.levels.ERROR,
{ title = "dms integration" }
)
return
end
local settings = vim.json.decode(settings_file:read("*a"))
settings_file:close()
local current_file_path = vim.fn.stdpath("config") .. "/lua/plugins/dankcolors.lua"
if not _G._matugen_theme_watcher then
local uv = vim.uv or vim.loop
_G._matugen_theme_watcher = uv.new_fs_event()
_G._matugen_theme_watcher:start(current_file_path, {}, vim.schedule_wrap(function()
local new_spec = dofile(current_file_path)
if new_spec and new_spec[1] and new_spec[1].config then
new_spec[1].config()
print("Theme reload")
end
end))
end
local function deepGet(t, k)
for _, s in ipairs(k) do
if type(t) ~= "table" then
return
end
}
}
t = t[s]
end
return t
end
local current_file_path = debug.getinfo(1, "S").source:sub(2)
local theme_base = deepGet(settings, { "matugenTemplateNeovimSettings", vim.o.background, "baseTheme" })
or ("github_" .. vim.o.background)
local harmony = deepGet(settings, { "matugenTemplateNeovimSettings", vim.o.background, "harmony" }) or 0.5
local theme_name = "dms"
if not _G._matugen_theme_watcher then
local uv = vim.uv or vim.loop
_G._matugen_theme_watcher = { uv.new_fs_event(), uv.new_fs_event(), reload_timer = uv.new_timer() }
local debounce_time = 100 -- ms
local function handler()
_G._matugen_theme_watcher.reload_timer:stop()
_G._matugen_theme_watcher.reload_timer:start(
debounce_time,
0,
vim.schedule_wrap(function()
base46.theme_tables[theme_name] = nil
if vim.g.colors_name == theme_name then
vim.cmd.colorscheme(theme_name)
vim.notify("Theme reload", vim.log.levels.INFO, { title = "dms integration" })
end
-- NOTE: contrary to what the documentation says, uv fs events usually do not manage to react to more than one edit.
-- I understand that this is not intended: some edit processes in a typical system (e.g. the one neovim uses with
-- multiple renames and changes) make things hard to follow for libuv. Therefore, a restart is the best option.
_G._matugen_theme_watcher[1]:stop()
_G._matugen_theme_watcher[2]:stop()
_G._matugen_theme_watcher[1]:start(current_file_path, {}, handler)
_G._matugen_theme_watcher[2]:start(settings_file_path, {}, handler)
end)
)
end
_G._matugen_theme_watcher[1]:start(current_file_path, {}, handler)
_G._matugen_theme_watcher[2]:start(settings_file_path, {}, handler)
end
if not base46.theme_tables[theme_name] or base46.theme_tables[theme_name].type ~= vim.o.background then
local builtin = vim.deepcopy(assert(base46.get_builtin_theme(theme_base)))
local harmonized = base46.theme_harmonize(builtin, "{{colors.source_color.default.hex}}", harmony)
harmonized = base46.theme_set_bg(harmonized, "{{colors.background.default.hex}}")
base46.theme_tables[theme_name] = harmonized
end
base46.load(theme_name)
vim.g.colors_name = theme_name

File diff suppressed because it is too large Load Diff

View File

@@ -2583,6 +2583,29 @@
"description": "Mouse pointer appearance",
"conditionKey": "isNiri"
},
{
"section": "matugenTemplateNeovimSettings",
"label": "Dark mode base",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"base",
"colors",
"dark",
"dark mode",
"look",
"matugen",
"mode",
"neovim",
"night",
"scheme",
"style",
"template",
"terminal",
"theme"
]
},
{
"section": "modalDarkenBackground",
"label": "Darken Modal Background",
@@ -3948,20 +3971,17 @@
"keywords": [
"appearance",
"colors",
"lazy",
"look",
"manager",
"matugen",
"neovim",
"plugin",
"requires",
"required",
"scheme",
"style",
"template",
"terminal",
"theme"
],
"description": "Requires lazy plugin manager"
"description": "Required plugin: "
},
{
"section": "matugenTemplateNiri",
@@ -4138,18 +4158,14 @@
"authentication",
"biometric",
"enable",
"enrolled",
"fingerprint",
"fprint",
"lock",
"lockscreen",
"login",
"password",
"reader",
"screen",
"security"
],
"description": "Use fingerprint reader for lock screen authentication (requires enrolled fingerprints)"
]
},
{
"section": "loginctlLockIntegration",
@@ -4182,20 +4198,17 @@
"keywords": [
"authentication",
"enable",
"enrolled",
"fido",
"hardware",
"key",
"lock",
"lockscreen",
"login",
"password",
"screen",
"security",
"u2f",
"yubikey"
],
"description": "Use a FIDO2/U2F security key (e.g. YubiKey) for lock screen authentication (requires enrolled keys)"
]
},
{
"section": "lockDisplay",
@@ -4286,6 +4299,27 @@
],
"description": "Automatically lock the screen when DMS starts"
},
{
"section": "lockBeforeSuspend",
"label": "Lock before suspend",
"tabIndex": 11,
"category": "Lock Screen",
"keywords": [
"automatic",
"automatically",
"before",
"lock",
"login",
"password",
"prepares",
"screen",
"security",
"sleep",
"suspend",
"system"
],
"description": "Automatically lock the screen when the system prepares to suspend"
},
{
"section": "lockScreenNotificationMode",
"label": "Notification Display",
@@ -6288,27 +6322,6 @@
"icon": "schedule",
"description": "Gradually fade the screen before locking with a configurable grace period"
},
{
"section": "lockBeforeSuspend",
"label": "Lock before suspend",
"tabIndex": 21,
"category": "Power & Sleep",
"keywords": [
"automatically",
"before",
"energy",
"lock",
"power",
"prepares",
"screen",
"security",
"shutdown",
"sleep",
"suspend",
"system"
],
"description": "Automatically lock the screen when the system prepares to suspend"
},
{
"section": "fadeToLockGracePeriod",
"label": "Lock fade grace period",

View File

@@ -1518,6 +1518,13 @@
"reference": "",
"comment": ""
},
{
"term": "Available.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "BSSID",
"translation": "",
@@ -3653,6 +3660,20 @@
"reference": "",
"comment": ""
},
{
"term": "Dark mode base",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Dark mode harmony",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Darken Modal Background",
"translation": "",
@@ -4003,13 +4024,6 @@
"reference": "",
"comment": ""
},
{
"term": "Disabled.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Disabling WiFi...",
"translation": "",
@@ -4647,6 +4661,76 @@
"reference": "",
"comment": ""
},
{
"term": "Enabled, but fingerprint availability could not be confirmed.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Enabled, but no fingerprint reader was detected.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Enabled, but no prints are enrolled yet. Enroll fingerprints and run Sync.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Enabled, but no prints are enrolled yet. Enroll fingerprints to use it.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Enabled, but no registered security key was found yet. Register a key and run Sync.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Enabled, but no registered security key was found yet. Register a key or update your U2F config.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Enabled, but security-key availability could not be confirmed.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Enabled. PAM already provides fingerprint auth.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Enabled. PAM already provides security-key auth.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Enabled. PAM provides fingerprint auth, but no prints are enrolled yet.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Enabling WiFi...",
"translation": "",
@@ -5529,6 +5613,27 @@
"reference": "",
"comment": ""
},
{
"term": "Fingerprint availability could not be confirmed.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Fingerprint reader detected, but no prints are enrolled yet. You can enable this now and enroll later.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Fingerprint reader detected, but no prints are enrolled yet. You can enable this now and run Sync later.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Finish",
"translation": "",
@@ -5641,6 +5746,13 @@
"reference": "",
"comment": ""
},
{
"term": "Focused Monitor Only",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Focused Window",
"translation": "",
@@ -5648,6 +5760,13 @@
"reference": "",
"comment": ""
},
{
"term": "Focused monitor only",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Fog",
"translation": "",
@@ -6425,6 +6544,20 @@
"reference": "",
"comment": ""
},
{
"term": "Highlight Active Workspace App",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Highlight the currently focused app inside workspace indicators",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "History",
"translation": "",
@@ -7321,6 +7454,20 @@
"reference": "",
"comment": ""
},
{
"term": "Light mode base",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Light mode harmony",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Line",
"translation": "",
@@ -8826,6 +8973,13 @@
"reference": "",
"comment": ""
},
{
"term": "No fingerprint reader detected.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "No folders found",
"translation": "",
@@ -9121,14 +9275,28 @@
"comment": ""
},
{
"term": "Not available — install fprintd and enroll fingerprints.",
"term": "Not available — install fprintd and pam_fprintd, or configure greetd PAM.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Not available — install pam_u2f and enroll keys.",
"term": "Not available — install fprintd and pam_fprintd.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Not available — install or configure pam_u2f, or configure greetd PAM.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Not available — install or configure pam_u2f.",
"translation": "",
"context": "",
"reference": "",
@@ -9148,13 +9316,6 @@
"reference": "",
"comment": ""
},
{
"term": "Not enrolled",
"translation": "",
"context": "fingerprint not detected status | security key not detected status",
"reference": "",
"comment": ""
},
{
"term": "Not paired",
"translation": "",
@@ -9394,7 +9555,7 @@
"comment": ""
},
{
"term": "Only off for DMS-managed PAM lines. If greetd includes system-auth/common-auth/password-auth with pam_fprintd, fingerprint still stays enabled.",
"term": "Only affects DMS-managed PAM. If greetd already includes pam_fprintd, fingerprint stays enabled.",
"translation": "",
"context": "",
"reference": "",
@@ -9715,6 +9876,41 @@
"reference": "",
"comment": ""
},
{
"term": "PAM already provides fingerprint auth. Enable this to show it at login.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "PAM already provides security-key auth. Enable this to show it at login.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "PAM provides fingerprint auth, but availability could not be confirmed.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "PAM provides fingerprint auth, but no prints are enrolled yet.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "PAM provides fingerprint auth, but no reader was detected.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "PIN",
"translation": "",
@@ -10940,6 +11136,13 @@
"reference": "",
"comment": ""
},
{
"term": "Required plugin: ",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Requires %1",
"translation": "",
@@ -10968,13 +11171,6 @@
"reference": "",
"comment": ""
},
{
"term": "Requires lazy plugin manager",
"translation": "",
"context": "neovim template description",
"reference": "",
"comment": ""
},
{
"term": "Requires night mode support",
"translation": "",
@@ -11052,6 +11248,13 @@
"reference": "",
"comment": ""
},
{
"term": "Restore Special Workspace Windows",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Resume",
"translation": "",
@@ -11640,6 +11843,20 @@
"reference": "",
"comment": ""
},
{
"term": "Security-key availability could not be confirmed.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Security-key support was detected, but no registered key was found yet. You can enable this now and register one later.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Select",
"translation": "",
@@ -12585,6 +12802,20 @@
"reference": "",
"comment": ""
},
{
"term": "Show notification popups only on the currently focused monitor",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Show notifications only on the currently focused monitor",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Show on Last Display",
"translation": "",
@@ -14307,13 +14538,6 @@
"reference": "",
"comment": ""
},
{
"term": "Use a FIDO2/U2F security key (e.g. YubiKey) for lock screen authentication (requires enrolled keys)",
"translation": "",
"context": "lock screen U2F security key setting",
"reference": "",
"comment": ""
},
{
"term": "Use a custom image for the login screen, or leave empty to use your desktop wallpaper.",
"translation": "",
@@ -14328,6 +14552,13 @@
"reference": "",
"comment": ""
},
{
"term": "Use a security key for lock screen authentication.",
"translation": "",
"context": "lock screen U2F security key setting",
"reference": "",
"comment": ""
},
{
"term": "Use an external wallpaper manager like swww, hyprpaper, or swaybg.",
"translation": "",
@@ -14392,7 +14623,7 @@
"comment": ""
},
{
"term": "Use fingerprint reader for lock screen authentication (requires enrolled fingerprints)",
"term": "Use fingerprint authentication for the lock screen.",
"translation": "",
"context": "",
"reference": "",
@@ -14832,6 +15063,13 @@
"reference": "",
"comment": ""
},
{
"term": "When clicking a dock window in a Hyprland special workspace, bring that special workspace back before focusing the window",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "When enabled, apps are sorted alphabetically. When disabled, apps are sorted by usage frequency.",
"translation": "",