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/ipython/py2/IPython/terminal/ptutils.py | |
parent | 38f2c5852db84c7b4d83adfcb009eb61541d1ccd (diff) | |
download | ydb-e0e3e1717e3d33762ce61950504f9637a6e669ed.tar.gz |
add ydb deps
Diffstat (limited to 'contrib/python/ipython/py2/IPython/terminal/ptutils.py')
-rw-r--r-- | contrib/python/ipython/py2/IPython/terminal/ptutils.py | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/contrib/python/ipython/py2/IPython/terminal/ptutils.py b/contrib/python/ipython/py2/IPython/terminal/ptutils.py new file mode 100644 index 0000000000..c9ff705642 --- /dev/null +++ b/contrib/python/ipython/py2/IPython/terminal/ptutils.py @@ -0,0 +1,115 @@ +"""prompt-toolkit utilities + +Everything in this module is a private API, +not to be used outside IPython. +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import unicodedata +from wcwidth import wcwidth + +from IPython.utils.py3compat import PY3 + +from IPython.core.completer import IPCompleter +from prompt_toolkit.completion import Completer, Completion +from prompt_toolkit.layout.lexers import Lexer +from prompt_toolkit.layout.lexers import PygmentsLexer + +import pygments.lexers as pygments_lexers + + +class IPythonPTCompleter(Completer): + """Adaptor to provide IPython completions to prompt_toolkit""" + def __init__(self, ipy_completer=None, shell=None, patch_stdout=None): + if shell is None and ipy_completer is None: + raise TypeError("Please pass shell=an InteractiveShell instance.") + self._ipy_completer = ipy_completer + self.shell = shell + if patch_stdout is None: + raise TypeError("Please pass patch_stdout") + self.patch_stdout = patch_stdout + + @property + def ipy_completer(self): + if self._ipy_completer: + return self._ipy_completer + else: + return self.shell.Completer + + def get_completions(self, document, complete_event): + if not document.current_line.strip(): + return + + # Some bits of our completion system may print stuff (e.g. if a module + # is imported). This context manager ensures that doesn't interfere with + # the prompt. + with self.patch_stdout(): + used, matches = self.ipy_completer.complete( + line_buffer=document.current_line, + cursor_pos=document.cursor_position_col + ) + start_pos = -len(used) + for m in matches: + if not m: + # Guard against completion machinery giving us an empty string. + continue + + m = unicodedata.normalize('NFC', m) + + # When the first character of the completion has a zero length, + # then it's probably a decomposed unicode character. E.g. caused by + # the "\dot" completion. Try to compose again with the previous + # character. + if wcwidth(m[0]) == 0: + if document.cursor_position + start_pos > 0: + char_before = document.text[document.cursor_position + start_pos - 1] + m = unicodedata.normalize('NFC', char_before + m) + + # Yield the modified completion instead, if this worked. + if wcwidth(m[0:1]) == 1: + yield Completion(m, start_position=start_pos - 1) + continue + + # TODO: Use Jedi to determine meta_text + # (Jedi currently has a bug that results in incorrect information.) + # meta_text = '' + # yield Completion(m, start_position=start_pos, + # display_meta=meta_text) + yield Completion(m, start_position=start_pos) + +class IPythonPTLexer(Lexer): + """ + Wrapper around PythonLexer and BashLexer. + """ + def __init__(self): + l = pygments_lexers + self.python_lexer = PygmentsLexer(l.Python3Lexer if PY3 else l.PythonLexer) + self.shell_lexer = PygmentsLexer(l.BashLexer) + + self.magic_lexers = { + 'HTML': PygmentsLexer(l.HtmlLexer), + 'html': PygmentsLexer(l.HtmlLexer), + 'javascript': PygmentsLexer(l.JavascriptLexer), + 'js': PygmentsLexer(l.JavascriptLexer), + 'perl': PygmentsLexer(l.PerlLexer), + 'ruby': PygmentsLexer(l.RubyLexer), + 'latex': PygmentsLexer(l.TexLexer), + } + + def lex_document(self, cli, document): + text = document.text.lstrip() + + lexer = self.python_lexer + + if text.startswith('!') or text.startswith('%%bash'): + lexer = self.shell_lexer + + elif text.startswith('%%'): + for magic, l in self.magic_lexers.items(): + if text.startswith('%%' + magic): + lexer = l + break + + return lexer.lex_document(cli, document) |