mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-06-29 04:11:49 +00:00
Replace ctypes in marks.py with C-level set_uint_at_address function
This commit is contained in:
parent
9b2c7ddcf5
commit
c35ff2e843
3 changed files with 67 additions and 23 deletions
|
|
@ -683,6 +683,17 @@ py_get_config_dir(PyObject *self UNUSED, PyObject *args UNUSED) {
|
|||
|
||||
#include "launcher/cli-parser.h"
|
||||
|
||||
static PyObject*
|
||||
set_uint_at_address(PyObject *self UNUSED, PyObject *args) {
|
||||
PyObject *address_obj;
|
||||
unsigned int value;
|
||||
if (!PyArg_ParseTuple(args, "OI", &address_obj, &value)) return NULL;
|
||||
void *ptr = PyLong_AsVoidPtr(address_obj);
|
||||
if (ptr == NULL && PyErr_Occurred()) return NULL;
|
||||
*((unsigned int*)ptr) = value;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef module_methods[] = {
|
||||
METHODB(replace_c0_codes_except_nl_space_tab, METH_O),
|
||||
METHODB(read_file, METH_O),
|
||||
|
|
@ -716,6 +727,7 @@ static PyMethodDef module_methods[] = {
|
|||
{"timed_debug_print", (PyCFunction)py_timed_debug_print, METH_VARARGS, ""},
|
||||
{"find_in_memoryview", (PyCFunction)find_in_memoryview, METH_VARARGS, ""},
|
||||
{"run_at_exit_cleanup_functions", (PyCFunction)py_run_atexit_cleanup_functions, METH_NOARGS, ""},
|
||||
{"set_uint_at_address", (PyCFunction)set_uint_at_address, METH_VARARGS, ""},
|
||||
#ifdef __APPLE__
|
||||
METHODB(user_cache_dir, METH_NOARGS),
|
||||
METHODB(process_group_map, METH_NOARGS),
|
||||
|
|
|
|||
|
|
@ -3,26 +3,16 @@
|
|||
|
||||
import re
|
||||
from collections.abc import Callable, Generator, Iterable, Sequence
|
||||
from ctypes import POINTER, c_uint, c_void_p, cast
|
||||
from re import Pattern
|
||||
from typing import Union
|
||||
|
||||
from .fast_data_types import set_uint_at_address
|
||||
from .utils import resolve_custom_file
|
||||
|
||||
pointer_to_uint = POINTER(c_uint)
|
||||
|
||||
|
||||
MarkerFunc = Callable[[str, int, int, int], Generator[None, None, None]]
|
||||
|
||||
|
||||
def get_output_variables(left_address: int, right_address: int, color_address: int) -> tuple[c_uint, c_uint, c_uint]:
|
||||
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: Union[str, 'Pattern[str]'], color: int, flags: int = re.UNICODE) -> MarkerFunc:
|
||||
color = max(1, min(color, 3))
|
||||
if isinstance(expression, str):
|
||||
|
|
@ -31,11 +21,10 @@ def marker_from_regex(expression: Union[str, 'Pattern[str]'], color: int, flags:
|
|||
pat = expression
|
||||
|
||||
def marker(text: str, left_address: int, right_address: int, color_address: int) -> Generator[None, None, None]:
|
||||
left, right, colorv = get_output_variables(left_address, right_address, color_address)
|
||||
colorv.value = color
|
||||
set_uint_at_address(color_address, color)
|
||||
for match in pat.finditer(text):
|
||||
left.value = match.start()
|
||||
right.value = match.end() - 1
|
||||
set_uint_at_address(left_address, match.start())
|
||||
set_uint_at_address(right_address, match.end() - 1)
|
||||
yield
|
||||
|
||||
return marker
|
||||
|
|
@ -52,12 +41,11 @@ def marker_from_multiple_regex(regexes: Iterable[tuple[int, str]], flags: int =
|
|||
pat = re.compile(expr, flags=flags)
|
||||
|
||||
def marker(text: str, left_address: int, right_address: int, color_address: int) -> Generator[None, None, None]:
|
||||
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
|
||||
set_uint_at_address(left_address, match.start())
|
||||
set_uint_at_address(right_address, match.end() - 1)
|
||||
grp = match.lastgroup
|
||||
color.value = color_map[grp] if grp is not None else 0
|
||||
set_uint_at_address(color_address, color_map[grp] if grp is not None else 0)
|
||||
yield
|
||||
|
||||
return marker
|
||||
|
|
@ -69,11 +57,10 @@ def marker_from_text(expression: str, color: int) -> MarkerFunc:
|
|||
|
||||
def marker_from_function(func: Callable[[str], Iterable[tuple[int, int, int]]]) -> MarkerFunc:
|
||||
def marker(text: str, left_address: int, right_address: int, color_address: int) -> Generator[None, None, None]:
|
||||
left, right, colorv = get_output_variables(left_address, right_address, color_address)
|
||||
for (ll, r, c) in func(text):
|
||||
left.value = ll
|
||||
right.value = r
|
||||
colorv.value = c
|
||||
set_uint_at_address(left_address, ll)
|
||||
set_uint_at_address(right_address, r)
|
||||
set_uint_at_address(color_address, c)
|
||||
yield
|
||||
|
||||
return marker
|
||||
|
|
|
|||
|
|
@ -940,3 +940,48 @@ class TestDataTypes(BaseTest):
|
|||
s.reset()
|
||||
s.draw('\0')
|
||||
self.ae(str(s.line(0)), '')
|
||||
|
||||
def test_set_uint_at_address(self):
|
||||
from ctypes import addressof, c_uint
|
||||
|
||||
from kitty.fast_data_types import set_uint_at_address
|
||||
from kitty.marks import marker_from_function, marker_from_multiple_regex, marker_from_regex, marker_from_text
|
||||
|
||||
# Test set_uint_at_address directly
|
||||
val = c_uint(0)
|
||||
addr = addressof(val)
|
||||
set_uint_at_address(addr, 42)
|
||||
self.ae(val.value, 42)
|
||||
set_uint_at_address(addr, 0)
|
||||
self.ae(val.value, 0)
|
||||
set_uint_at_address(addr, 0xFFFF)
|
||||
self.ae(val.value, 0xFFFF)
|
||||
|
||||
# Test marker functions using set_uint_at_address via Screen
|
||||
s = self.create_screen()
|
||||
s.draw('abaa')
|
||||
s.set_marker(marker_from_regex('a', 3))
|
||||
self.ae(s.marked_cells(), [(0, 0, 3), (2, 0, 3), (3, 0, 3)])
|
||||
s.set_marker()
|
||||
self.ae(s.marked_cells(), [])
|
||||
|
||||
s = self.create_screen()
|
||||
s.draw('aXbX')
|
||||
s.set_marker(marker_from_multiple_regex([(1, 'a'), (2, 'X')]))
|
||||
self.ae(s.marked_cells(), [(0, 0, 1), (1, 0, 2), (3, 0, 2)])
|
||||
|
||||
s = self.create_screen(cols=20)
|
||||
s.draw('hello world')
|
||||
s.set_marker(marker_from_text('world', 2))
|
||||
self.ae(s.marked_cells(), [(6, 0, 2), (7, 0, 2), (8, 0, 2), (9, 0, 2), (10, 0, 2)])
|
||||
|
||||
def mark_func(text):
|
||||
for i, ch in enumerate(text):
|
||||
if ch == 'x':
|
||||
yield i, i, 1
|
||||
|
||||
s = self.create_screen()
|
||||
s.draw('axbxc')
|
||||
s.set_marker(marker_from_function(mark_func))
|
||||
self.ae(s.marked_cells(), [(1, 0, 1), (3, 0, 1)])
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue