diff --git a/highlight_selection.py b/highlight_selection.py index cd4b5c4..9f0b6d5 100644 --- a/highlight_selection.py +++ b/highlight_selection.py @@ -45,7 +45,10 @@ class HighlightSelection(Highlight): start_column = line.char_to_column(start_char) end_column = line.char_to_column(end_char) - length_in_columns = end_column - start_column + if end_column >= 0: + length_in_columns = end_column - start_column + else: + length_in_columns = 4096 return [HighlightedRange(start_column, length_in_columns, brush=QBrush(QColor(156, 215, 255, 192)), pen=Qt.PenStyle.NoPen)] diff --git a/line.py b/line.py index a738970..f2f4e64 100644 --- a/line.py +++ b/line.py @@ -1,3 +1,5 @@ +from typing import Dict + import constants @@ -6,6 +8,7 @@ class Line: self._byte_offset = byte_offset self._byte_end = byte_end self._line = line + self._char_to_column_cache = self._cache_char_to_column() def byte_offset(self) -> int: return self._byte_offset @@ -63,17 +66,25 @@ class Line: return result - # todo this method is slow def char_to_column(self, char_in_line: int) -> int: + if not char_in_line in self._char_to_column_cache: + # print("%d in %s" % (char_in_line, self._char_to_column_cache)) + return -1 + return self._char_to_column_cache[char_in_line] + + def _cache_char_to_column(self) -> Dict[int, int]: + char_to_column_cache = {} result = 0 i = 0 - while i < char_in_line: + char_to_column_cache[0] = 0 + while i < len(self._line): if i < len(self._line) and self._line[i] == "\t": result = result + constants.tab_width - result % constants.tab_width else: result = result + 1 i = i + 1 - return result + char_to_column_cache[i] = result + return char_to_column_cache def includes_byte(self, byte: int) -> bool: return self._byte_offset <= byte <= self._byte_end