mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-11-13 03:12:37 +03:00
API to set text in Line efficiently
This commit is contained in:
parent
b02dc836fb
commit
44e8238eaf
@ -112,6 +112,10 @@ class Line:
|
||||
to.bg[dest] = self.bg[src]
|
||||
to.decoration_fg[dest] = self.decoration_fg[src]
|
||||
|
||||
def cursor_to_attrs(self, c: Cursor) -> int:
|
||||
return ((c.decoration & 0b11) << DECORATION_SHIFT) | ((c.bold & 0b1) << BOLD_SHIFT) | \
|
||||
((c.italic & 0b1) << ITALIC_SHIFT) | ((c.reverse & 0b1) << REVERSE_SHIFT) | ((c.strikethrough & 0b1) << STRIKE_SHIFT)
|
||||
|
||||
def apply_cursor(self, c: Cursor, at: int=0, num: int=1, clear_char=False, char=' ') -> None:
|
||||
for i in range(at, at + num):
|
||||
self.fg[i] = c.fg
|
||||
@ -121,8 +125,7 @@ class Line:
|
||||
ch = ord(char) if clear_char else sc & CHAR_MASK
|
||||
sattrs = sc >> ATTRS_SHIFT
|
||||
w = 1 if clear_char else sattrs & WIDTH_MASK
|
||||
attrs = w | ((c.decoration & 0b11) << DECORATION_SHIFT) | ((c.bold & 0b1) << BOLD_SHIFT) | \
|
||||
((c.italic & 0b1) << ITALIC_SHIFT) | ((c.reverse & 0b1) << REVERSE_SHIFT) | ((c.strikethrough & 0b1) << STRIKE_SHIFT)
|
||||
attrs = w | self.cursor_to_attrs(c)
|
||||
self.char[i] = (ch & CHAR_MASK) | (attrs << ATTRS_SHIFT)
|
||||
|
||||
def cursor_from(self, x: int, ypos: int=0) -> Cursor:
|
||||
@ -136,6 +139,17 @@ class Line:
|
||||
c.strikethrough = bool((attrs >> STRIKE_SHIFT) & 0b1)
|
||||
return c
|
||||
|
||||
def set_text(self, text: str, offset_in_text: int, sz: int, cursor: Cursor) -> None:
|
||||
' Set the specified text in this line, with attributes taken from the cursor '
|
||||
attrs = self.cursor_to_attrs(cursor) | 1
|
||||
fg, bg, dfg = cursor.fg, cursor.bg, cursor.decoration_fg
|
||||
dx = cursor.x
|
||||
for cpos in range(offset_in_text, offset_in_text + sz):
|
||||
ch = ord(text[cpos]) & CHAR_MASK
|
||||
self.char[dx] = ch | (attrs << ATTRS_SHIFT)
|
||||
self.fg[dx], self.bg[dx], self.decoration_fg[dx] = fg, bg, dfg
|
||||
dx += 1
|
||||
|
||||
def copy_slice(self, src, dest, num):
|
||||
src, dest = slice(src, src + num), slice(dest, dest + num)
|
||||
for a in (self.char, self.fg, self.bg, self.decoration_fg):
|
||||
@ -164,10 +178,14 @@ class Line:
|
||||
def width(self, i):
|
||||
return (self.char[i] >> ATTRS_SHIFT) & 0b11
|
||||
|
||||
def set_char(self, i, ch, width=1):
|
||||
c = self.char[i]
|
||||
a = c >> ATTRS_SHIFT
|
||||
a = (a & ~WIDTH_MASK) | (width & WIDTH_MASK)
|
||||
def set_char(self, i: int, ch: str, width: int=1, cursor: Cursor=None) -> None:
|
||||
if cursor is None:
|
||||
c = self.char[i]
|
||||
a = (c >> ATTRS_SHIFT) & ~WIDTH_MASK
|
||||
else:
|
||||
a = self.cursor_to_attrs(cursor)
|
||||
self.fg[i], self.bg[i], self.decoration_fg[i] = cursor.fg, cursor.bg, cursor.decoration_fg
|
||||
a |= width & WIDTH_MASK
|
||||
self.char[i] = (a << ATTRS_SHIFT) | (ord(ch) & CHAR_MASK)
|
||||
|
||||
def set_bold(self, i, val):
|
||||
|
@ -8,12 +8,3 @@ from unittest import TestCase
|
||||
class BaseTest(TestCase):
|
||||
|
||||
ae = TestCase.assertEqual
|
||||
|
||||
|
||||
def set_text_in_line(line, text, offset=0):
|
||||
pos = offset
|
||||
for ch in text:
|
||||
line.set_char(pos, ch)
|
||||
pos += 1
|
||||
if pos >= len(line):
|
||||
break
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
import codecs
|
||||
|
||||
from . import BaseTest, set_text_in_line
|
||||
from . import BaseTest
|
||||
|
||||
from kitty.data_types import Line, Cursor
|
||||
from kitty.utils import is_simple_string, wcwidth
|
||||
@ -15,7 +15,7 @@ class TestDataTypes(BaseTest):
|
||||
def test_line_ops(self):
|
||||
t = 'Testing with simple text'
|
||||
l = Line(len(t))
|
||||
set_text_in_line(l, t)
|
||||
l.set_text(t, 0, len(t), Cursor())
|
||||
self.ae(l, l)
|
||||
self.ae(str(l), t)
|
||||
self.ae(str(l.copy()), t)
|
||||
@ -49,7 +49,7 @@ class TestDataTypes(BaseTest):
|
||||
|
||||
t = '0123456789'
|
||||
lo = Line(len(t))
|
||||
set_text_in_line(lo, t)
|
||||
lo.set_text(t, 0, len(t), Cursor())
|
||||
l = lo.copy()
|
||||
l.right_shift(4, 2)
|
||||
self.ae(str(l), '0123454567')
|
||||
@ -75,6 +75,14 @@ class TestDataTypes(BaseTest):
|
||||
l.set_decoration(0, q.decoration)
|
||||
c = l.cursor_from(0)
|
||||
self.ae(c, q)
|
||||
l = Line(len(t))
|
||||
l.set_text(t, 0, len(t), q)
|
||||
self.ae(l.cursor_from(0), q)
|
||||
l.set_text('axyb', 1, 2, Cursor(3))
|
||||
self.ae(str(l), '012xy56789')
|
||||
l = Line(1)
|
||||
l.set_char(0, 'x', cursor=q)
|
||||
self.ae(l.cursor_from(0), q)
|
||||
|
||||
def test_utils(self):
|
||||
d = codecs.getincrementaldecoder('utf-8')('strict').decode
|
||||
|
Loading…
Reference in New Issue
Block a user