diff options
author | nkozlovskiy <nmk@ydb.tech> | 2023-09-29 12:24:06 +0300 |
---|---|---|
committer | nkozlovskiy <nmk@ydb.tech> | 2023-09-29 12:41:34 +0300 |
commit | e0e3e1717e3d33762ce61950504f9637a6e669ed (patch) | |
tree | bca3ff6939b10ed60c3d5c12439963a1146b9711 /contrib/python/prompt-toolkit/py2/prompt_toolkit/layout/utils.py | |
parent | 38f2c5852db84c7b4d83adfcb009eb61541d1ccd (diff) | |
download | ydb-e0e3e1717e3d33762ce61950504f9637a6e669ed.tar.gz |
add ydb deps
Diffstat (limited to 'contrib/python/prompt-toolkit/py2/prompt_toolkit/layout/utils.py')
-rw-r--r-- | contrib/python/prompt-toolkit/py2/prompt_toolkit/layout/utils.py | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/layout/utils.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/layout/utils.py new file mode 100644 index 0000000000..a4fb7ed0f5 --- /dev/null +++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/layout/utils.py @@ -0,0 +1,181 @@ +from __future__ import unicode_literals + +from prompt_toolkit.utils import get_cwidth +from prompt_toolkit.token import Token + +__all__ = ( + 'token_list_len', + 'token_list_width', + 'token_list_to_text', + 'explode_tokens', + 'split_lines', + 'find_window_for_buffer_name', +) + + +def token_list_len(tokenlist): + """ + Return the amount of characters in this token list. + + :param tokenlist: List of (token, text) or (token, text, mouse_handler) + tuples. + """ + ZeroWidthEscape = Token.ZeroWidthEscape + return sum(len(item[1]) for item in tokenlist if item[0] != ZeroWidthEscape) + + +def token_list_width(tokenlist): + """ + Return the character width of this token list. + (Take double width characters into account.) + + :param tokenlist: List of (token, text) or (token, text, mouse_handler) + tuples. + """ + ZeroWidthEscape = Token.ZeroWidthEscape + return sum(get_cwidth(c) for item in tokenlist for c in item[1] if item[0] != ZeroWidthEscape) + + +def token_list_to_text(tokenlist): + """ + Concatenate all the text parts again. + """ + ZeroWidthEscape = Token.ZeroWidthEscape + return ''.join(item[1] for item in tokenlist if item[0] != ZeroWidthEscape) + + +def iter_token_lines(tokenlist): + """ + Iterator that yields tokenlists for each line. + """ + line = [] + for token, c in explode_tokens(tokenlist): + line.append((token, c)) + + if c == '\n': + yield line + line = [] + + yield line + + +def split_lines(tokenlist): + """ + Take a single list of (Token, text) tuples and yield one such list for each + line. Just like str.split, this will yield at least one item. + + :param tokenlist: List of (token, text) or (token, text, mouse_handler) + tuples. + """ + line = [] + + for item in tokenlist: + # For (token, text) tuples. + if len(item) == 2: + token, string = item + parts = string.split('\n') + + for part in parts[:-1]: + if part: + line.append((token, part)) + yield line + line = [] + + line.append((token, parts[-1])) + # Note that parts[-1] can be empty, and that's fine. It happens + # in the case of [(Token.SetCursorPosition, '')]. + + # For (token, text, mouse_handler) tuples. + # I know, partly copy/paste, but understandable and more efficient + # than many tests. + else: + token, string, mouse_handler = item + parts = string.split('\n') + + for part in parts[:-1]: + if part: + line.append((token, part, mouse_handler)) + yield line + line = [] + + line.append((token, parts[-1], mouse_handler)) + + # Always yield the last line, even when this is an empty line. This ensures + # that when `tokenlist` ends with a newline character, an additional empty + # line is yielded. (Otherwise, there's no way to differentiate between the + # cases where `tokenlist` does and doesn't end with a newline.) + yield line + + +class _ExplodedList(list): + """ + Wrapper around a list, that marks it as 'exploded'. + + As soon as items are added or the list is extended, the new items are + automatically exploded as well. + """ + def __init__(self, *a, **kw): + super(_ExplodedList, self).__init__(*a, **kw) + self.exploded = True + + def append(self, item): + self.extend([item]) + + def extend(self, lst): + super(_ExplodedList, self).extend(explode_tokens(lst)) + + def insert(self, index, item): + raise NotImplementedError # TODO + + # TODO: When creating a copy() or [:], return also an _ExplodedList. + + def __setitem__(self, index, value): + """ + Ensure that when `(Token, 'long string')` is set, the string will be + exploded. + """ + if not isinstance(index, slice): + index = slice(index, index + 1) + value = explode_tokens([value]) + super(_ExplodedList, self).__setitem__(index, value) + + +def explode_tokens(tokenlist): + """ + Turn a list of (token, text) tuples into another list where each string is + exactly one character. + + It should be fine to call this function several times. Calling this on a + list that is already exploded, is a null operation. + + :param tokenlist: List of (token, text) tuples. + """ + # When the tokenlist is already exploded, don't explode again. + if getattr(tokenlist, 'exploded', False): + return tokenlist + + result = [] + + for token, string in tokenlist: + for c in string: + result.append((token, c)) + + return _ExplodedList(result) + + +def find_window_for_buffer_name(cli, buffer_name): + """ + Look for a :class:`~prompt_toolkit.layout.containers.Window` in the Layout + that contains the :class:`~prompt_toolkit.layout.controls.BufferControl` + for the given buffer and return it. If no such Window is found, return None. + """ + from prompt_toolkit.interface import CommandLineInterface + assert isinstance(cli, CommandLineInterface) + + from .containers import Window + from .controls import BufferControl + + for l in cli.layout.walk(cli): + if isinstance(l, Window) and isinstance(l.content, BufferControl): + if l.content.buffer_name == buffer_name: + return l |