Skip to content

Commit

Permalink
Merge pull request #1279 from pimutils/config_based_theming
Browse files Browse the repository at this point in the history
ikhal: initial support for config based ikhal theming
  • Loading branch information
geier authored Oct 26, 2023
2 parents 3877aac + d726500 commit 25c5c26
Show file tree
Hide file tree
Showing 7 changed files with 274 additions and 115 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ not released yet
* optimization in ikhal when editing events in the far future or past
* FIX an issue in ikhal with updating the view of the event list after editing
an event
* NEW properties of ikhal themes (dark and light) can now be overriden from the
config file (via the new [palette] section, check the documenation)

0.11.2
======
Expand Down
35 changes: 34 additions & 1 deletion khal/settings/khal.spec
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ blank_line_before_day = boolean(default=False)
# `khal/settings/khal.spec` in the section `[default]` of the property `theme`.
#
# __ http://urwid.org/manual/displayattributes.html
# .. _github: # https://github.com/pimutils/khal/issues
# .. _github: https://github.com/pimutils/khal/issues
theme = option('dark', 'light', default='dark')

# Whether to show a visible frame (with *box drawing* characters) around some
Expand Down Expand Up @@ -324,3 +324,36 @@ multiple_on_overflow = boolean(default=False)
# actually disables highlighting for events that should use the
# default color.
default_color = color(default='')

# Override ikhal's color theme with a custom palette. This is useful to style
# certain elements of ikhal individually.
# Palette entries take the form of `key = foreground, background, mono,
# foreground_high, background_high` where foreground and background are used in
# "low color mode" and foreground_high and background_high are used in "high
# color mode" and mono if only monocolor is supported. If you don't want to set
# a value for a certain color, use an empty string (`''`).
# Valid entries for low color mode are listed on the `urwid website
# <http://urwid.org/manual/displayattributes.html#standard-foreground-colors>`_. For
# high color mode you can use any valid 24-bit color value, e.g. `'#ff0000'`.
#
# .. note::
# 24-bit colors must be enclosed in single quotes to be parsed correctly,
# otherwise the `#` will be interpreted as a comment.
#
# Most modern terminals should support high color mode.
#
# Example entry (particular ugly):
#
# .. highlight:: ini
#
# ::
#
# [palette]
# header = light red, default, default, '#ff0000', default
# edit = '', '', 'bold', '#FF00FF', '#12FF14'
# footer = '', '', '', '#121233', '#656599'
#
# See the default palettes in `khal/ui/colors.py` for all available keys.
# If you can't theme an element in ikhal, please open an issue on `github
# <https://github.com/pimutils/khal/issues/new/choose>`_.
[palette]
25 changes: 21 additions & 4 deletions khal/settings/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,10 @@ def is_timedelta(string: str) -> dt.timedelta:
raise VdtValueError(f"Invalid timedelta: {string}")


def weeknumber_option(option: str) -> Union[str, Literal[False]]:
def weeknumber_option(option: str) -> Union[Literal['left', 'right'], Literal[False]]:
"""checks if *option* is a valid value
:param option: the option the user set in the config file
:type option: str
:returns: 'off', 'left', 'right' or False
"""
option = option.lower()
Expand All @@ -89,11 +88,10 @@ def weeknumber_option(option: str) -> Union[str, Literal[False]]:
"'off', 'left' or 'right'")


def monthdisplay_option(option: str) -> str:
def monthdisplay_option(option: str) -> Literal['firstday', 'firstfullweek']:
"""checks if *option* is a valid value
:param option: the option the user set in the config file
:returns: firstday, firstfullweek
"""
option = option.lower()
if option == 'firstday':
Expand Down Expand Up @@ -215,6 +213,17 @@ def get_vdir_type(_: str) -> str:
# TODO implement
return 'calendar'

def validate_palette_entry(attr, definition: str) -> bool:
if len(definition) not in (2, 3, 5):
logging.error('Invalid color definition for %s: %s, must be of length, 2, 3, or 5',
attr, definition)
return False
if (definition[0] not in COLORS and definition[0] != '') or \
(definition[1] not in COLORS and definition[1] != ''):
logging.error('Invalid color definition for %s: %s, must be one of %s',
attr, definition, COLORS.keys())
return False
return True

def config_checks(
config,
Expand Down Expand Up @@ -263,3 +272,11 @@ def config_checks(
if config['calendars'][calendar]['color'] == 'auto':
config['calendars'][calendar]['color'] = \
_get_color_from_vdir(config['calendars'][calendar]['path'])

# check palette settings
valid_palette = True
for attr in config.get('palette', []):
valid_palette = valid_palette and validate_palette_entry(attr, config['palette'][attr])
if not valid_palette:
logger.fatal('Invalid palette entry')
raise InvalidSettingsError()
Loading

0 comments on commit 25c5c26

Please sign in to comment.