From 36074eabc83814e69c6603bad5617e04270f1bb0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 7 Nov 2024 13:14:33 +0530 Subject: [PATCH] Make code to parse color specs and patch options objects re-useable --- kitty/boss.py | 11 ++-------- kitty/colors.py | 47 ++++++++++++++++++++++++++++++++++++++++++ kitty/launch.py | 2 +- kitty/rc/set_colors.py | 28 ++----------------------- 4 files changed, 52 insertions(+), 36 deletions(-) create mode 100644 kitty/colors.py diff --git a/kitty/boss.py b/kitty/boss.py index 20bf74ade..f3cd4a5ce 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -118,7 +118,6 @@ from .notifications import NotificationManager from .options.types import Options, nullable_colors from .options.utils import MINIMUM_FONT_SIZE, KeyboardMode, KeyDefinition from .os_window_size import initial_window_size_func -from .rgb import color_from_int from .session import Session, create_sessions, get_os_window_sizing_data from .shaders import load_shader_programs from .tabs import SpecialWindow, SpecialWindowInstance, Tab, TabDict, TabManager @@ -2641,14 +2640,8 @@ class Boss: def patch_colors(self, spec: dict[str, Optional[int]], transparent_background_colors: tuple[tuple[Color, float], ...], configured: bool = False) -> None: opts = get_options() if configured: - for k, v in spec.items(): - if hasattr(opts, k): - if v is None: - if k in nullable_colors: - setattr(opts, k, None) - else: - setattr(opts, k, color_from_int(v)) - opts.transparent_background_colors = transparent_background_colors + from kitty.colors import patch_options_with_color_spec + patch_options_with_color_spec(opts, spec, transparent_background_colors) for tm in self.all_tab_managers: tm.tab_bar.patch_colors(spec) tm.tab_bar.layout() diff --git a/kitty/colors.py b/kitty/colors.py new file mode 100644 index 000000000..952a71c75 --- /dev/null +++ b/kitty/colors.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# License: GPLv3 Copyright: 2024, Kovid Goyal + +import os +from typing import Iterable, Optional, Union + +from .config import parse_config +from .fast_data_types import Color +from .options.types import Options, nullable_colors +from .rgb import color_from_int + + +def parse_colors(args: Iterable[Union[str, Iterable[str]]]) -> tuple[dict[str, Optional[int]], tuple[tuple[Color, float], ...]]: + colors: dict[str, Optional[Color]] = {} + nullable_color_map: dict[str, Optional[int]] = {} + transparent_background_colors = () + for spec in args: + if isinstance(spec, str): + if '=' in spec: + conf = parse_config((spec.replace('=', ' '),)) + else: + with open(os.path.expanduser(spec), encoding='utf-8', errors='replace') as f: + conf = parse_config(f) + else: + conf = parse_config(spec) + transparent_background_colors = conf.pop('transparent_background_colors', ()) + colors.update(conf) + for k in nullable_colors: + q = colors.pop(k, False) + if q is not False: + val = int(q) if isinstance(q, Color) else None + nullable_color_map[k] = val + ans: dict[str, Optional[int]] = {k: int(v) for k, v in colors.items() if isinstance(v, Color)} + ans.update(nullable_color_map) + return ans, transparent_background_colors + + +def patch_options_with_color_spec(opts: Options, spec: dict[str, Optional[int]], transparent_background_colors: tuple[tuple[Color, float], ...]) -> None: + + for k, v in spec.items(): + if hasattr(opts, k): + if v is None: + if k in nullable_colors: + setattr(opts, k, None) + else: + setattr(opts, k, color_from_int(v)) + opts.transparent_background_colors = transparent_background_colors diff --git a/kitty/launch.py b/kitty/launch.py index 123ae3093..2b2ee594e 100644 --- a/kitty/launch.py +++ b/kitty/launch.py @@ -486,7 +486,7 @@ class LaunchKwds(TypedDict): def apply_colors(window: Window, spec: Sequence[str]) -> None: - from kitty.rc.set_colors import parse_colors + from .colors import parse_colors colors, transparent_background_colors = parse_colors(spec) profiles = window.screen.color_profile, patch_color_profiles(colors, transparent_background_colors, profiles, True) diff --git a/kitty/rc/set_colors.py b/kitty/rc/set_colors.py index 0f7db8804..df2e770ca 100644 --- a/kitty/rc/set_colors.py +++ b/kitty/rc/set_colors.py @@ -2,11 +2,9 @@ # License: GPLv3 Copyright: 2020, Kovid Goyal -import os -from typing import TYPE_CHECKING, Dict, Iterable, Optional +from typing import TYPE_CHECKING, Dict, Optional from kitty.cli import emph -from kitty.config import parse_config from kitty.fast_data_types import Color, patch_color_profiles from .base import ( @@ -27,29 +25,6 @@ if TYPE_CHECKING: from kitty.cli_stub import SetColorsRCOptions as CLIOptions -def parse_colors(args: Iterable[str]) -> tuple[Dict[str, Optional[int]], tuple[tuple[Color, float], ...]]: - from kitty.options.types import nullable_colors - colors: Dict[str, Optional[Color]] = {} - nullable_color_map: Dict[str, Optional[int]] = {} - transparent_background_colors = () - for spec in args: - if '=' in spec: - conf = parse_config((spec.replace('=', ' '),)) - else: - with open(os.path.expanduser(spec), encoding='utf-8', errors='replace') as f: - conf = parse_config(f) - transparent_background_colors = conf.pop('transparent_background_colors', ()) - colors.update(conf) - for k in nullable_colors: - q = colors.pop(k, False) - if q is not False: - val = int(q) if isinstance(q, Color) else None - nullable_color_map[k] = val - ans: Dict[str, Optional[int]] = {k: int(v) for k, v in colors.items() if isinstance(v, Color)} - ans.update(nullable_color_map) - return ans, transparent_background_colors - - class SetColors(RemoteCommand): protocol_spec = __doc__ = ''' @@ -93,6 +68,7 @@ this option, any color arguments are ignored and :option:`kitten @ set-colors -- def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType: final_colors: Dict[str, int | None | str] = {} transparent_background_colors: tuple[tuple[Color, float], ...] = () + from kitty.colors import parse_colors if not opts.reset: try: fc, transparent_background_colors = parse_colors(args)