summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Geier <geier@lostpackets.de>2023-10-29 16:56:06 +0100
committerChristian Geier <geier@lostpackets.de>2024-04-11 21:21:42 +0200
commit2fedc40158e245c64cfe5170b7c1f9bd40167550 (patch)
tree1d92663f040052b5378b80bc75b912dd223e1852
parent692d2d1fa109e37b74a68cd9855f62352c3f76a7 (diff)
support for color theme plugins
-rw-r--r--khal/khalendar/event.py6
-rw-r--r--khal/plugins.py8
-rw-r--r--khal/settings/khal.spec2
-rw-r--r--khal/ui/__init__.py16
4 files changed, 24 insertions, 8 deletions
diff --git a/khal/khalendar/event.py b/khal/khalendar/event.py
index c3112fba..d300b17d 100644
--- a/khal/khalendar/event.py
+++ b/khal/khalendar/event.py
@@ -25,7 +25,7 @@ helper functions."""
import datetime as dt
import logging
import os
-from typing import Dict, List, Optional, Tuple, Type, Union
+from typing import Callable, Dict, List, Optional, Tuple, Type, Union
import icalendar
import icalendar.cal
@@ -729,9 +729,9 @@ class Event:
formatters = FORMATTERS.values()
if len(formatters) == 1:
- fmt = list(formatters)[0]
+ fmt: Callable[[str], str] = list(formatters)[0]
else:
- def fmt(s): return s.strip()
+ def fmt(s: str) -> str: return s.strip()
attributes["description"] = fmt(self.description)
attributes["description-separator"] = ""
diff --git a/khal/plugins.py b/khal/plugins.py
index 891eca99..fc3d5096 100644
--- a/khal/plugins.py
+++ b/khal/plugins.py
@@ -1,4 +1,5 @@
from collections.abc import Callable, Mapping
+from typing import Dict, List, Tuple
from khal._compat import importlib_metadata
@@ -18,6 +19,12 @@ def _load_formatters() -> dict[str, Callable[[str], str]]:
FORMATTERS: Mapping[str, Callable[[str], str]] = _load_formatters()
+def _load_color_themes() -> Dict[str, List[Tuple[str, ...]]]:
+ color_theme_entrypoints = importlib_metadata.entry_points(group="khal.color_theme")
+ return {ep.name: ep.load() for ep in color_theme_entrypoints}
+
+THEMES: Dict[str, List[Tuple[str, ...]],] = _load_color_themes()
+
# class ParserExtensionInterface(Protocol):
# """An interface for parser extension plugins."""
@@ -43,7 +50,6 @@ FORMATTERS: Mapping[str, Callable[[str], str]] = _load_formatters()
# """Add options to the khal CLI, to be stored in mdit.options["mdformat"]
# (optional)"""
-
# def _load_parser_extensions() -> dict[str, ParserExtensionInterface]:
# parser_extension_entrypoints = importlib_metadata.entry_points(
# group="khal.parser_extension"
diff --git a/khal/settings/khal.spec b/khal/settings/khal.spec
index 676d5103..b5e758dd 100644
--- a/khal/settings/khal.spec
+++ b/khal/settings/khal.spec
@@ -269,7 +269,7 @@ blank_line_before_day = boolean(default=False)
#
# __ http://urwid.org/manual/displayattributes.html
# .. _github: https://github.com/pimutils/khal/issues
-theme = option('dark', 'light', default='dark')
+theme = string(default='dark')
# Whether to show a visible frame (with *box drawing* characters) around some
# (groups of) elements or not. There are currently several different frame
diff --git a/khal/ui/__init__.py b/khal/ui/__init__.py
index 930b3023..f3ea06de 100644
--- a/khal/ui/__init__.py
+++ b/khal/ui/__init__.py
@@ -29,9 +29,9 @@ from typing import Dict, List, Literal, Optional, Tuple
import click
import urwid
-from .. import utils
+from .. import plugins, utils
from ..khalendar import CalendarCollection
-from ..khalendar.exceptions import ReadOnlyCalendarError
+from ..khalendar.exceptions import FatalError, ReadOnlyCalendarError
from ..parse_datetime import timedelta2str
from . import colors
from .base import Pane, Window
@@ -1367,6 +1367,17 @@ def start_pane(
color_mode: Literal['rgb', '256colors']='rgb',
):
"""Open the user interface with the given initial pane."""
+ # We don't validate the themes in settings.spec but instead here
+ # first try to load built-in themes, then try to load themes from
+ # plugins
+ theme = colors.themes.get(pane._conf['view']['theme'])
+ if theme is None:
+ theme = plugins.THEMES.get(pane._conf['view']['theme'])
+ if theme is None:
+ logger.fatal(f'Invalid theme {pane._conf["view"]["theme"]} configured')
+ logger.fatal(f'Available themes are: {", ".join(colors.themes.keys())}')
+ raise FatalError
+
quit_keys = quit_keys or ['q']
frame = Window(
@@ -1417,7 +1428,6 @@ def start_pane(
logger.addHandler(header_handler)
frame.open(pane, callback)
- theme = getattr(colors, pane._conf['view']['theme'])
palette = _add_calendar_colors(
theme, pane.collection, color_mode=color_mode,
base='calendar', attr_template='calendar {}',