ptutils.py
62 lines
| 2.4 KiB
| text/x-python
|
PythonLexer
Thomas Kluyver
|
r22388 | import unicodedata | ||
from wcwidth import wcwidth | ||||
from IPython.utils.py3compat import PY3 | ||||
from prompt_toolkit.completion import Completer, Completion | ||||
from prompt_toolkit.layout.lexers import Lexer | ||||
from prompt_toolkit.layout.lexers import PygmentsLexer | ||||
from pygments.lexers import Python3Lexer, BashLexer, PythonLexer | ||||
class IPythonPTCompleter(Completer): | ||||
"""Adaptor to provide IPython completions to prompt_toolkit""" | ||||
def __init__(self, ipy_completer): | ||||
self.ipy_completer = ipy_completer | ||||
def get_completions(self, document, complete_event): | ||||
if not document.current_line.strip(): | ||||
return | ||||
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: | ||||
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): | ||||
self.python_lexer = PygmentsLexer(Python3Lexer if PY3 else PythonLexer) | ||||
self.shell_lexer = PygmentsLexer(BashLexer) | ||||
def lex_document(self, cli, document): | ||||
if document.text.startswith('!'): | ||||
return self.shell_lexer.lex_document(cli, document) | ||||
else: | ||||
return self.python_lexer.lex_document(cli, document) | ||||