diff --git a/kitty/config.py b/kitty/config.py index 91c27c775..65b3e99c9 100644 --- a/kitty/config.py +++ b/kitty/config.py @@ -241,6 +241,47 @@ def disable_ligatures_in(func, rest): return func, [where, strategy] +@func_with_args('add_marker') +def add_marker(func, rest): + parts = rest.split(maxsplit=1) + if len(parts) != 2: + raise ValueError('{} if not a valid marker specification'.format(rest)) + name = parts[0] + parts = parts[1].split(':', maxsplit=1) + if len(parts) != 2: + raise ValueError('{} if not a valid marker specification'.format(rest)) + ftype, spec = parts + color = None + if ftype in ('text', 'itext', 'regex'): + flags = re.UNICODE + parts = spec.split(':', maxsplit=1) + if len(parts) != 2: + raise ValueError('No color specified in marker: {}'.format(spec)) + try: + color = int(parts[0]) + except Exception: + raise ValueError('color {} in marker specification is not an integer'.format(parts[0])) + spec = parts[1] + if ftype in ('text', 'itext'): + spec = re.escape(spec) + flags |= re.IGNORECASE + ftype = 'regex' + try: + spec = re.compile(spec, flgas=flags) + except Exception: + raise ValueError('{} is not a valid regular expression'.format(spec)) + elif ftype == 'function': + pass + else: + raise ValueError('Unknown marker type: {}'.format(ftype)) + return func, [name, ftype, spec, color] + + +@func_with_args('remove_marker') +def remove_marker(func, rest): + return func, [rest] + + def parse_key_action(action): parts = action.strip().split(maxsplit=1) func = parts[0] diff --git a/kitty/marks.py b/kitty/marks.py index 168c37481..9bac90628 100644 --- a/kitty/marks.py +++ b/kitty/marks.py @@ -23,7 +23,10 @@ def get_output_variables(left_address, right_address, color_address): def marker_from_regex(expression, color): color = max(1, min(color, 3)) - pat = re.compile(expression) + if isinstance(expression, str): + pat = re.compile(expression) + else: + pat = expression def marker(text, left_address, right_address, color_address): left, right, colorv = get_output_variables(left_address, right_address, color_address) diff --git a/kitty/window.py b/kitty/window.py index bfaeaa70a..6e81380ac 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -12,7 +12,7 @@ from itertools import chain from .config import build_ansi_color_table from .constants import ( - ScreenGeometry, WindowGeometry, appname, get_boss, wakeup + ScreenGeometry, WindowGeometry, appname, get_boss, wakeup, config_dir ) from .fast_data_types import ( BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM, CELL_PROGRAM, @@ -603,4 +603,21 @@ class Window: def scroll_end(self): if self.screen.is_main_linebuf(): self.screen.scroll(SCROLL_FULL, False) + + def add_marker(self, name, ftype, spec, color): + from .marks import marker_from_regex, marker_from_function + if ftype == 'regex': + marker = marker_from_regex(spec, color) + elif ftype == 'function': + import runpy + path = spec + if not os.path.isabs(path): + path = os.path.join(config_dir, path) + marker = marker_from_function(runpy.run_path(path, run_name='__marker__').marker) + else: + raise ValueError('Unknown marker type: {}'.format(ftype)) + self.screen.add_marker(name, marker) + + def remove_marker(self, name): + self.screen.remove_marker(name) # }}}