From 1efb60a429a7145d0ea4247f18f245e60ecf663a Mon Sep 17 00:00:00 2001 From: Goffi Date: Tue, 1 Oct 2019 22:49:10 +0200 Subject: [PATCH] jp: dark and light theme: - `background` setting can now be used in sat.conf to indicate if the terminal use a `dark` or a `light` colour - if `background` is not set or set to `auto`, the background colour is autodetected - Jp.get_config (or CommandBase.get_config) method can now be used to retrieve a setting --- doc/configuration.rst | 3 ++ sat_frontends/jp/base.py | 61 ++++++++++++++++++++++++++++++++++++ sat_frontends/jp/cmd_blog.py | 2 +- sat_frontends/jp/common.py | 1 - 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/doc/configuration.rst b/doc/configuration.rst index dca9de71..990bda60 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -103,6 +103,9 @@ the comments to get the meaning of each option. hosts_dict = { "example.org": {"host": "127.0.0.1"} } + ; background luminance, used by terminal frontends + ; can be "auto" (default) to autodetect, "dark" or "light" + background = auto [plugin account] ; where a new account must be created diff --git a/sat_frontends/jp/base.py b/sat_frontends/jp/base.py index b563b28d..f135797a 100644 --- a/sat_frontends/jp/base.py +++ b/sat_frontends/jp/base.py @@ -30,6 +30,8 @@ import os import os.path import argparse import inspect +import tty +import termios from pathlib import Path from glob import iglob from importlib import import_module @@ -38,6 +40,8 @@ from sat.tools import config from sat.tools.common import dynamic_import from sat.tools.common import uri from sat.tools.common import date_utils +from sat.tools.common import utils +from sat.tools.common.ansi import ANSI as A from sat.core import exceptions import sat_frontends.jp from sat_frontends.jp.loops import QuitException, getJPLoop @@ -100,6 +104,8 @@ class Jp(object): @attribute progress_failure(callable): method to call when progress failed by default display a message """ + self.sat_conf = main_config + self.set_color_theme() bridge_module = dynamic_import.bridge(bridge_name, 'sat_frontends.bridge') if bridge_module is None: log.error("Can't import {} bridge".format(bridge_name)) @@ -108,6 +114,57 @@ class Jp(object): self.bridge = bridge_module.AIOBridge() self._onQuitCallbacks = [] + def get_config(self, name, section='jp', default=None): + """Retrieve a setting value from sat.conf""" + return config.getConfig(self.sat_conf, section, name, default=default) + + def guess_background(self): + stdin_fd = sys.stdin.fileno() + old_settings = termios.tcgetattr(stdin_fd) + try: + tty.setraw(sys.stdin.fileno()) + # we request background color + sys.stdout.write("\033]11;?\a") + sys.stdout.flush() + expected = "\033]11;rgb:" + for c in expected: + ch = sys.stdin.read(1) + if ch != c: + # background id is not supported + # TODO: log something? + return + red, green, blue = [int(c, 16)/65535 for c in sys.stdin.read(14).split('/')] + # '\a' is the last character + sys.stdin.read(1) + finally: + termios.tcsetattr(stdin_fd, termios.TCSADRAIN, old_settings) + + lum = utils.per_luminance(red, green, blue) + if lum <= 0.5: + return 'dark' + else: + return 'light' + + def set_color_theme(self): + background = self.get_config('background', default='auto') + if background == 'auto': + background = self.guess_background() + if background not in ('dark', 'light'): + raise exceptions.ConfigError(_( + f'Invalid value set for "background" ({background!r}), please check ' + f'your settings in sat.conf')) + if background == 'light': + C.A_HEADER = A.FG_MAGENTA + C.A_SUBHEADER = A.BOLD + A.FG_RED + C.A_LEVEL_COLORS = (C.A_HEADER, A.BOLD + A.FG_BLUE, A.FG_MAGENTA, A.FG_CYAN) + C.A_SUCCESS = A.FG_GREEN + C.A_FAILURE = A.BOLD + A.FG_RED + C.A_WARNING = A.FG_RED + C.A_PROMPT_PATH = A.FG_BLUE + C.A_PROMPT_SUF = A.BOLD + C.A_DIRECTORY = A.BOLD + A.FG_MAGENTA + C.A_FILE = A.FG_BLACK + def _bridgeConnected(self): self.parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=DESCRIPTION) @@ -897,6 +954,10 @@ class CommandBase(object): self.parser.set_defaults(_cmd=self) self.add_parser_options() + @property + def sat_conf(self): + return self.host.sat_conf + @property def args(self): return self.host.args diff --git a/sat_frontends/jp/cmd_blog.py b/sat_frontends/jp/cmd_blog.py index 34205a32..022df1d1 100644 --- a/sat_frontends/jp/cmd_blog.py +++ b/sat_frontends/jp/cmd_blog.py @@ -719,7 +719,7 @@ class Preview(base.CommandBase, common.BaseEdit): else: aionotify = None - sat_conf = config.parseMainConf() + sat_conf = self.sat_conf SYNTAX_EXT.update(config.getConfig(sat_conf, "jp", CONF_SYNTAX_EXT, {})) try: diff --git a/sat_frontends/jp/common.py b/sat_frontends/jp/common.py index 6de59f44..951cfd66 100644 --- a/sat_frontends/jp/common.py +++ b/sat_frontends/jp/common.py @@ -126,7 +126,6 @@ class BaseEdit(object): and vice versa """ self.host = host - self.sat_conf = config.parseMainConf() self.cat_dir = cat_dir self.use_metadata = use_metadata