From c52c7f314ccadcc2fcd91e28c8fd1b88f6d5ce0c Mon Sep 17 00:00:00 2001 From: Benedikt Peetz Date: Fri, 18 Oct 2024 17:07:46 +0200 Subject: refactor(modules): Move all system modules to `by-name` From now on all modules should be added to the new `by-name` directory. This should help remove the (superficial and utterly useless) distinction between `home-manager` and `NixOS` modules. --- modules/home.legacy/conf/taskwarrior/default.nix | 125 +++++++++++++++++ .../conf/taskwarrior/firefox/default.nix | 32 +++++ .../home.legacy/conf/taskwarrior/hooks/default.nix | 114 ++++++++++++++++ .../hooks/scripts/on-add_enforce-policies.sh | 41 ++++++ .../hooks/scripts/on-add_sync-git-repo.sh | 42 ++++++ .../hooks/scripts/on-modify_sync-git-repo.sh | 43 ++++++ .../hooks/scripts/on-modify_track-timewarrior.py | 94 +++++++++++++ .../scripts/on-modify_track-total-active-time.py | 148 +++++++++++++++++++++ modules/home.legacy/conf/taskwarrior/nord.theme | 100 ++++++++++++++ .../conf/taskwarrior/projects/default.nix | 119 +++++++++++++++++ 10 files changed, 858 insertions(+) create mode 100644 modules/home.legacy/conf/taskwarrior/default.nix create mode 100644 modules/home.legacy/conf/taskwarrior/firefox/default.nix create mode 100644 modules/home.legacy/conf/taskwarrior/hooks/default.nix create mode 100755 modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_enforce-policies.sh create mode 100755 modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_sync-git-repo.sh create mode 100755 modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_sync-git-repo.sh create mode 100755 modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-timewarrior.py create mode 100755 modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-total-active-time.py create mode 100644 modules/home.legacy/conf/taskwarrior/nord.theme create mode 100644 modules/home.legacy/conf/taskwarrior/projects/default.nix (limited to 'modules/home.legacy/conf/taskwarrior') diff --git a/modules/home.legacy/conf/taskwarrior/default.nix b/modules/home.legacy/conf/taskwarrior/default.nix new file mode 100644 index 00000000..d7aec156 --- /dev/null +++ b/modules/home.legacy/conf/taskwarrior/default.nix @@ -0,0 +1,125 @@ +{ + nixosConfig, + lib, + config, + ... +}: { + imports = [ + ./hooks + ]; + + services.taskwarrior-sync = { + enable = true; + }; + + programs.taskwarrior = let + projects = import ./projects {}; + + mkContext = project: + if builtins.hasAttr "subprojects" project + then + lib.lists.flatten ( + (builtins.map mkContext (builtins.map (mkProject project) project.subprojects)) + ++ (mkContext (builtins.removeAttrs project ["subprojects"])) + ) + else [ + { + inherit (project) name; + value = let + name = + if builtins.hasAttr "pname" project + then project.pname + else project.name; + in { + read = "project:${name}"; + write = "project:${name}"; + rc = { + neorg_path = + if builtins.hasAttr "neorg_path" project + then project.neorg_path + else "${project.prefix}/${project.name}/index.norg"; + }; + }; + } + ]; + mkProject = project: subproject: let + pname = + if builtins.hasAttr "pname" project + then project.pname + else project.name; + in + if builtins.isString subproject + then { + name = "${project.name}_${subproject}"; + pname = "${pname}.${subproject}"; + neorg_path = + if builtins.hasAttr "neorg_path_prefix" project + then "${project.neorg_path_prefix}/${subproject}/index.norg" + else "${project.prefix}/${project.name}/${subproject}/index.norg"; + } + else if builtins.isAttrs subproject + then let + name = builtins.elemAt (builtins.attrNames subproject) 0; + in { + name = "${project.name}_${name}"; + pname = "${pname}.${name}"; + prefix = "${project.prefix}/${project.name}"; + neorg_path_prefix = "${project.prefix}/${project.name}/${name}"; + subprojects = builtins.elemAt (builtins.attrValues subproject) 0; + } + else builtins.throw "Subproject not a string or a attrs: ${subproject}"; + + context = + builtins.listToAttrs (lib.lists.flatten (builtins.map mkContext projects)); + in { + enable = true; + colorTheme = ./nord.theme; + extraConfig = '' + # This include just contains my taskd user credentials + include ${nixosConfig.age.secrets.taskserverCredentials.path} + ''; + config = { + news.version = "2.6.0"; + complete.all.tags = true; + list.all = { + projects = true; + tags = true; + }; + regex = true; + weekstart = "Monday"; + uda = { + total_active_time = { + type = "duration"; + label = "Total active time"; + }; + }; + alias = { + mod = "modify"; + n = "execute neorg --task"; + fstart = "execute neorg fstart"; + }; + color = true; + + hooks.location = "${config.xdg.configHome}/task/hooks"; + + urgency.uda.priority = { + H.coefficient = 6.0; + M.coefficient = 0; + L.coefficient = -1.8; + }; + + inherit context; + + taskd = { + server = "taskserver.vhack.eu:53589"; + trust = "strict"; + ca = + nixosConfig.age.secrets.taskserverCA.path; + key = + nixosConfig.age.secrets.taskserverPrivate.path; + certificate = + nixosConfig.age.secrets.taskserverPublic.path; + }; + }; + }; +} diff --git a/modules/home.legacy/conf/taskwarrior/firefox/default.nix b/modules/home.legacy/conf/taskwarrior/firefox/default.nix new file mode 100644 index 00000000..fb5daaa8 --- /dev/null +++ b/modules/home.legacy/conf/taskwarrior/firefox/default.nix @@ -0,0 +1,32 @@ +{ + config, + lib, + # options + prefConfig, + profile_size, + search, + userChrome, + ... +}: let + inherit (config.soispha.taskwarrior.projects) projects; + + mkFirefoxProfile = { + name, + id, + }: { + inherit name; + value = { + isDefault = false; + extraConfig = prefConfig; + inherit id name search userChrome; + }; + }; + projects_id = + lib.imap0 (id: project: { + name = project; + id = id + profile_size; + }) + projects; + firefoxProfiles = builtins.listToAttrs (builtins.map mkFirefoxProfile projects_id); +in + firefoxProfiles diff --git a/modules/home.legacy/conf/taskwarrior/hooks/default.nix b/modules/home.legacy/conf/taskwarrior/hooks/default.nix new file mode 100644 index 00000000..ef97e1b5 --- /dev/null +++ b/modules/home.legacy/conf/taskwarrior/hooks/default.nix @@ -0,0 +1,114 @@ +{ + sysLib, + pkgs, + lib, + config, + ... +}: let + mkProject = project: subproject: + if builtins.isString subproject + then { + name = "${project.name}.${subproject}"; + prefix = null; + } + else let + name = builtins.elemAt (builtins.attrNames subproject) 0; + in { + name = "${project.name}.${name}"; + subprojects = builtins.elemAt (builtins.attrValues subproject) 0; + prefix = null; + }; + + mkProjectName = project: + if builtins.hasAttr "subprojects" project + then + lib.lists.flatten ([project.name] + ++ (builtins.map mkProjectName + (builtins.map (mkProject project) project.subprojects))) + else [project.name]; + projects = lib.lists.unique (lib.lists.naturalSort (lib.lists.flatten (builtins.map mkProjectName (import ../projects {})))); + projects_newline = builtins.concatStringsSep "\n" projects; + projects_comma = builtins.concatStringsSep ", " projects; + projects_pipe = builtins.concatStringsSep "|" projects; + + enforce_policies = sysLib.writeShellScript { + name = "bin"; + src = ./scripts/on-add_enforce-policies.sh; + dependencies = with pkgs; [dash jq taskwarrior gnused gnugrep]; + replacementStrings = { + PROJECTS_NEWLINE = projects_newline; + PROJECTS_COMMA = projects_comma; + }; + }; + track_timewarrior = pkgs.stdenv.mkDerivation { + name = "track_timewarrior.taskwarrior-hook"; + nativeBuildInputs = [ + pkgs.makeWrapper + ]; + buildInputs = [ + pkgs.timewarrior + pkgs.taskwarrior + # TODO: Use a `taskw` package, that actually supports newer python variants <2024-07-13> + (pkgs.python311.withPackages (pythonPackages: + with pythonPackages; [ + taskw + ])) + ]; + dontUnpack = true; + installPhase = '' + install -Dm755 ${./scripts/on-modify_track-timewarrior.py} $out/bin/bin + wrapProgram $out/bin/bin \ + --prefix PATH : ${lib.makeBinPath [pkgs.taskwarrior pkgs.timewarrior]} + ''; + }; + track_total_active_time = pkgs.stdenv.mkDerivation { + name = "track_total_active_time.taskwarrior-hook"; + nativeBuildInputs = [ + pkgs.makeWrapper + ]; + buildInputs = [ + pkgs.taskwarrior + # TODO: Use a `taskw` package, that actually supports newer python variants <2024-07-13> + (pkgs.python311.withPackages (pythonPackages: + with pythonPackages; [ + taskw + ])) + ]; + dontUnpack = true; + installPhase = '' + install -Dm755 ${./scripts/on-modify_track-total-active-time.py} $out/bin/bin + wrapProgram $out/bin/bin \ + --prefix PATH : ${lib.makeBinPath [pkgs.taskwarrior]} + ''; + }; + + mkSyncGitRepo = type: { + name = "${hookPath}/${type}_sync-git-repo"; + value = { + source = "${sysLib.writeShellScript { + name = "bin"; + src = ./scripts + "/${type}_sync-git-repo.sh"; + dependencies = with pkgs; [dash taskwarrior git]; + }}/bin/bin"; + }; + }; + sync_git_repos = + builtins.listToAttrs (builtins.map mkSyncGitRepo ["on-add" "on-modify"]); + hookPath = config.programs.taskwarrior.config.hooks.location; +in { + options.soispha.taskwarrior.projects = lib.mkOption { + type = lib.types.attrs; + }; + config = { + soispha.taskwarrior.projects = { + inherit projects_newline projects_comma projects projects_pipe; + }; + home.file = + { + "${hookPath}/on-add_enforce-policies".source = "${enforce_policies}/bin/bin"; + "${hookPath}/on-modify_track-timewarrior".source = "${track_timewarrior}/bin/bin"; + "${hookPath}/on-modify_track-total-active-time".source = "${track_total_active_time}/bin/bin"; + } + // sync_git_repos; + }; +} diff --git a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_enforce-policies.sh b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_enforce-policies.sh new file mode 100755 index 00000000..eaf7f30c --- /dev/null +++ b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_enforce-policies.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +# override shell lib output to stdout +eprint() { + # shellcheck disable=SC2317 + print "$@" +} +eprintln() { + # shellcheck disable=SC2317 + println "$@" +} + +enable_hook_dbg() { + debug_hooks="$(task _get rc.debug.hooks)" + [ "$debug_hooks" ] && [ "$debug_hooks" -ge 1 ] && dbg_enable +} + +enforce_project() { + project="$(jq '.project' "$(ptmp "$1")")" + [ "$project" = "null" ] && die "No project supplied!" + + if grep -q "^$(echo "$project" | sed 's|"\(.*\)"|\1|')\$" "$(ptmp "%PROJECTS_NEWLINE")"; then + dbg "project('$project') is a valid part of %PROJECTS_COMMA" + else + die "The project '$(echo "$project" | sed 's|"||g')' is not registered with the nix config, registered projects: %PROJECTS_COMMA" + fi +} + +read -r new_task +# We don't change the task, thus immediately return the json +echo "$new_task" + +enable_hook_dbg +enforce_project "$new_task" + +exit 0 + +# vim: ft=sh diff --git a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_sync-git-repo.sh b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_sync-git-repo.sh new file mode 100755 index 00000000..dadc96b0 --- /dev/null +++ b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_sync-git-repo.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +# override shell lib output to stdout +eprint() { + # shellcheck disable=SC2317 + print "$@" +} +eprintln() { + # shellcheck disable=SC2317 + println "$@" +} + +enable_hook_dbg() { + debug_hooks="$(task _get rc.debug.hooks)" + [ "$debug_hooks" ] && [ "$debug_hooks" -ge 1 ] && dbg_enable +} + +update_git_repo() { + task_data="$(task _get rc.data.location)" + [ "$task_data" ] || die "Taskwarrior should have a location set" + + cd "$task_data" || die "(BUG?): Your data.location path is not accessable" + + [ -d ./.git/ ] || git init + + git add . + git commit --message="chore: Update" --no-gpg-sign +} + +read -r new_task +# We don't change the task, thus immediately return the json +echo "$new_task" + +enable_hook_dbg +update_git_repo + +exit 0 + +# vim: ft=sh diff --git a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_sync-git-repo.sh b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_sync-git-repo.sh new file mode 100755 index 00000000..25813e46 --- /dev/null +++ b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_sync-git-repo.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +# override shell lib output to stdout +eprint() { + # shellcheck disable=SC2317 + print "$@" +} +eprintln() { + # shellcheck disable=SC2317 + println "$@" +} + +enable_hook_dbg() { + debug_hooks="$(task _get rc.debug.hooks)" + [ "$debug_hooks" ] && [ "$debug_hooks" -ge 1 ] && dbg_enable +} + +update_git_repo() { + task_data="$(task _get rc.data.location)" + [ "$task_data" ] || die "Taskwarrior should have a location set" + + cd "$task_data" || die "(BUG?): Your data.location path is not accessable" + + [ -d ./.git/ ] || git init + + git add . + git commit --message="chore: Update" --no-gpg-sign +} + +read -r _old_task +read -r new_task +# We don't change the task, thus immediately return the json +echo "$new_task" + +enable_hook_dbg +update_git_repo + +exit 0 + +# vim: ft=sh diff --git a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-timewarrior.py b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-timewarrior.py new file mode 100755 index 00000000..b482af6a --- /dev/null +++ b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-timewarrior.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (C) 2016-present Arctic Ice Studio +# Copyright (C) 2016-present Sven Greb + +# Project: igloo +# Repository: https://github.com/arcticicestudio/igloo +# License: MIT +# References: +# https://taskwarrior.org/docs +# https://taskwarrior.org/docs/timewarrior +# timew(1) +# task(1) + +"""A Taskwarrior hook to track the time of a active task with Taskwarrior. + +This hook will extract all of the following for use as Timewarrior tags: + +* UUID +* Project +* Tags +* Description +* UDAs + +Note: + This hook requires Python 3 and is only compatible with Taskwarrior version greater or equal to 2.4! + +This hook is a fork from the `official on-modify.timewarrior hook`_. + +.. _`official on-modify.timewarrior hook`: + https://github.com/GothenburgBitFactory/timewarrior/blob/dev/ext/on-modify.timewarrior +""" + +import subprocess +import sys +from json import loads, dumps +from os import system +from sys import stdin +from taskw import TaskWarrior + +# Make no changes to the task, simply observe. +old = loads(stdin.readline()) +new = loads(stdin.readline()) +print(dumps(new)) + + +w = TaskWarrior(config_filename=sys.argv[4].replace("rc:", "")) +config = w.load_config(config_filename=sys.argv[4].replace("rc:", "")) +if "max_active_tasks" in config: + MAX_ACTIVE = int(config["max_active_tasks"]) +else: + MAX_ACTIVE = 1 + + +# Extract attributes for use as tags. +tags = [new["description"]] + +if "project" in new: + project = new["project"] + tags.append(project) + if "." in project: + tags.extend([tag for tag in project.split(".")]) + +if "tags" in new: + tags.extend(new["tags"]) + +combined = " ".join(["'%s'" % tag for tag in tags]).encode("utf-8").strip() + +# Task has been started. +if "start" in new and "start" not in old: + # Prevent this task from starting if "task +ACTIVE count" is greater than "MAX_ACTIVE". + p = subprocess.Popen( + ["task", "+ACTIVE", "status:pending", "count", "rc.verbose:off"], + stdout=subprocess.PIPE, + ) + out, err = p.communicate() + count = int(out.rstrip()) + if count >= MAX_ACTIVE: + print( + "Only %d task(s) can be active at a time. " + "See 'max_active_tasks' in .taskrc." % MAX_ACTIVE + ) + sys.exit(1) + + system("timew start " + combined.decode() + " :yes") + +# Task has been stopped. +elif "start" not in new and "start" in old: + system("timew stop " + combined.decode() + " :yes") + +# Any task that is active, with a non-pending status should not be tracked. +elif "start" in new and new["status"] != "pending": + system("timew stop " + combined.decode() + " :yes") diff --git a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-total-active-time.py b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-total-active-time.py new file mode 100755 index 00000000..d5b380d0 --- /dev/null +++ b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-total-active-time.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (C) 2016-present Arctic Ice Studio +# Copyright (C) 2016-present Sven Greb + +# Project: igloo +# Repository: https://github.com/arcticicestudio/igloo +# License: MIT +# References: +# https://taskwarrior.org/docs +# task(1) + +"""A Taskwarrior hook to track the total active time of a task. + +The tracked time is stored in a UDA task duration attribute named ``totalactivetime`` of type ``duration`` holding the total number of seconds the task was +active. The tracked time can then be included in any report by adding the ``totalactivetime`` column. + +By default, this plugin allows to have one task active at a time. This can be changed by setting ``max_active_tasks`` in ``.taskrc`` to a value greater than +``1``. + +Note: + This hook requires Python 3 and the `taskw`_ package to be installed which provides the python bindings for Taskwarrior! + Also note that this hook is only compatible with Taskwarrior version greater or equal to 2.4! + +This hook is a fork from `kostajh/taskwarrior-time-tracking-hook`_ + +.. _taskw: + https://pypi.python.org/pypi/taskw +.. _kostajh/taskwarrior-time-tracking-hook: + https://github.com/kostajh/taskwarrior-time-tracking-hook +""" + +import datetime +import json +import re +import sys +import subprocess +from taskw import TaskWarrior +from typing import TypeVar + +TIME_FORMAT = "%Y%m%dT%H%M%SZ" +UDA_KEY = "total_active_time" + +w = TaskWarrior(config_filename=sys.argv[4].replace("rc:", "")) +config = w.load_config(config_filename=sys.argv[4].replace("rc:", "")) +if "max_active_tasks" in config: + MAX_ACTIVE = int(config["max_active_tasks"]) +else: + MAX_ACTIVE = 1 + +"""Compiled regular expression for the duration as ISO-8601 formatted string.""" +ISO8601DURATION = re.compile("P((\d*)Y)?((\d*)M)?((\d*)D)?T((\d*)H)?((\d*)M)?((\d*)S)?") + +"""The duration type either as integer (in seconds), as ISO-8601 formatted string ("PT1H10M31S") or the seconds suffixed with "seconds".""" +DurationType = TypeVar("DurationType", str, int) + + +def duration_str_to_time_delta(duration_str: DurationType) -> datetime.timedelta: + """Converts duration string into a timedelta object. + + :param duration_str: The duration + :return: The duration as timedelta object + """ + if duration_str.startswith("P"): + match = ISO8601DURATION.match(duration_str) + if match: + year = match.group(2) + month = match.group(4) + day = match.group(6) + hour = match.group(8) + minute = match.group(10) + second = match.group(12) + value = 0 + if second: + value += int(second) + if minute: + value += int(minute) * 60 + if hour: + value += int(hour) * 3600 + if day: + value += int(day) * 3600 * 24 + if month: + # Assume a month is 30 days for now. + value += int(month) * 3600 * 24 * 30 + if year: + # Assume a year is 365 days for now. + value += int(year) * 3600 * 24 * 365 + else: + value = int(duration_str) + elif duration_str.endswith("seconds"): + value = int(duration_str.rstrip("seconds")) + else: + value = int(duration_str) + return datetime.timedelta(seconds=value) + + +def main(): + original = json.loads(sys.stdin.readline()) + modified = json.loads(sys.stdin.readline()) + + # An active task has just been started. + if "start" in modified and "start" not in original: + # Prevent this task from starting if "task +ACTIVE count" is greater than "MAX_ACTIVE". + p = subprocess.Popen( + ["task", "+ACTIVE", "status:pending", "count", "rc.verbose:off"], + stdout=subprocess.PIPE, + ) + out, err = p.communicate() + count = int(out.rstrip()) + if count >= MAX_ACTIVE: + print( + "Only %d task(s) can be active at a time. " + "See 'max_active_tasks' in .taskrc." % MAX_ACTIVE + ) + sys.exit(1) + + # An active task has just been stopped. + if "start" in original and "start" not in modified: + # Calculate the elapsed time. + start = datetime.datetime.strptime(original["start"], TIME_FORMAT) + end = datetime.datetime.utcnow() + + if UDA_KEY not in modified: + modified[UDA_KEY] = 0 + + this_duration = end - start + total_duration = this_duration + duration_str_to_time_delta( + str(modified[UDA_KEY]) + ) + print( + "Total Time Tracked: %s (%s in this instance)" + % (total_duration, this_duration) + ) + modified[UDA_KEY] = ( + str(int(total_duration.days * (60 * 60 * 24) + total_duration.seconds)) + + "seconds" + ) + + return json.dumps(modified, separators=(",", ":")) + + +def cmdline(): + sys.stdout.write(main()) + + +if __name__ == "__main__": + cmdline() diff --git a/modules/home.legacy/conf/taskwarrior/nord.theme b/modules/home.legacy/conf/taskwarrior/nord.theme new file mode 100644 index 00000000..2897418f --- /dev/null +++ b/modules/home.legacy/conf/taskwarrior/nord.theme @@ -0,0 +1,100 @@ +# Copyright (C) 2016-present Arctic Ice Studio +# Copyright (C) 2016-present Sven Greb + +# Project: igloo +# Repository: https://github.com/arcticicestudio/igloo +# License: MIT +# References: +# https://taskwarrior.org/docs/themes.html +# task-color(5) +# taskrc(5) + +rule.precedence.color=deleted,completed,active,keyword.,tag.,project.,overdue,scheduled,due.today,due,blocked,blocking,recurring,tagged,uda. + +#+---------+ +#+ General + +#+---------+ +color.label= +color.label.sort= +color.alternate= +color.header=bold blue +color.footnote=cyan +color.warning=bold black on yellow +color.error=bold black on red +color.debug=magenta + +#+-------------+ +#+ Task States + +#+-------------+ +color.completed=green +color.deleted=red +color.active=bold black on cyan +color.recurring= +color.scheduled=white on black +color.until=white on bright black +color.blocked=yellow on black +color.blocking=bold yellow on black + +#+----------+ +#+ Projects + +#+----------+ +color.project.none= + +#+----------+ +#+ Priority + +#+----------+ +color.uda.priority.H=bold cyan +color.uda.priority.M=bold blue +color.uda.priority.L=color245 + +#+------+ +#+ Tags + +#+------+ +color.tag.next= +color.tag.none= +color.tagged= + +#+-----+ +#+ Due + +#+-----+ +color.due=blue +color.due.today=cyan on black +color.overdue=bold red + +#+---------+ +#+ Reports + +#+---------+ +color.burndown.done=bold black on cyan +color.burndown.pending=black on bright cyan +color.burndown.started=black on blue + +color.history.add=bold black on blue +color.history.delete=bright white on bold black +color.history.done=bold black on cyan + +color.summary.background=bright white on black +color.summary.bar=black on cyan + +#+----------+ +#+ Calendar + +#+----------+ +color.calendar.due=bold black on blue +color.calendar.due.today=bold black on cyan +color.calendar.holiday=bold blue on white +color.calendar.overdue=bold black on red +color.calendar.today=bold black on cyan +color.calendar.weekend=bright white on bright black +color.calendar.weeknumber=bold black + +#+-----------------+ +#+ Synchronization + +#+-----------------+ +color.sync.added=green +color.sync.changed=yellow +color.sync.rejected=red + +#+------+ +#+ Undo + +#+------+ +color.undo.after=green +color.undo.before=red diff --git a/modules/home.legacy/conf/taskwarrior/projects/default.nix b/modules/home.legacy/conf/taskwarrior/projects/default.nix new file mode 100644 index 00000000..9b555fef --- /dev/null +++ b/modules/home.legacy/conf/taskwarrior/projects/default.nix @@ -0,0 +1,119 @@ +{}: [ + { + name = "me"; + prefix = ""; + subprojects = ["health" "sweden" "bank"]; + } + { + name = "timesinks"; + prefix = ""; + subprojects = ["youtube" "games" "netflix" "music"]; + } + { + name = "input"; + prefix = "research"; + subprojects = ["read-things" "dotfiles"]; + } + { + name = "aoc"; + prefix = "programming/advent_of_code"; + } + { + name = "camera"; + prefix = "programming/zig"; + subprojects = []; + } + { + name = "trinitrix"; + prefix = "programming/rust"; + subprojects = ["testing" "documentation"]; + } + { + name = "serverphone"; + prefix = "programming/rust"; + } + { + name = "latex"; + prefix = "programming/latex"; + } + { + name = "presentation"; + prefix = "research"; + } + { + name = "possible-projects"; + prefix = "research"; + } + { + name = "school"; + prefix = "research"; + subprojects = [ + "biologie" + "chemie" + "deutsch" + "english" + "geographie" + "geschichte" + "infomatik" + "klausuren" + "latein" + "mathematik" + "musik" + "philosophie" + "physik" + "sozialkunde" + "sport" + {extern = ["bwinf" "dsa"];} + {chemie = ["facharbeit"];} # TODO: Remove once the ff tabs are cleared <2024-05-10> + ]; + } + { + name = "hardware"; + prefix = "research"; + } + { + name = "buy"; + prefix = "buy"; + subprojects = ["books" "pc"]; + } + { + name = "system"; + prefix = "config"; + subprojects = [ + "youtube" + "backup" + "bar" + "email" + "firefox" + "gpg" + "keyboard" + "laptop" + "nvim" + "rss" + "shell" + "task" + "wm" + ]; + } + { + name = "server"; + prefix = "config"; + subprojects = [ + "b-peetz" + "email" + "blog" + "nix-sync" + "sudo-less" + "ci" + ]; + } + { + name = "3d-printer"; + prefix = "hardware"; + } + { + name = "smartphone"; + prefix = "hardware"; + subprojects = ["airplay" "airdrop"]; + } +] -- cgit 1.4.1