forked from prompt-toolkit/ptpython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
127 lines (104 loc) · 3.86 KB
/
utils.py
File metadata and controls
127 lines (104 loc) · 3.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""
For internal use only.
"""
from __future__ import unicode_literals
from prompt_toolkit.mouse_events import MouseEventTypes
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(cli, mouse_event):
if mouse_event.event_type == MouseEventTypes.MOUSE_DOWN:
return handler(cli, mouse_event)
else:
return NotImplemented
return handle_if_mouse_down