Skip to content

Commit

Permalink
Add colortheme configuration to kate (#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
Asqiir authored Mar 29, 2024
1 parent 298f345 commit fb4a1cd
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 102 deletions.
2 changes: 1 addition & 1 deletion modules/apps/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
{
imports = [
./konsole.nix
./kate.nix
./kate
];
}
101 changes: 0 additions & 101 deletions modules/apps/kate.nix

This file was deleted.

45 changes: 45 additions & 0 deletions modules/apps/kate/check-theme-name-free.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# there could be a bash shebang to ${pkgs.bash}/bin/bash here

# https://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux/5947802#5947802
RED='\033[0;31m'

# https://stackoverflow.com/questions/2924697/how-does-one-output-bold-text-in-bash/2924755#2924755
BOLD=$(tput bold)
NORMAL=$(tput sgr0)


# # =====================================
# # CHECK THE NUMBER OF ARGS
# #
# # https://www.baeldung.com/linux/bash-check-script-arguments

if [[ "$#" -ne 1 ]]; then
# https://stackoverflow.com/questions/3005963/how-can-i-have-a-newline-in-a-string-in-sh/3182519#3182519
>&2 printf "%sIncorrect number of arguments.%s Expected one: The name of the theme that should not already be in use" "${RED}${BOLD}" "${NORMAL}${RED}"
exit 1
fi

THEMENAME=$1


# =====================================
# GO THROUGH THE THEMES
#
# reference the XDG dir as proposed in https://github.com/nix-community/home-manager/pull/4594#issuecomment-1774024207

THEME_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/org.kde.syntax-highlighting/themes/"

# TODO and symlinks! (or: skip over dirs)
find "${THEME_DIR}" \( -type f -o -type l \) | while read -r themefile; do
THIS_THEMENAME=$(jq -r .metadata.name "${themefile}")

if [[ "${THIS_THEMENAME}" == "${themefile}" ]]; then
# make sure to not look at symbolic links to the nix store
# https://stackoverflow.com/questions/17918367/linux-shell-verify-whether-a-file-exists-and-is-a-soft-link/17918442#17918442
# https://stackoverflow.com/questions/2172352/in-bash-how-can-i-check-if-a-string-begins-with-some-value/2172367#2172367
if [[ ! ( -L "${themefile}" && $(readlink -f "${themefile}") == /nix/store/* ) ]]; then
>&2 printf "%s In %s there is already a theme with the name %s (%s).%s You could rename the theme given in config.programs.kate.editor.theme.src by changing the value for metadata.name inside the theme." "${RED}${BOLD}" "${THEME_DIR}" "${THEMENAME}" "${themefile}" "${NORMAL}${RED}"
exit 1 # even on dryrun
fi
fi
done
192 changes: 192 additions & 0 deletions modules/apps/kate/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
{ config, lib, pkgs, ... }:

let
cfg = config.programs.kate;

# compute kate's magic TabHandlingMode
# 0 is not tab & not undoByShiftTab
# 1 is tab & undoByShiftTab
# 2 is not tab & undoByShiftTab
tabHandlingMode = indentSettings:
if (!indentSettings.undoByShiftTab && !indentSettings.tabFromEverywhere) then 0 else
(
if (indentSettings.undoByShiftTab && indentSettings.tabFromEverywhere) then 1 else
2
);

checkThemeNameScript = pkgs.writeShellApplication {
name = "checkThemeName";
runtimeInputs = with pkgs; [ jq ];
text = builtins.readFile ./check-theme-name-free.sh;
};

checkThemeName = name:
''
${checkThemeNameScript}/bin/checkThemeName ${name}
'';

script = pkgs.writeScript "kate-check" (checkThemeName cfg.editor.theme.name);
in
{
options.programs.kate = {
enable = lib.mkEnableOption ''
Enable configuration management for kate.
'';

package = lib.mkPackageOption pkgs "kate" {
default = [ "kate" ];
example = "pkgs.libsForQt5.kate";
extraDescription = ''
Which kate package to install. Use `pkgs.libsForQt5.kate` in Plasma5 and
`pkgs.kdePackages.kate` in Plasma6. Use `null` if home-manager should not install kate
(use this if you want to manage the settings of this user of a system-wide kate
installation).
'';
};

# ==================================
# INDENTATION
editor = {
tabWidth = lib.mkOption {
description = "The width of a single tab (''\t) sign (in number of spaces).";
default = 4;
type = lib.types.int;
};

indent.showLines = lib.mkOption {
description = "Whether to show the vertical lines that mark each indentation level.";
default = true;
type = lib.types.bool;
};

indent.width = lib.mkOption {
description = "The width of each indent level (in number of spaces).";
default = cfg.editor.tabWidth;
type = lib.types.int;
};

indent.autodetect = lib.mkOption {
description = ''
Whether kate should try to detect indentation for each given file and not impose default indentation settings.
'';
default = true;
type = lib.types.bool;
};

indent.keepExtraSpaces = lib.mkOption {
description = "Whether additional spaces that do not match the indent should be kept when adding/removing indentation level. If these are kept (option to true) then indenting 1 space further (with a default of 4 spaces) will be set to 5 spaces.";
default = false;
type = lib.types.bool;
};

indent.replaceWithSpaces = lib.mkOption {
description = "Whether all indentation should be automatically converted to spaces.";
default = false;
type = lib.types.bool;
};

indent.backspaceDecreaseIndent = lib.mkOption {
description = "Whether the backspace key in the indentation should decrease indentation by a full level always.";
default = true;
type = lib.types.bool;
};

indent.tabFromEverywhere = lib.mkOption {
description = "Whether the tabulator key increases intendation independent from the current cursor position.";
default = false;
type = lib.types.bool;
};

indent.undoByShiftTab = lib.mkOption {
description = "Whether to unindent the current line by one level with the shortcut Shift+Tab";
default = true;
type = lib.types.bool;
};
};
};

config.assertions = [
{
assertion = cfg.editor.indent.undoByShiftTab || (!cfg.editor.indent.tabFromEverywhere);
message = "Kate does not support both 'undoByShiftTab' to be disabled and 'tabFromEverywhere' to be enabled at the same time.";
}
];

config.programs.plasma.configFile."katerc" = lib.mkIf cfg.enable {
"KTextEditor Document" = {
"Auto Detect Indent".value = cfg.editor.indent.autodetect;
"Indentation Width".value = cfg.editor.indent.width;
"Tab Handling".value = (tabHandlingMode cfg.editor.indent);
"Tab Width".value = cfg.editor.tabWidth;
"Keep Extra Spaces".value = cfg.editor.indent.keepExtraSpaces;
"ReplaceTabsDyn".value = cfg.editor.indent.replaceWithSpaces;
};

"KTextEditor Renderer" = {
"Show Indentation Lines".value = cfg.editor.indent.showLines;


# COLORTHEME (cannot define this below)
# Do pick the theme if the user chose one,
# Do not touch the theme settings otherwise
"Auto Color Theme Selection".value = lib.mkIf (cfg.editor.theme.name != "") false;
"Color Theme".value = lib.mkIf (cfg.editor.theme.name != "") cfg.editor.theme.name;
};
};


# ==================================
# COLORTHEME

options.programs.kate.editor.theme = {
src = lib.mkOption {
description = ''
The path of a theme file for the KDE editor (not the window color scheme).
Obtain a custom one by using the GUI settings in kate. If you want to use a system-wide
editor color scheme set this path to null. If you set the metadata.name entry in the file
to a value that matches the name of a system-wide color scheme undesired behaviour may
occur. The activation will fail if a theme with the filename `<name of your theme>.theme`
already exists.'';
type = lib.types.nullOr lib.types.path;
default = null;
};

name = lib.mkOption {
description = ''
The name of the theme in use. May be a system theme.
If a theme file was submitted this setting will be set automatically.
'';
type = lib.types.str;
default = "";
};
};

config.programs.kate.editor.theme = {
# kate's naming scheme is ${themename}.theme
# which is why we use the same naming scheme here
name = lib.mkIf (cfg.enable && null != cfg.editor.theme.src) (lib.mkForce (builtins.fromJSON (builtins.readFile cfg.editor.theme.src))."metadata"."name");
};

# This won't override existing files since the home-manager activation fails in that case
config.xdg.dataFile."${cfg.editor.theme.name}.theme" = lib.mkIf (cfg.enable && null != cfg.editor.theme.src)
{
source = cfg.editor.theme.src;
target = "org.kde.syntax-highlighting/themes/${cfg.editor.theme.name}.theme";
};

config = {
home.packages = lib.mkIf (cfg.enable && cfg.package != null) [ cfg.package ];

# In case of using a custom theme, check that there is no name collision
home.activation.checkKateTheme = lib.mkIf (cfg.enable && cfg.editor.theme.src != null) (lib.hm.dag.entryBefore [ "writeBoundary" ]
# No `$DRY_RUN_CMD`, since even a dryrun should fail if checks fail
''
${script}
'');

# In case of using a system theme, there should be a check that there exists such a theme
# but I could not figure out where to find them
# That's why there is no check for now
# See also [the original PR](https://github.com/pjones/plasma-manager/pull/95#issue-2206192839)
};
}

0 comments on commit fb4a1cd

Please sign in to comment.