Compare commits
3 Commits
9c1b8298be
...
be53c209ea
| Author | SHA1 | Date | |
|---|---|---|---|
| be53c209ea | |||
| aa2bfa967e | |||
| 2b91b19ef3 |
@@ -116,7 +116,7 @@ class Line:
|
||||
# todo there are many other character combinations that should be skipped
|
||||
while i < len(self._line) and unicodedata.category(self._line[i]) == "Mn":
|
||||
self._char_to_column_cache[i] = result - 1
|
||||
if not result in self._column_to_char_cache:
|
||||
if (result - 1) not in self._column_to_char_cache:
|
||||
self._column_to_char_cache[result - 1] = i
|
||||
i = i + 1
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ from src.ui.bigtext.highlighting import Highlighting
|
||||
from src.ui.bigtext.line import Line
|
||||
import os
|
||||
from src.settings.settings import Settings
|
||||
from functools import lru_cache
|
||||
|
||||
|
||||
class LogFileModel:
|
||||
@@ -21,6 +22,8 @@ class LogFileModel:
|
||||
range_start = 0
|
||||
range_end = -1
|
||||
|
||||
_line_cache = {}
|
||||
|
||||
def __init__(self, file: str, settings: Settings, original_file: str = False):
|
||||
"""
|
||||
:param file:
|
||||
@@ -133,6 +136,13 @@ class LogFileModel:
|
||||
def _is_word_char(self, char: str) -> bool:
|
||||
return re.match(r"\w", char) is not None
|
||||
|
||||
def prune_cache(self, range_start: int, range_end: int):
|
||||
for key in list(self._line_cache.keys()):
|
||||
line = self._line_cache[key]
|
||||
if range_start > line.byte_end() or line.byte_offset() > range_end:
|
||||
del self._line_cache[key]
|
||||
|
||||
|
||||
def data(self, byte_offset: int, scroll_lines: int, lines: int, range_start: int, range_end: int) -> List[Line]:
|
||||
# print("data(%s, %s, %s)" % (byte_offset, scroll_lines, lines))
|
||||
lines_before_offset: List[Line] = []
|
||||
@@ -148,19 +158,36 @@ class LogFileModel:
|
||||
offset = max(0,
|
||||
max(range_start - self.settings.max_line_length(), offset - self.settings.max_line_length()))
|
||||
|
||||
self.prune_cache(range_start, range_end)
|
||||
|
||||
previous_line_is_complete = False
|
||||
f.seek(offset)
|
||||
while l := f.readline():
|
||||
while True:
|
||||
line: Line | None = self._line_cache.get(offset)
|
||||
if line is None:
|
||||
line_bytes = f.readline()
|
||||
if not line_bytes:
|
||||
break
|
||||
new_offset = f.tell()
|
||||
if 0 <= range_end < new_offset:
|
||||
break
|
||||
line = Line(offset, new_offset, l.decode("utf8", errors="ignore"))
|
||||
line = Line(offset, new_offset, line_bytes.decode("utf8", errors="ignore"))
|
||||
if previous_line_is_complete: # only cache lines when we know they are complete
|
||||
self._line_cache[offset] = line
|
||||
offset = new_offset
|
||||
previous_line_is_complete = True
|
||||
else:
|
||||
# print(f"loaded cached line at offset {offset}")
|
||||
offset = line.byte_end() # line.byte_end() returns the end byte +1
|
||||
f.seek(offset)
|
||||
previous_line_is_complete = True
|
||||
|
||||
if line.byte_end() <= byte_offset: # line.byte_end() returns the end byte +1
|
||||
if line.byte_offset() >= range_start: # only add if in range
|
||||
lines_before_offset.append(line)
|
||||
else:
|
||||
lines_after_offset.append(line)
|
||||
offset = f.tell()
|
||||
|
||||
if len(lines_after_offset) >= lines_to_find:
|
||||
break
|
||||
|
||||
|
||||
@@ -31,9 +31,9 @@ class MyTestCase(unittest.TestCase):
|
||||
self.assertEqual(9, line.column_to_char(15)) # tab
|
||||
self.assertEqual(10, line.column_to_char(16)) # g
|
||||
|
||||
def test_column_to_char_ignore_nonspacing_mark_charaters(self):
|
||||
def test_column_to_char_ignore_nonspacing_mark_characters(self):
|
||||
"""
|
||||
nonspacing mark charaters are those little decorations that are applied to the previous character,
|
||||
nonspacing mark characters are those little decorations that are applied to the previous character,
|
||||
e.g. x\u0308 to make ẍ
|
||||
:return:
|
||||
"""
|
||||
@@ -63,7 +63,7 @@ class MyTestCase(unittest.TestCase):
|
||||
|
||||
def test_char_to_column_ignore_nonspacing_mark_charaters(self):
|
||||
"""
|
||||
nonspacing mark charaters are those little decorations that are applied to the previous character,
|
||||
nonspacing mark characters are those little decorations that are applied to the previous character,
|
||||
e.g. x\u0308 to make ẍ
|
||||
:return:
|
||||
"""
|
||||
@@ -119,7 +119,7 @@ class MyTestCase(unittest.TestCase):
|
||||
for i in range(128):
|
||||
if unicodedata.category(chr(i)) == "Cc":
|
||||
# print(i, " -> ", ord(chr(i)), " --> ", chr(9216 + i))
|
||||
if not i in [9, 10, 11, 13]:
|
||||
if i not in [9, 10, 11, 13]:
|
||||
text = text + chr(i)
|
||||
|
||||
line = Line(byte_offset=byte_offset, byte_end=byte_offset + len(text.encode("utf8")), line=text)
|
||||
|
||||
Reference in New Issue
Block a user