Tokenizes a line of code, returning pygments tokens with side effects/impurities: - reads self.cpos to see what parens should be highlighted - reads self.buffer to see what came before the passed in line - sets self.highlighted_paren to (buffer_lineno, tokens_for_that
(self, s, newline=False)
| 1092 | """See the flush() method docstring.""" |
| 1093 | |
| 1094 | def tokenize(self, s, newline=False) -> list[tuple[_TokenType, str]]: |
| 1095 | """Tokenizes a line of code, returning pygments tokens |
| 1096 | with side effects/impurities: |
| 1097 | - reads self.cpos to see what parens should be highlighted |
| 1098 | - reads self.buffer to see what came before the passed in line |
| 1099 | - sets self.highlighted_paren to (buffer_lineno, tokens_for_that_line) |
| 1100 | for buffer line that should replace that line to unhighlight it, |
| 1101 | or None if no paren is currently highlighted |
| 1102 | - calls reprint_line with a buffer's line's tokens and the buffer |
| 1103 | lineno that has changed if line other than the current line changes |
| 1104 | """ |
| 1105 | highlighted_paren = None |
| 1106 | |
| 1107 | source = "\n".join(self.buffer + [s]) |
| 1108 | cursor = len(source) - self.cpos |
| 1109 | if self.cpos: |
| 1110 | cursor += 1 |
| 1111 | stack: list[Any] = list() |
| 1112 | all_tokens = list(Python3Lexer().get_tokens(source)) |
| 1113 | # Unfortunately, Pygments adds a trailing newline and strings with |
| 1114 | # no size, so strip them |
| 1115 | while not all_tokens[-1][1]: |
| 1116 | all_tokens.pop() |
| 1117 | all_tokens[-1] = (all_tokens[-1][0], all_tokens[-1][1].rstrip("\n")) |
| 1118 | line = pos = 0 |
| 1119 | parens = dict(zip("{([", "})]")) |
| 1120 | line_tokens: list[tuple[_TokenType, str]] = list() |
| 1121 | saved_tokens: list[tuple[_TokenType, str]] = list() |
| 1122 | search_for_paren = True |
| 1123 | for token, value in split_lines(all_tokens): |
| 1124 | pos += len(value) |
| 1125 | if token is Token.Text and value == "\n": |
| 1126 | line += 1 |
| 1127 | # Remove trailing newline |
| 1128 | line_tokens = list() |
| 1129 | saved_tokens = list() |
| 1130 | continue |
| 1131 | line_tokens.append((token, value)) |
| 1132 | saved_tokens.append((token, value)) |
| 1133 | if not search_for_paren: |
| 1134 | continue |
| 1135 | under_cursor = pos == cursor |
| 1136 | if token is Token.Punctuation: |
| 1137 | if value in parens: |
| 1138 | if under_cursor: |
| 1139 | line_tokens[-1] = (Parenthesis.UnderCursor, value) |
| 1140 | # Push marker on the stack |
| 1141 | stack.append((Parenthesis, value)) |
| 1142 | else: |
| 1143 | stack.append( |
| 1144 | (line, len(line_tokens) - 1, line_tokens, value) |
| 1145 | ) |
| 1146 | elif value in parens.values(): |
| 1147 | saved_stack = list(stack) |
| 1148 | try: |
| 1149 | while True: |
| 1150 | opening = stack.pop() |
| 1151 | if parens[opening[-1]] == value: |
no test coverage detected