Fixes the exception below that happened for function-markers:
```
Traceback (most recent call last):
File "/usr/bin/../lib/kitty/kitty/boss.py", line 540, in dispatch_special_key
return self.dispatch_action(key_action)
File "/usr/bin/../lib/kitty/kitty/boss.py", line 612, in dispatch_action
passthrough = f(*key_action.args)
File "/usr/bin/../lib/kitty/kitty/window.py", line 615, in toggle_marker
self.screen.set_marker(marker_from_spec(ftype, spec, flags))
File "/usr/bin/../lib/kitty/kitty/marks.py", line 92, in marker_from_spec
return marker_from_function(runpy.run_path(path, run_name='__marker__').marker)
```
94 lines
2.8 KiB
Python
94 lines
2.8 KiB
Python
#!/usr/bin/env python
|
|
# vim:fileencoding=utf-8
|
|
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
|
|
|
import os
|
|
import re
|
|
from ctypes import POINTER, c_uint, c_void_p, cast
|
|
|
|
from .constants import config_dir
|
|
|
|
pointer_to_uint = POINTER(c_uint)
|
|
|
|
|
|
def null_marker(*a):
|
|
return iter(())
|
|
|
|
|
|
def get_output_variables(left_address, right_address, color_address):
|
|
return (
|
|
cast(c_void_p(left_address), pointer_to_uint).contents,
|
|
cast(c_void_p(right_address), pointer_to_uint).contents,
|
|
cast(c_void_p(color_address), pointer_to_uint).contents,
|
|
)
|
|
|
|
|
|
def marker_from_regex(expression, color, flags=re.UNICODE):
|
|
color = max(1, min(color, 3))
|
|
if isinstance(expression, str):
|
|
pat = re.compile(expression, flags=flags)
|
|
else:
|
|
pat = expression
|
|
|
|
def marker(text, left_address, right_address, color_address):
|
|
left, right, colorv = get_output_variables(left_address, right_address, color_address)
|
|
colorv.value = color
|
|
for match in pat.finditer(text):
|
|
left.value = match.start()
|
|
right.value = match.end() - 1
|
|
yield
|
|
|
|
return marker
|
|
|
|
|
|
def marker_from_multiple_regex(regexes, flags=re.UNICODE):
|
|
expr = ''
|
|
color_map = {}
|
|
for i, (color, spec) in enumerate(regexes):
|
|
grp = 'mcg{}'.format(i)
|
|
expr += '|(?P<{}>{})'.format(grp, spec)
|
|
color_map[grp] = color
|
|
expr = expr[1:]
|
|
pat = re.compile(expr, flags=flags)
|
|
|
|
def marker(text, left_address, right_address, color_address):
|
|
left, right, color = get_output_variables(left_address, right_address, color_address)
|
|
for match in pat.finditer(text):
|
|
left.value = match.start()
|
|
right.value = match.end() - 1
|
|
grp = next(k for k, v in match.groupdict().items() if v is not None)
|
|
color.value = color_map[grp]
|
|
yield
|
|
|
|
return marker
|
|
|
|
|
|
def marker_from_text(expression, color):
|
|
return marker_from_regex(re.escape(expression), color)
|
|
|
|
|
|
def marker_from_function(func):
|
|
def marker(text, left_address, right_address, color_address):
|
|
left, right, colorv = get_output_variables(left_address, right_address, color_address)
|
|
for (l, r, c) in func(text):
|
|
left.value = l
|
|
right.value = r
|
|
colorv.value = c
|
|
yield
|
|
|
|
return marker
|
|
|
|
|
|
def marker_from_spec(ftype, spec, flags):
|
|
if ftype == 'regex':
|
|
if len(spec) == 1:
|
|
return marker_from_regex(spec[0][1], spec[0][0], flags=flags)
|
|
return marker_from_multiple_regex(spec, flags=flags)
|
|
if ftype == 'function':
|
|
import runpy
|
|
path = spec
|
|
if not os.path.isabs(path):
|
|
path = os.path.join(config_dir, path)
|
|
return marker_from_function(runpy.run_path(path, run_name='__marker__')["marker"])
|
|
raise ValueError('Unknown marker type: {}'.format(ftype))
|