You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ORPA-pyOpenRPA/WPy32-3720/python-3.7.2/Lib/site-packages/ptpython/utils.py

128 lines
3.8 KiB

6 years ago
"""
For internal use only.
"""
from __future__ import unicode_literals
from prompt_toolkit.mouse_events import MouseEventType
import re
__all__ = (
'has_unclosed_brackets',
'get_jedi_script_from_document',
'document_is_multiline_python',
)
def has_unclosed_brackets(text):
"""
Starting at the end of the string. If we find an opening bracket
for which we didn't had a closing one yet, return True.
"""
stack = []
# Ignore braces inside strings
text = re.sub(r'''('[^']*'|"[^"]*")''', '', text) # XXX: handle escaped quotes.!
for c in reversed(text):
if c in '])}':
stack.append(c)
elif c in '[({':
if stack:
if ((c == '[' and stack[-1] == ']') or
(c == '{' and stack[-1] == '}') or
(c == '(' and stack[-1] == ')')):
stack.pop()
else:
# Opening bracket for which we didn't had a closing one.
return True
return False
def get_jedi_script_from_document(document, locals, globals):
import jedi # We keep this import in-line, to improve start-up time.
# Importing Jedi is 'slow'.
try:
return jedi.Interpreter(
document.text,
column=document.cursor_position_col,
line=document.cursor_position_row + 1,
path='input-text',
namespaces=[locals, globals])
except ValueError:
# Invalid cursor position.
# ValueError('`column` parameter is not in a valid range.')
return None
except AttributeError:
# Workaround for #65: https://github.com/jonathanslenders/python-prompt-toolkit/issues/65
# See also: https://github.com/davidhalter/jedi/issues/508
return None
except IndexError:
# Workaround Jedi issue #514: for https://github.com/davidhalter/jedi/issues/514
return None
except KeyError:
# Workaroud for a crash when the input is "u'", the start of a unicode string.
return None
except Exception:
# Workaround for: https://github.com/jonathanslenders/ptpython/issues/91
return None
_multiline_string_delims = re.compile('''[']{3}|["]{3}''')
def document_is_multiline_python(document):
"""
Determine whether this is a multiline Python document.
"""
def ends_in_multiline_string():
"""
``True`` if we're inside a multiline string at the end of the text.
"""
delims = _multiline_string_delims.findall(document.text)
opening = None
for delim in delims:
if opening is None:
opening = delim
elif delim == opening:
opening = None
return bool(opening)
if '\n' in document.text or ends_in_multiline_string():
return True
def line_ends_with_colon():
return document.current_line.rstrip()[-1:] == ':'
# If we just typed a colon, or still have open brackets, always insert a real newline.
if line_ends_with_colon() or \
(document.is_cursor_at_the_end and
has_unclosed_brackets(document.text_before_cursor)) or \
document.text.startswith('@'):
return True
# If the character before the cursor is a backslash (line continuation
# char), insert a new line.
elif document.text_before_cursor[-1:] == '\\':
return True
return False
def if_mousedown(handler):
"""
Decorator for mouse handlers.
Only handle event when the user pressed mouse down.
(When applied to a token list. Scroll events will bubble up and are handled
by the Window.)
"""
def handle_if_mouse_down(mouse_event):
if mouse_event.event_type == MouseEventType.MOUSE_DOWN:
return handler(mouse_event)
else:
return NotImplemented
return handle_if_mouse_down