diff --git a/lib/kxmlgui.nix b/lib/kxmlgui.nix
new file mode 100644
index 00000000..934d750a
--- /dev/null
+++ b/lib/kxmlgui.nix
@@ -0,0 +1,226 @@
+{ lib, ... }:
+let
+ boolToString = bool: if bool then "1" else "0";
+
+ propertyType = lib.types.submodule {
+ options = {
+ name = lib.mkOption {
+ type = lib.types.str;
+ description = "The name of the property.";
+ };
+ shortcut = lib.mkOption {
+ type = lib.types.str;
+ description = "The shortcut of the property.";
+ };
+ };
+ };
+
+ actionPropertiesType = lib.types.submodule {
+ options = {
+ scheme = lib.mkOption {
+ type = lib.types.str;
+ description = "The scheme of the action properties.";
+ };
+ properties = lib.mkOption {
+ type = lib.types.listOf propertyType;
+ description = "The properties of the action properties.";
+ };
+ };
+ };
+
+ toolbarType = lib.types.submodule {
+ options = {
+ alreadyVisited = lib.mkOption {
+ type = with lib.types; nullOr bool;
+ default = null;
+ example = true;
+ description = "Whether the toolbar has already been visited.";
+ apply = value: if value != null then boolToString value else null;
+ };
+ noMerge = lib.mkOption {
+ type = with lib.types; nullOr bool;
+ default = null;
+ example = true;
+ description = "Whether the toolbar should not be merged.";
+ apply = value: if value != null then boolToString value else null;
+ };
+ items = lib.mkOption {
+ type = lib.types.listOf itemType;
+ description = "The items of the toolbar.";
+ };
+ };
+ };
+
+ itemType = lib.types.submodule {
+ options = {
+ type = lib.mkOption {
+ type = lib.types.enum [
+ "action"
+ "group"
+ "text"
+ "separator"
+ ];
+ description = "The type of the item.";
+ example = "action";
+ };
+ group = lib.mkOption {
+ type = with lib.types; nullOr str;
+ default = null;
+ description = "The group of the item.";
+ };
+ value = lib.mkOption {
+ type = lib.types.str;
+ description = "The value of the item.";
+ };
+ };
+ };
+
+ menuType = lib.types.submodule {
+ options = {
+ name = lib.mkOption {
+ type = lib.types.str;
+ description = "The name of the menu.";
+ };
+ items = lib.mkOption {
+ type = lib.types.listOf itemType;
+ description = "The items of the menu.";
+ };
+ };
+ };
+
+ menuBarType = lib.types.submodule {
+ options = {
+ alreadyVisited = lib.mkOption {
+ type = with lib.types; nullOr bool;
+ default = null;
+ example = true;
+ description = "Whether the menu bar has already been visited.";
+ apply = value: if value != null then boolToString value else null;
+ };
+ noMerge = lib.mkOption {
+ type = with lib.types; nullOr bool;
+ default = null;
+ example = true;
+ description = "Whether the menu bar should not be merged.";
+ apply = value: if value != null then boolToString value else null;
+ };
+ menus = lib.mkOption {
+ type = lib.types.listOf menuType;
+ description = "The menus of the menu bar.";
+ };
+ };
+ };
+
+ kxmlguiType = lib.types.submodule {
+ options = {
+ name = lib.mkOption {
+ type = lib.types.str;
+ description = "The name of the configuration.";
+ };
+ version = lib.mkOption {
+ type = lib.types.ints.unsigned;
+ description = "The version of the configuration.";
+ };
+ translationDomain = lib.mkOption {
+ type = with lib.types; nullOr str;
+ default = null;
+ example = "kxmlgui6";
+ description = "The translation domain of the configuration";
+ };
+ menubar = lib.mkOption {
+ type = lib.types.nullOr menuBarType;
+ default = null;
+ description = "The menu bar of the configuration.";
+ };
+ toolbar = lib.mkOption {
+ type = lib.types.nullOr toolbarType;
+ default = null;
+ description = "The toolbar of the configuration.";
+ };
+ actionProperties = lib.mkOption {
+ type = lib.types.nullOr actionPropertiesType;
+ default = null;
+ description = "The action properties of the configuration.";
+ };
+ };
+ };
+
+ generateKXMLGUI =
+ name: version: translationDomain: menubar: toolbar: actionProperties:
+ let
+ generateItem =
+ item:
+ if item.type == "action" then
+ ''''
+ else if item.type == "group" then
+ ''''
+ else if item.type == "text" then
+ "${item.value}"
+ else
+ "";
+ generateActionProperty =
+ property: '''';
+ in
+ ''
+
+
+
+ ${
+ lib.optionalString (menubar != null) ''
+
+ ${
+ lib.concatMapStringsSep "\n" (menu: ''
+
+ '') menubar.menus
+ }
+
+ ''
+ }
+ ${
+ lib.optionalString (toolbar != null) ''
+
+ ${lib.concatMapStringsSep "\n" (item: ''${generateItem item}'') toolbar.items}
+
+ ''
+ }
+ ${
+ lib.optionalString (actionProperties != null) ''
+ ${lib.concatMapStringsSep "\n" (actionProps: ''
+
+ ${
+ lib.concatMapStringsSep "\n" (property: ''
+ ${generateActionProperty property}
+ '') actionProps.properties
+ }
+
+ '') actionProperties}
+ ''
+ }
+
+ '';
+in
+{
+ inherit generateKXMLGUI kxmlguiType;
+}
diff --git a/modules/apps/konsole.nix b/modules/apps/konsole.nix
index c6d1ad2b..15710aed 100644
--- a/modules/apps/konsole.nix
+++ b/modules/apps/konsole.nix
@@ -1,12 +1,27 @@
-{ config, lib, pkgs, ... }:
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
let
- inherit (import ../../lib/types.nix { inherit lib; inherit config; }) basicSettingsType;
+ inherit
+ (import ../../lib/types.nix {
+ inherit lib;
+ inherit config;
+ })
+ basicSettingsType
+ ;
+ inherit (import ../../lib/kxmlgui.nix { inherit lib; }) generateKXMLGUI kxmlguiType;
# used as shown in the example in the library docs:
# https://ryantm.github.io/nixpkgs/functions/library/attrsets/#function-library-lib.attrsets.mapAttrs-prime
- createColorSchemes = lib.attrsets.mapAttrs' (name: value: lib.attrsets.nameValuePair
- ("konsole/${name}.colorscheme")
- ({ enable = true; source = value; })
+ createColorSchemes = lib.attrsets.mapAttrs' (
+ name: value:
+ lib.attrsets.nameValuePair ("konsole/${name}.colorscheme") {
+ enable = true;
+ source = value;
+ }
);
cfg = config.programs.konsole;
@@ -42,11 +57,11 @@ let
name = lib.mkOption {
type = lib.types.str;
/*
- TODO: Set default to null after adding an assertion
- Konsole needs to have a font set to be able to change font size
- Since I couldn't get that to work I'll just set a default font
- Not ideal since IMO we should only write things that are set explicitly
- by the user but ehh it is what it is
+ TODO: Set default to null after adding an assertion
+ Konsole needs to have a font set to be able to change font size
+ Since I couldn't get that to work I'll just set a default font
+ Not ideal since IMO we should only write things that are set explicitly
+ by the user but ehh it is what it is
*/
default = "Hack";
example = "Hack";
@@ -121,27 +136,41 @@ in
};
extraConfig = lib.mkOption {
- type = with lib.types; nullOr (attrsOf (attrsOf (basicSettingsType)));
+ type = with lib.types; nullOr (attrsOf (attrsOf basicSettingsType));
default = null;
description = ''
Extra config to add to konsolerc.
'';
};
+
+ toolbar = {
+ konsole = lib.mkOption {
+ type = lib.types.nullOr kxmlguiType;
+ default = null;
+ description = ''
+ The toolbar of Konsole.
+ '';
+ };
+ session = lib.mkOption {
+ type = lib.types.nullOr kxmlguiType;
+ default = null;
+ description = ''
+ The toolbar of Konsole sessions.
+ '';
+ };
+ };
};
config = lib.mkIf (cfg.enable) {
programs.plasma.configFile."konsolerc" = lib.mkMerge [
- (
- lib.mkIf (cfg.defaultProfile != null) {
- "Desktop Entry"."DefaultProfile" = "${cfg.defaultProfile}.profile";
- }
- )
- (
- lib.mkIf (cfg.extraConfig != null) (lib.mapAttrs
- (groupName: groupAttrs:
- (lib.mapAttrs (keyName: keyAttrs: { value = keyAttrs; }) groupAttrs))
- cfg.extraConfig)
- )
+ (lib.mkIf (cfg.defaultProfile != null) {
+ "Desktop Entry"."DefaultProfile" = "${cfg.defaultProfile}.profile";
+ })
+ (lib.mkIf (cfg.extraConfig != null) (
+ lib.mapAttrs (
+ groupName: groupAttrs: (lib.mapAttrs (keyName: keyAttrs: { value = keyAttrs; }) groupAttrs)
+ ) cfg.extraConfig
+ ))
{
"UiSettings"."ColorScheme" = lib.mkIf (cfg.ui.colorScheme != null) {
value = cfg.ui.colorScheme;
@@ -153,51 +182,63 @@ in
];
xdg.dataFile = lib.mkMerge [
- (lib.mkIf (cfg.profiles != { })
- (
- lib.mkMerge ([
- (
- lib.mkMerge (
- lib.mapAttrsToList
- (
- attrName: profile:
- let
- # Use the name from the name option if it's set
- profileName = if builtins.isString profile.name then profile.name else attrName;
- fontString = lib.mkIf (profile.font.name != null) "${profile.font.name},${builtins.toString profile.font.size}";
- in
+ (lib.mkIf (cfg.profiles != { }) (
+ lib.mkMerge [
+ (lib.mkMerge (
+ lib.mapAttrsToList (
+ attrName: profile:
+ let
+ # Use the name from the name option if it's set
+ profileName = if builtins.isString profile.name then profile.name else attrName;
+ fontString = lib.mkIf (
+ profile.font.name != null
+ ) "${profile.font.name},${builtins.toString profile.font.size}";
+ in
+ {
+ "konsole/${profileName}.profile".text = lib.generators.toINI { } (
+ lib.recursiveUpdate {
+ "General" = (
+ {
+ "Name" = profileName;
+ # Konsole generated profiles seem to always have this
+ "Parent" = "FALLBACK/";
+ }
+ // (lib.optionalAttrs (profile.command != null) { "Command" = profile.command; })
+ );
+ "Appearance" = (
{
- "konsole/${profileName}.profile".text = lib.generators.toINI { }
- (lib.recursiveUpdate
- {
- "General" = (
- {
- "Name" = profileName;
- # Konsole generated profiles seem to always have this
- "Parent" = "FALLBACK/";
- } //
- (lib.optionalAttrs (profile.command != null) { "Command" = profile.command; })
- );
- "Appearance" = (
- {
- # If the font size is not set we leave a comma at the end after the name
- # We should fix this probs but konsole doesn't seem to care ¯\_(ツ)_/¯
- "Font" = fontString.content;
- } //
- (lib.optionalAttrs (profile.colorScheme != null) { "ColorScheme" = profile.colorScheme; })
- );
- }
- profile.extraConfig
- );
+ # If the font size is not set we leave a comma at the end after the name
+ # We should fix this probs but konsole doesn't seem to care ¯\_(ツ)_/¯
+ "Font" = fontString.content;
}
- )
- cfg.profiles
- )
- )
- ])
- )
- )
+ // (lib.optionalAttrs (profile.colorScheme != null) { "ColorScheme" = profile.colorScheme; })
+ );
+ } profile.extraConfig
+ );
+ }
+ ) cfg.profiles
+ ))
+ ]
+ ))
(createColorSchemes cfg.customColorSchemes)
+ (lib.mkIf (cfg.toolbar.konsole != null) {
+ "kxmlgui5/konsole/konsoleui.rc".text = (
+ generateKXMLGUI cfg.toolbar.konsole.name cfg.toolbar.konsole.version
+ cfg.toolbar.konsole.translationDomain
+ cfg.toolbar.konsole.menubar
+ cfg.toolbar.konsole.toolbar
+ cfg.toolbar.konsole.actionProperties
+ );
+ })
+ (lib.mkIf (cfg.toolbar.session != null) {
+ "kxmlgui5/konsole/sessionui.rc".text = (
+ generateKXMLGUI cfg.toolbar.session.name cfg.toolbar.session.version
+ cfg.toolbar.session.translationDomain
+ cfg.toolbar.session.menubar
+ cfg.toolbar.session.toolbar
+ cfg.toolbar.session.actionProperties
+ );
+ })
];
};
}