mwxlib 0.97.6__py3-none-any.whl → 0.98.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mwxlib might be problematic. Click here for more details.
- mwx/controls.py +0 -1
- mwx/framework.py +13 -9
- mwx/nutshell.py +482 -382
- {mwxlib-0.97.6.dist-info → mwxlib-0.98.0.dist-info}/METADATA +1 -1
- {mwxlib-0.97.6.dist-info → mwxlib-0.98.0.dist-info}/RECORD +8 -8
- {mwxlib-0.97.6.dist-info → mwxlib-0.98.0.dist-info}/WHEEL +1 -1
- {mwxlib-0.97.6.dist-info → mwxlib-0.98.0.dist-info}/LICENSE +0 -0
- {mwxlib-0.97.6.dist-info → mwxlib-0.98.0.dist-info}/top_level.txt +0 -0
mwx/controls.py
CHANGED
mwx/framework.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#! python3
|
|
2
2
|
"""mwxlib framework.
|
|
3
3
|
"""
|
|
4
|
-
__version__ = "0.
|
|
4
|
+
__version__ = "0.98.0"
|
|
5
5
|
__author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
|
|
6
6
|
|
|
7
7
|
from contextlib import contextmanager
|
|
@@ -78,11 +78,12 @@ def postcall(f):
|
|
|
78
78
|
|
|
79
79
|
@contextmanager
|
|
80
80
|
def save_focus_excursion():
|
|
81
|
+
"""Save window focus excursion."""
|
|
81
82
|
wnd = wx.Window.FindFocus() # original focus
|
|
82
83
|
try:
|
|
83
84
|
yield wnd
|
|
84
85
|
finally:
|
|
85
|
-
if wnd:
|
|
86
|
+
if wnd and wnd.IsShownOnScreen():
|
|
86
87
|
wnd.SetFocus() # restore focus
|
|
87
88
|
|
|
88
89
|
|
|
@@ -506,15 +507,19 @@ def pack(self, items, orient=wx.HORIZONTAL, style=None, label=None):
|
|
|
506
507
|
ALIGN_CENTER_VERTICAL, ALIGN_CENTER_HORIZONTAL
|
|
507
508
|
"""
|
|
508
509
|
if style is None:
|
|
509
|
-
style = (0, wx.EXPAND | wx.ALL, 0)
|
|
510
|
-
if label is
|
|
510
|
+
style = (0, wx.EXPAND | wx.ALL, 0) # DEFALT_STYLE (prop, flag, border)
|
|
511
|
+
if label is None:
|
|
512
|
+
sizer = wx.BoxSizer(orient)
|
|
513
|
+
else:
|
|
511
514
|
box = wx.StaticBox(self, -1, label)
|
|
512
515
|
sizer = wx.StaticBoxSizer(box, orient)
|
|
513
|
-
else:
|
|
514
|
-
sizer = wx.BoxSizer(orient)
|
|
515
516
|
for item in items:
|
|
517
|
+
if not isinstance(item, (wx.Object, list, tuple, type(None))):
|
|
518
|
+
warn(f"pack items must be a wx.Object, tuple or None, not {type(item)}")
|
|
516
519
|
if item is None:
|
|
517
|
-
item = (
|
|
520
|
+
item = (0, 0), 0, 0, 0 # null space
|
|
521
|
+
elif not item:
|
|
522
|
+
item = (0, 0) # padding space
|
|
518
523
|
try:
|
|
519
524
|
try:
|
|
520
525
|
sizer.Add(item, *style)
|
|
@@ -522,8 +527,7 @@ def pack(self, items, orient=wx.HORIZONTAL, style=None, label=None):
|
|
|
522
527
|
sizer.Add(*item) # using item-specific style
|
|
523
528
|
except TypeError as e:
|
|
524
529
|
traceback.print_exc()
|
|
525
|
-
bmp = wx.StaticBitmap(self,
|
|
526
|
-
bitmap=wx.ArtProvider.GetBitmap(wx.ART_ERROR))
|
|
530
|
+
bmp = wx.StaticBitmap(self, bitmap=wx.ArtProvider.GetBitmap(wx.ART_ERROR))
|
|
527
531
|
bmp.SetToolTip(str(e))
|
|
528
532
|
sizer.Add(bmp, 0, wx.EXPAND | wx.ALL, 0)
|
|
529
533
|
wx.Bell()
|
mwx/nutshell.py
CHANGED
|
@@ -71,11 +71,289 @@ def ask(f, prompt="Enter value", type=str):
|
|
|
71
71
|
return _f
|
|
72
72
|
|
|
73
73
|
|
|
74
|
+
class AutoCompInterfaceMixin:
|
|
75
|
+
"""Auto completion interface.
|
|
76
|
+
|
|
77
|
+
Note:
|
|
78
|
+
This class is mixed-in ``wx.py.editwindow.EditWindow``.
|
|
79
|
+
"""
|
|
80
|
+
modules = set() # to be used in module-comp mode
|
|
81
|
+
|
|
82
|
+
fragmwords = set(keyword.kwlist + dir(builtins)) # to be used in text-comp mode
|
|
83
|
+
|
|
84
|
+
def __init__(self):
|
|
85
|
+
## cf. sys.modules
|
|
86
|
+
if not self.modules:
|
|
87
|
+
force = wx.GetKeyState(wx.WXK_CONTROL)\
|
|
88
|
+
& wx.GetKeyState(wx.WXK_SHIFT)
|
|
89
|
+
AutoCompInterfaceMixin.modules = set(find_modules(force))
|
|
90
|
+
|
|
91
|
+
def CallTipShow(self, pos, tip, N=11):
|
|
92
|
+
"""Show a call tip containing a definition near position pos.
|
|
93
|
+
|
|
94
|
+
(override) Snip the tip of max N lines if it is too long.
|
|
95
|
+
Keep the tip for calltip-click event.
|
|
96
|
+
"""
|
|
97
|
+
self._calltip_pos = pos
|
|
98
|
+
self._calltip = tip
|
|
99
|
+
lines = tip.splitlines()
|
|
100
|
+
if len(lines) > N > 0:
|
|
101
|
+
lines[N+1:] = ["\n...(snip) This tips are too long... "
|
|
102
|
+
"Click to show more details."]
|
|
103
|
+
tip = '\n'.join(lines)
|
|
104
|
+
super().CallTipShow(pos, tip)
|
|
105
|
+
|
|
106
|
+
def autoCallTipShow(self, command, insertcalltip=True):
|
|
107
|
+
"""Display argument spec and docstring in a popup window."""
|
|
108
|
+
if self.CallTipActive():
|
|
109
|
+
self.CallTipCancel()
|
|
110
|
+
|
|
111
|
+
name, argspec, tip = introspect.getCallTip(command, locals=self.locals)
|
|
112
|
+
if tip:
|
|
113
|
+
dispatcher.send(signal='Shell.calltip', sender=self, calltip=tip)
|
|
114
|
+
p = self.cpos
|
|
115
|
+
if argspec and insertcalltip:
|
|
116
|
+
self.AddText(argspec + ')') # 挿入後のカーソル位置は変化しない
|
|
117
|
+
self.SetSelection(self.cpos, p) # selection back
|
|
118
|
+
if tip:
|
|
119
|
+
## In case there isn't enough room, only go back to bol fallback.
|
|
120
|
+
tippos = max(self.bol, p - len(name) - 1)
|
|
121
|
+
self.CallTipShow(tippos, tip)
|
|
122
|
+
|
|
123
|
+
def call_helpDoc(self, evt):
|
|
124
|
+
"""Show help:str for the selected topic."""
|
|
125
|
+
if self.CallTipActive():
|
|
126
|
+
self.CallTipCancel()
|
|
127
|
+
|
|
128
|
+
text = next(self.gen_text_at_caret(), None)
|
|
129
|
+
if text:
|
|
130
|
+
text = introspect.getRoot(text, terminator='(')
|
|
131
|
+
try:
|
|
132
|
+
obj = self.eval(text)
|
|
133
|
+
self.help(obj)
|
|
134
|
+
except Exception as e:
|
|
135
|
+
self.message("- {} : {!r}".format(e, text))
|
|
136
|
+
|
|
137
|
+
def call_helpTip(self, evt):
|
|
138
|
+
"""Show tooltips for the selected topic."""
|
|
139
|
+
if self.CallTipActive():
|
|
140
|
+
self.CallTipCancel()
|
|
141
|
+
|
|
142
|
+
text = next(self.gen_text_at_caret(), None)
|
|
143
|
+
if text:
|
|
144
|
+
p = self.cpos
|
|
145
|
+
self.autoCallTipShow(text,
|
|
146
|
+
p == self.eol and self.get_char(p-1) == '(') # => CallTipShow
|
|
147
|
+
|
|
148
|
+
def on_completion_forward(self, evt):
|
|
149
|
+
if not self.AutoCompActive():
|
|
150
|
+
self.handler('quit', evt)
|
|
151
|
+
return
|
|
152
|
+
self._on_completion(1)
|
|
153
|
+
|
|
154
|
+
def on_completion_backward(self, evt):
|
|
155
|
+
if not self.AutoCompActive():
|
|
156
|
+
self.handler('quit', evt)
|
|
157
|
+
return
|
|
158
|
+
self._on_completion(-1)
|
|
159
|
+
|
|
160
|
+
def _on_completion(self, step=0):
|
|
161
|
+
"""Show completion with selection."""
|
|
162
|
+
try:
|
|
163
|
+
N = len(self.__comp_words)
|
|
164
|
+
j = self.__comp_ind + step
|
|
165
|
+
j = 0 if j < 0 else j if j < N else N-1
|
|
166
|
+
word = self.__comp_words[j]
|
|
167
|
+
n = len(self.__comp_hint)
|
|
168
|
+
p = self.cpos
|
|
169
|
+
if not self.SelectedText:
|
|
170
|
+
p, self.anchor, sty = self.get_following_atom(p) # word-right-selection
|
|
171
|
+
self.ReplaceSelection(word[n:]) # Modify (or insert) the selected range
|
|
172
|
+
self.cpos = p # backward selection to the point
|
|
173
|
+
self.__comp_ind = j
|
|
174
|
+
except IndexError:
|
|
175
|
+
self.message("No completion words")
|
|
176
|
+
|
|
177
|
+
def _gen_autocomp(self, j, hint, words, sep=' ', mode=True):
|
|
178
|
+
## Prepare on_completion_forward/backward
|
|
179
|
+
self.__comp_ind = j
|
|
180
|
+
self.__comp_hint = hint
|
|
181
|
+
self.__comp_words = words
|
|
182
|
+
if not mode:
|
|
183
|
+
self.anchor = self.eolc # selection to eol
|
|
184
|
+
self._on_completion() # show completion always
|
|
185
|
+
elif words:
|
|
186
|
+
self.AutoCompSetSeparator(ord(sep))
|
|
187
|
+
self.AutoCompShow(len(hint), sep.join(words))
|
|
188
|
+
|
|
189
|
+
def _get_words_hint(self):
|
|
190
|
+
cmdl = self.GetTextRange(self.bol, self.cpos)
|
|
191
|
+
text = next(split_words(cmdl, reverse=1), '')
|
|
192
|
+
return text.rpartition('.') # -> text, sep, hint
|
|
193
|
+
|
|
194
|
+
def call_history_comp(self, evt):
|
|
195
|
+
"""Called when history-comp mode."""
|
|
196
|
+
if not self.CanEdit():
|
|
197
|
+
self.handler('quit', evt)
|
|
198
|
+
return
|
|
199
|
+
|
|
200
|
+
cmdl = self.GetTextRange(self.bol, self.cpos)
|
|
201
|
+
if cmdl.isspace() or self.bol != self.bolc:
|
|
202
|
+
self.handler('skip', evt) # [tab pressed] => on_indent_line
|
|
203
|
+
return
|
|
204
|
+
|
|
205
|
+
hint = cmdl.strip()
|
|
206
|
+
ls = [x.replace('\n', os.linesep + sys.ps2)
|
|
207
|
+
for x in self.history if x.startswith(hint)] # case-sensitive match
|
|
208
|
+
words = sorted(set(ls), key=ls.index, reverse=0) # keep order, no duplication
|
|
209
|
+
|
|
210
|
+
## the latest history stacks in the head of the list (time-descending)
|
|
211
|
+
self._gen_autocomp(0, hint, words, mode=False)
|
|
212
|
+
self.message("[history] {} candidates matched"
|
|
213
|
+
" with {!r}".format(len(words), hint))
|
|
214
|
+
|
|
215
|
+
def call_text_autocomp(self, evt):
|
|
216
|
+
"""Called when text-comp mode."""
|
|
217
|
+
if not self.CanEdit():
|
|
218
|
+
self.handler('quit', evt)
|
|
219
|
+
return
|
|
220
|
+
|
|
221
|
+
cmdl = self.GetTextRange(self.bol, self.cpos)
|
|
222
|
+
hint = re.search(r"[\w.]*$", cmdl).group(0) # extract the last word
|
|
223
|
+
|
|
224
|
+
ls = [x for x in self.fragmwords if x.startswith(hint)] # case-sensitive match
|
|
225
|
+
words = sorted(ls, key=lambda s:s.upper())
|
|
226
|
+
|
|
227
|
+
self._gen_autocomp(0, hint, words)
|
|
228
|
+
self.message("[text] {} candidates matched"
|
|
229
|
+
" with {!r}".format(len(words), hint))
|
|
230
|
+
|
|
231
|
+
def call_module_autocomp(self, evt, force=False):
|
|
232
|
+
"""Called when module-comp mode."""
|
|
233
|
+
if not self.CanEdit():
|
|
234
|
+
self.handler('quit', evt)
|
|
235
|
+
return
|
|
236
|
+
|
|
237
|
+
def _continue(hints):
|
|
238
|
+
if not hints.endswith(' '):
|
|
239
|
+
h = hints.strip()
|
|
240
|
+
if not h.endswith(','):
|
|
241
|
+
lh = h.split(',')[-1].strip() # 'x, y, z|' last hint after ','
|
|
242
|
+
if ' ' not in lh: # 'x, y as|' contains no spaces.
|
|
243
|
+
return lh
|
|
244
|
+
|
|
245
|
+
cmdl = self.GetTextRange(self.bol, self.cpos)
|
|
246
|
+
hint = re.search(r"[\w.]*$", cmdl).group(0) # extract the last word
|
|
247
|
+
try:
|
|
248
|
+
if (m := re.match(r"from\s+([\w.]+)\s+import\s+(.*)", cmdl)):
|
|
249
|
+
text, hints = m.groups()
|
|
250
|
+
if not _continue(hints) and not force:
|
|
251
|
+
self.message("[module]>>> waiting for key input...")
|
|
252
|
+
return
|
|
253
|
+
elif '.' in hints:
|
|
254
|
+
self.message("[module] invalid syntax.")
|
|
255
|
+
return
|
|
256
|
+
try:
|
|
257
|
+
self.message("[module]>>> loading {}...".format(text))
|
|
258
|
+
modules = set(dir(import_module(text)))
|
|
259
|
+
except ImportError as e:
|
|
260
|
+
self.message("\b failed:", e)
|
|
261
|
+
return
|
|
262
|
+
else:
|
|
263
|
+
## Add unimported module names.
|
|
264
|
+
p = "{}.{}".format(text, hint)
|
|
265
|
+
keys = [x[len(text)+1:] for x in self.modules if x.startswith(p)]
|
|
266
|
+
modules.update(k for k in keys if '.' not in k)
|
|
267
|
+
|
|
268
|
+
elif (m := re.match(r"(import|from)\s+(.*)", cmdl)):
|
|
269
|
+
text, hints = m.groups()
|
|
270
|
+
if not _continue(hints) and not force:
|
|
271
|
+
self.message("[module]>>> waiting for key input...")
|
|
272
|
+
return
|
|
273
|
+
modules = self.modules
|
|
274
|
+
else:
|
|
275
|
+
text, sep, hint = self._get_words_hint()
|
|
276
|
+
obj = self.eval(text)
|
|
277
|
+
modules = set(k for k, v in vars(obj).items() if inspect.ismodule(v))
|
|
278
|
+
|
|
279
|
+
P = re.compile(hint)
|
|
280
|
+
p = re.compile(hint, re.I)
|
|
281
|
+
words = sorted([x for x in modules if p.match(x)], key=lambda s:s.upper())
|
|
282
|
+
|
|
283
|
+
j = next((k for k, w in enumerate(words) if P.match(w)),
|
|
284
|
+
next((k for k, w in enumerate(words) if p.match(w)), -1))
|
|
285
|
+
|
|
286
|
+
self._gen_autocomp(j, hint, words)
|
|
287
|
+
self.message("[module] {} candidates matched"
|
|
288
|
+
" with {!r} in {}".format(len(words), hint, text))
|
|
289
|
+
except re.error as e:
|
|
290
|
+
self.message("- re:miss compilation {!r} : {!r}".format(e, hint))
|
|
291
|
+
except SyntaxError as e:
|
|
292
|
+
self.handler('quit', evt)
|
|
293
|
+
self.message("- {} : {!r}".format(e, text))
|
|
294
|
+
except Exception as e:
|
|
295
|
+
self.message("- {} : {!r}".format(e, text))
|
|
296
|
+
|
|
297
|
+
def call_word_autocomp(self, evt):
|
|
298
|
+
"""Called when word-comp mode."""
|
|
299
|
+
if not self.CanEdit():
|
|
300
|
+
self.handler('quit', evt)
|
|
301
|
+
return
|
|
302
|
+
try:
|
|
303
|
+
text, sep, hint = self._get_words_hint()
|
|
304
|
+
obj = self.eval(text)
|
|
305
|
+
|
|
306
|
+
P = re.compile(hint)
|
|
307
|
+
p = re.compile(hint, re.I)
|
|
308
|
+
words = sorted([x for x in dir(obj) if p.match(x)], key=lambda s:s.upper())
|
|
309
|
+
|
|
310
|
+
j = next((k for k, w in enumerate(words) if P.match(w)),
|
|
311
|
+
next((k for k, w in enumerate(words) if p.match(w)), -1))
|
|
312
|
+
|
|
313
|
+
self._gen_autocomp(j, hint, words)
|
|
314
|
+
self.message("[word] {} candidates matched"
|
|
315
|
+
" with {!r} in {}".format(len(words), hint, text))
|
|
316
|
+
except re.error as e:
|
|
317
|
+
self.message("- re:miss compilation {!r} : {!r}".format(e, hint))
|
|
318
|
+
except SyntaxError as e:
|
|
319
|
+
self.handler('quit', evt)
|
|
320
|
+
self.message("- {} : {!r}".format(e, text))
|
|
321
|
+
except Exception as e:
|
|
322
|
+
self.message("- {} : {!r}".format(e, text))
|
|
323
|
+
|
|
324
|
+
def call_apropos_autocomp(self, evt):
|
|
325
|
+
"""Called when apropos mode."""
|
|
326
|
+
if not self.CanEdit():
|
|
327
|
+
self.handler('quit', evt)
|
|
328
|
+
return
|
|
329
|
+
try:
|
|
330
|
+
text, sep, hint = self._get_words_hint()
|
|
331
|
+
obj = self.eval(text)
|
|
332
|
+
|
|
333
|
+
P = re.compile(hint)
|
|
334
|
+
p = re.compile(hint, re.I)
|
|
335
|
+
words = sorted([x for x in dir(obj) if p.search(x)], key=lambda s:s.upper())
|
|
336
|
+
|
|
337
|
+
j = next((k for k, w in enumerate(words) if P.match(w)),
|
|
338
|
+
next((k for k, w in enumerate(words) if p.match(w)), -1))
|
|
339
|
+
|
|
340
|
+
self._gen_autocomp(j, hint, words)
|
|
341
|
+
self.message("[apropos] {} candidates matched"
|
|
342
|
+
" with {!r} in {}".format(len(words), hint, text))
|
|
343
|
+
except re.error as e:
|
|
344
|
+
self.message("- re:miss compilation {!r} : {!r}".format(e, hint))
|
|
345
|
+
except SyntaxError as e:
|
|
346
|
+
self.handler('quit', evt)
|
|
347
|
+
self.message("- {} : {!r}".format(e, text))
|
|
348
|
+
except Exception as e:
|
|
349
|
+
self.message("- {} : {!r}".format(e, text))
|
|
350
|
+
|
|
351
|
+
|
|
74
352
|
class EditorInterface(CtrlInterface):
|
|
75
353
|
"""Interface of Python code editor.
|
|
76
354
|
|
|
77
355
|
Note:
|
|
78
|
-
This class
|
|
356
|
+
This class is mixed-in ``wx.stc.StyledTextCtrl``.
|
|
79
357
|
"""
|
|
80
358
|
def __init__(self):
|
|
81
359
|
CtrlInterface.__init__(self)
|
|
@@ -538,7 +816,7 @@ class EditorInterface(CtrlInterface):
|
|
|
538
816
|
return (self.cpos - lp + len(text.encode()))
|
|
539
817
|
|
|
540
818
|
@property
|
|
541
|
-
def
|
|
819
|
+
def line_at_caret(self):
|
|
542
820
|
"""Text of the range (bol, eol) at the caret-line."""
|
|
543
821
|
return self.GetTextRange(self.bol, self.eol)
|
|
544
822
|
|
|
@@ -586,6 +864,19 @@ class EditorInterface(CtrlInterface):
|
|
|
586
864
|
q = self.cpos
|
|
587
865
|
return self.GetTextRange(p, q)
|
|
588
866
|
|
|
867
|
+
def gen_text_at_caret(self):
|
|
868
|
+
"""Generates the selected text,
|
|
869
|
+
otherwise the line or expression at the caret.
|
|
870
|
+
"""
|
|
871
|
+
def _gen_text():
|
|
872
|
+
text = self.SelectedText
|
|
873
|
+
if text:
|
|
874
|
+
yield text
|
|
875
|
+
else:
|
|
876
|
+
yield self.line_at_caret
|
|
877
|
+
yield self.expr_at_caret
|
|
878
|
+
return filter(None, _gen_text())
|
|
879
|
+
|
|
589
880
|
## --------------------------------
|
|
590
881
|
## Python syntax and indentation
|
|
591
882
|
## --------------------------------
|
|
@@ -604,24 +895,26 @@ class EditorInterface(CtrlInterface):
|
|
|
604
895
|
@can_edit
|
|
605
896
|
def py_indent_line(self):
|
|
606
897
|
"""Indent the current line."""
|
|
607
|
-
text = self.
|
|
608
|
-
lstr = text.lstrip()
|
|
609
|
-
p = self.bol + len(text) - len(lstr)
|
|
898
|
+
text = self.line_at_caret # w/ no-prompt
|
|
899
|
+
lstr = text.lstrip() # w/ no-indent
|
|
900
|
+
p = self.bol + len(text) - len(lstr)
|
|
610
901
|
offset = max(0, self.cpos - p)
|
|
611
902
|
indent = self.py_current_indent() # check current/previous line
|
|
612
|
-
|
|
613
|
-
|
|
903
|
+
if indent >= 0:
|
|
904
|
+
self.Replace(self.bol, p, ' '*indent)
|
|
905
|
+
self.goto_char(self.bol + indent + offset)
|
|
614
906
|
|
|
615
907
|
@can_edit
|
|
616
908
|
def py_outdent_line(self):
|
|
617
909
|
"""Outdent the current line."""
|
|
618
|
-
text = self.
|
|
619
|
-
lstr = text.lstrip()
|
|
620
|
-
p = self.bol + len(text) - len(lstr)
|
|
910
|
+
text = self.line_at_caret # w/ no-prompt
|
|
911
|
+
lstr = text.lstrip() # w/ no-indent
|
|
912
|
+
p = self.bol + len(text) - len(lstr)
|
|
621
913
|
offset = max(0, self.cpos - p)
|
|
622
914
|
indent = len(text) - len(lstr) - 4
|
|
623
|
-
|
|
624
|
-
|
|
915
|
+
if indent >= 0:
|
|
916
|
+
self.Replace(self.bol, p, ' '*indent)
|
|
917
|
+
self.goto_char(self.bol + indent + offset)
|
|
625
918
|
|
|
626
919
|
def py_current_indent(self):
|
|
627
920
|
"""Calculate indent spaces from previous line."""
|
|
@@ -1146,9 +1439,9 @@ class EditorInterface(CtrlInterface):
|
|
|
1146
1439
|
self.goto_char(p)
|
|
1147
1440
|
|
|
1148
1441
|
def back_to_indentation(self):
|
|
1149
|
-
text = self.
|
|
1150
|
-
lstr = text.lstrip()
|
|
1151
|
-
p = self.bol + len(text) - len(lstr)
|
|
1442
|
+
text = self.line_at_caret # w/ no-prompt
|
|
1443
|
+
lstr = text.lstrip() # w/ no-indent
|
|
1444
|
+
p = self.bol + len(text) - len(lstr)
|
|
1152
1445
|
self.goto_char(p, interactive=True)
|
|
1153
1446
|
self.ScrollToColumn(0)
|
|
1154
1447
|
|
|
@@ -1191,13 +1484,11 @@ class EditorInterface(CtrlInterface):
|
|
|
1191
1484
|
"""Save buffer excursion."""
|
|
1192
1485
|
try:
|
|
1193
1486
|
p = self.cpos
|
|
1194
|
-
q = self.anchor
|
|
1195
1487
|
vpos = self.GetScrollPos(wx.VERTICAL)
|
|
1196
1488
|
hpos = self.GetScrollPos(wx.HORIZONTAL)
|
|
1197
1489
|
yield
|
|
1198
1490
|
finally:
|
|
1199
1491
|
self.GotoPos(p)
|
|
1200
|
-
self.SetAnchor(q)
|
|
1201
1492
|
self.ScrollToLine(vpos)
|
|
1202
1493
|
self.SetXOffset(hpos)
|
|
1203
1494
|
|
|
@@ -1336,13 +1627,13 @@ class EditorInterface(CtrlInterface):
|
|
|
1336
1627
|
_text, lp = self.CurLine
|
|
1337
1628
|
for i in range(lp % 4 or 4):
|
|
1338
1629
|
p = self.cpos
|
|
1339
|
-
if self.get_char(p-1) != ' '
|
|
1630
|
+
if p == self.bol or self.get_char(p-1) != ' ':
|
|
1340
1631
|
break
|
|
1341
1632
|
self.cpos = p-1
|
|
1342
1633
|
self.ReplaceSelection('')
|
|
1343
1634
|
|
|
1344
1635
|
|
|
1345
|
-
class Buffer(
|
|
1636
|
+
class Buffer(AutoCompInterfaceMixin, EditorInterface, EditWindow):
|
|
1346
1637
|
"""Python code buffer.
|
|
1347
1638
|
|
|
1348
1639
|
Attributes:
|
|
@@ -1468,6 +1759,7 @@ class Buffer(EditWindow, EditorInterface):
|
|
|
1468
1759
|
def __init__(self, parent, filename=None, **kwargs):
|
|
1469
1760
|
EditWindow.__init__(self, parent, **kwargs)
|
|
1470
1761
|
EditorInterface.__init__(self)
|
|
1762
|
+
AutoCompInterfaceMixin.__init__(self)
|
|
1471
1763
|
|
|
1472
1764
|
self.parent = parent
|
|
1473
1765
|
self.__filename = filename
|
|
@@ -1475,7 +1767,7 @@ class Buffer(EditWindow, EditorInterface):
|
|
|
1475
1767
|
self.code = None
|
|
1476
1768
|
|
|
1477
1769
|
self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdate) # skip to brace matching
|
|
1478
|
-
|
|
1770
|
+
self.Bind(stc.EVT_STC_CALLTIP_CLICK, self.OnCallTipClick)
|
|
1479
1771
|
self.Bind(stc.EVT_STC_INDICATOR_CLICK, self.OnIndicatorClick)
|
|
1480
1772
|
|
|
1481
1773
|
self.Bind(stc.EVT_STC_SAVEPOINTLEFT, self.OnSavePointLeft)
|
|
@@ -1493,6 +1785,26 @@ class Buffer(EditWindow, EditorInterface):
|
|
|
1493
1785
|
evt.Skip()
|
|
1494
1786
|
self.Bind(wx.EVT_KILL_FOCUS, inactivate)
|
|
1495
1787
|
|
|
1788
|
+
def clear(evt):
|
|
1789
|
+
## """Clear selection and message, no skip."""
|
|
1790
|
+
## *do not* clear autocomp, so that the event can skip to AutoComp properly.
|
|
1791
|
+
## if self.AutoCompActive():
|
|
1792
|
+
## self.AutoCompCancel() # may delete selection
|
|
1793
|
+
if self.CanEdit():
|
|
1794
|
+
self.ReplaceSelection("")
|
|
1795
|
+
self.message("")
|
|
1796
|
+
|
|
1797
|
+
def clear_autocomp(evt):
|
|
1798
|
+
## """Clear Autocomp, selection, and message."""
|
|
1799
|
+
if self.AutoCompActive():
|
|
1800
|
+
self.AutoCompCancel()
|
|
1801
|
+
if self.CanEdit():
|
|
1802
|
+
self.ReplaceSelection("")
|
|
1803
|
+
self.message("")
|
|
1804
|
+
|
|
1805
|
+
def fork(evt):
|
|
1806
|
+
self.handler.fork(self.handler.current_event, evt)
|
|
1807
|
+
|
|
1496
1808
|
def dispatch(evt):
|
|
1497
1809
|
"""Fork events to the parent."""
|
|
1498
1810
|
self.parent.handler(self.handler.current_event, evt)
|
|
@@ -1520,6 +1832,93 @@ class Buffer(EditWindow, EditorInterface):
|
|
|
1520
1832
|
'* pressed' : (0, skip, dispatch),
|
|
1521
1833
|
'* released' : (0, skip, dispatch),
|
|
1522
1834
|
'escape pressed' : (-1, self.on_enter_escmap),
|
|
1835
|
+
'C-h pressed' : (0, self.call_helpTip),
|
|
1836
|
+
'. pressed' : (2, skip),
|
|
1837
|
+
'M-. pressed' : (2, self.call_word_autocomp),
|
|
1838
|
+
'M-/ pressed' : (3, self.call_apropos_autocomp),
|
|
1839
|
+
'M-m pressed' : (5, self.call_module_autocomp),
|
|
1840
|
+
},
|
|
1841
|
+
2 : { # word auto completion AS-mode
|
|
1842
|
+
'quit' : (0, clear_autocomp),
|
|
1843
|
+
'* pressed' : (0, clear_autocomp, fork),
|
|
1844
|
+
'tab pressed' : (0, clear, skip),
|
|
1845
|
+
'enter pressed' : (0, clear, skip),
|
|
1846
|
+
'escape pressed' : (0, clear_autocomp),
|
|
1847
|
+
'up pressed' : (2, skip, self.on_completion_backward),
|
|
1848
|
+
'down pressed' : (2, skip, self.on_completion_forward),
|
|
1849
|
+
'*left pressed' : (2, skip),
|
|
1850
|
+
'*left released' : (2, self.call_word_autocomp),
|
|
1851
|
+
'*right pressed' : (2, skip),
|
|
1852
|
+
'*right released' : (2, self.call_word_autocomp),
|
|
1853
|
+
'[a-z0-9_.] pressed' : (2, skip),
|
|
1854
|
+
'[a-z0-9_.] released' : (2, self.call_word_autocomp),
|
|
1855
|
+
'S-[a-z\\] pressed' : (2, skip),
|
|
1856
|
+
'S-[a-z\\] released' : (2, self.call_word_autocomp),
|
|
1857
|
+
'\\ released' : (2, self.call_word_autocomp),
|
|
1858
|
+
'*delete pressed' : (2, skip),
|
|
1859
|
+
'*backspace pressed' : (2, skip),
|
|
1860
|
+
'*backspace released' : (2, self.call_word_autocomp),
|
|
1861
|
+
'C-S-backspace pressed' : (2, ),
|
|
1862
|
+
'*alt pressed' : (2, ),
|
|
1863
|
+
'*ctrl pressed' : (2, ),
|
|
1864
|
+
'*shift pressed' : (2, ),
|
|
1865
|
+
'*[LR]win pressed' : (2, ),
|
|
1866
|
+
'*f[0-9]* pressed' : (2, ),
|
|
1867
|
+
},
|
|
1868
|
+
3 : { # apropos auto completion AS-mode
|
|
1869
|
+
'quit' : (0, clear_autocomp),
|
|
1870
|
+
'* pressed' : (0, clear_autocomp, fork),
|
|
1871
|
+
'tab pressed' : (0, clear, skip),
|
|
1872
|
+
'enter pressed' : (0, clear, skip),
|
|
1873
|
+
'escape pressed' : (0, clear_autocomp),
|
|
1874
|
+
'up pressed' : (3, skip, self.on_completion_backward),
|
|
1875
|
+
'down pressed' : (3, skip, self.on_completion_forward),
|
|
1876
|
+
'*left pressed' : (3, skip),
|
|
1877
|
+
'*left released' : (3, self.call_apropos_autocomp),
|
|
1878
|
+
'*right pressed' : (3, skip),
|
|
1879
|
+
'*right released' : (3, self.call_apropos_autocomp),
|
|
1880
|
+
'[a-z0-9_.] pressed' : (3, skip),
|
|
1881
|
+
'[a-z0-9_.] released' : (3, self.call_apropos_autocomp),
|
|
1882
|
+
'S-[a-z\\] pressed' : (3, skip),
|
|
1883
|
+
'S-[a-z\\] released' : (3, self.call_apropos_autocomp),
|
|
1884
|
+
'\\ released' : (3, self.call_apropos_autocomp),
|
|
1885
|
+
'*delete pressed' : (3, skip),
|
|
1886
|
+
'*backspace pressed' : (3, skip),
|
|
1887
|
+
'*backspace released' : (3, self.call_apropos_autocomp),
|
|
1888
|
+
'C-S-backspace pressed' : (3, ),
|
|
1889
|
+
'*alt pressed' : (3, ),
|
|
1890
|
+
'*ctrl pressed' : (3, ),
|
|
1891
|
+
'*shift pressed' : (3, ),
|
|
1892
|
+
'*[LR]win pressed' : (3, ),
|
|
1893
|
+
'*f[0-9]* pressed' : (3, ),
|
|
1894
|
+
},
|
|
1895
|
+
5 : { # module auto completion AS-mode
|
|
1896
|
+
'quit' : (0, clear_autocomp),
|
|
1897
|
+
'* pressed' : (0, clear_autocomp, fork),
|
|
1898
|
+
'tab pressed' : (0, clear, skip),
|
|
1899
|
+
'enter pressed' : (0, clear, skip),
|
|
1900
|
+
'escape pressed' : (0, clear_autocomp),
|
|
1901
|
+
'up pressed' : (5, skip, self.on_completion_backward),
|
|
1902
|
+
'down pressed' : (5, skip, self.on_completion_forward),
|
|
1903
|
+
'*left pressed' : (5, skip),
|
|
1904
|
+
'*left released' : (5, self.call_module_autocomp),
|
|
1905
|
+
'*right pressed' : (5, skip),
|
|
1906
|
+
'*right released' : (5, self.call_module_autocomp),
|
|
1907
|
+
'[a-z0-9_.,] pressed' : (5, skip),
|
|
1908
|
+
'[a-z0-9_.,] released' : (5, self.call_module_autocomp),
|
|
1909
|
+
'S-[a-z\\] pressed' : (5, skip),
|
|
1910
|
+
'S-[a-z\\] released' : (5, self.call_module_autocomp),
|
|
1911
|
+
'\\ released' : (5, self.call_module_autocomp),
|
|
1912
|
+
'M-m pressed' : (5, _F(self.call_module_autocomp, force=1)),
|
|
1913
|
+
'*delete pressed' : (5, skip),
|
|
1914
|
+
'*backspace pressed' : (5, skip),
|
|
1915
|
+
'*backspace released' : (5, self.call_module_autocomp),
|
|
1916
|
+
'C-S-backspace pressed' : (5, ),
|
|
1917
|
+
'*alt pressed' : (5, ),
|
|
1918
|
+
'*ctrl pressed' : (5, ),
|
|
1919
|
+
'*shift pressed' : (5, ),
|
|
1920
|
+
'*[LR]win pressed' : (5, ),
|
|
1921
|
+
'*f[0-9]* pressed' : (5, ),
|
|
1523
1922
|
},
|
|
1524
1923
|
})
|
|
1525
1924
|
|
|
@@ -1542,6 +1941,12 @@ class Buffer(EditWindow, EditorInterface):
|
|
|
1542
1941
|
self.handler('buffer_modified', self)
|
|
1543
1942
|
evt.Skip()
|
|
1544
1943
|
|
|
1944
|
+
def OnCallTipClick(self, evt):
|
|
1945
|
+
if self.CallTipActive():
|
|
1946
|
+
self.CallTipCancel()
|
|
1947
|
+
self.CallTipShow(self._calltip_pos, self._calltip, N=-1)
|
|
1948
|
+
evt.Skip()
|
|
1949
|
+
|
|
1545
1950
|
def OnIndicatorClick(self, evt):
|
|
1546
1951
|
if self.SelectedText or not wx.GetKeyState(wx.WXK_CONTROL):
|
|
1547
1952
|
## Processing text selection, dragging, or dragging+
|
|
@@ -1647,24 +2052,38 @@ class Buffer(EditWindow, EditorInterface):
|
|
|
1647
2052
|
## Python eval / exec
|
|
1648
2053
|
## --------------------------------
|
|
1649
2054
|
|
|
2055
|
+
@property
|
|
2056
|
+
def locals(self): # internal use only
|
|
2057
|
+
try:
|
|
2058
|
+
return self.parent.parent.current_shell.locals
|
|
2059
|
+
except AttributeError:
|
|
2060
|
+
return None
|
|
2061
|
+
|
|
2062
|
+
@property
|
|
2063
|
+
def globals(self): # internal use only
|
|
2064
|
+
try:
|
|
2065
|
+
return self.parent.parent.current_shell.globals
|
|
2066
|
+
except AttributeError:
|
|
2067
|
+
return None
|
|
2068
|
+
|
|
2069
|
+
def eval(self, text):
|
|
2070
|
+
return eval(text, self.globals, self.locals) # using current shell namespace
|
|
2071
|
+
|
|
2072
|
+
def exec(self, text):
|
|
2073
|
+
exec(text, self.globals, self.locals) # using current shell namespace
|
|
2074
|
+
dispatcher.send(signal='Interpreter.push',
|
|
2075
|
+
sender=self, command=None, more=False)
|
|
2076
|
+
|
|
1650
2077
|
def py_eval_line(self, globals=None, locals=None):
|
|
1651
2078
|
if self.CallTipActive():
|
|
1652
2079
|
self.CallTipCancel()
|
|
1653
2080
|
|
|
1654
|
-
def _gen_text():
|
|
1655
|
-
text = self.SelectedText
|
|
1656
|
-
if text:
|
|
1657
|
-
yield text
|
|
1658
|
-
else:
|
|
1659
|
-
yield self.caretline
|
|
1660
|
-
yield self.expr_at_caret
|
|
1661
|
-
|
|
1662
2081
|
status = "No words"
|
|
1663
|
-
for text in
|
|
2082
|
+
for text in self.gen_text_at_caret():
|
|
1664
2083
|
try:
|
|
1665
2084
|
obj = eval(text, globals, locals)
|
|
1666
2085
|
except Exception as e:
|
|
1667
|
-
status = "- {}: {!r}".format(e, text)
|
|
2086
|
+
status = "- {} : {!r}".format(e, text)
|
|
1668
2087
|
else:
|
|
1669
2088
|
self.CallTipShow(self.cpos, pformat(obj))
|
|
1670
2089
|
self.message(text)
|
|
@@ -2182,13 +2601,15 @@ class Interpreter(interpreter.Interpreter):
|
|
|
2182
2601
|
(override) Ignore ValueError: no signature found for builtin
|
|
2183
2602
|
if the unwrapped function is a builtin function.
|
|
2184
2603
|
"""
|
|
2604
|
+
## In 4.2.1, DeprecationWarning was fixed.
|
|
2605
|
+
## In 4.2.2, ValueError was fixed.
|
|
2185
2606
|
try:
|
|
2186
2607
|
return interpreter.Interpreter.getCallTip(self, command, *args, **kwargs)
|
|
2187
2608
|
except ValueError:
|
|
2188
2609
|
return interpreter.Interpreter.getCallTip(self) # dummy
|
|
2189
2610
|
|
|
2190
2611
|
|
|
2191
|
-
class Nautilus(
|
|
2612
|
+
class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
2192
2613
|
"""Nautilus in the Shell.
|
|
2193
2614
|
|
|
2194
2615
|
Facade objects for accessing the APIs:
|
|
@@ -2332,8 +2753,6 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2332
2753
|
def globals(self): # internal use only
|
|
2333
2754
|
self.interp.globals = self.__target.__dict__
|
|
2334
2755
|
|
|
2335
|
-
modules = None
|
|
2336
|
-
|
|
2337
2756
|
## (override)
|
|
2338
2757
|
wrap = EditorInterface.wrap
|
|
2339
2758
|
|
|
@@ -2351,6 +2770,7 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2351
2770
|
execStartupScript=execStartupScript, # if True, executes ~/.py
|
|
2352
2771
|
**kwargs)
|
|
2353
2772
|
EditorInterface.__init__(self)
|
|
2773
|
+
AutoCompInterfaceMixin.__init__(self)
|
|
2354
2774
|
|
|
2355
2775
|
self.parent = parent #: parent<ShellFrame> is not Parent<AuiNotebook>
|
|
2356
2776
|
self.target = target
|
|
@@ -2359,12 +2779,6 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2359
2779
|
wx.py.shell.USE_MAGIC = True
|
|
2360
2780
|
wx.py.shell.magic = self.magic # called when USE_MAGIC
|
|
2361
2781
|
|
|
2362
|
-
## cf. sys.modules
|
|
2363
|
-
if not self.modules:
|
|
2364
|
-
force = wx.GetKeyState(wx.WXK_CONTROL)\
|
|
2365
|
-
& wx.GetKeyState(wx.WXK_SHIFT)
|
|
2366
|
-
Nautilus.modules = set(find_modules(force))
|
|
2367
|
-
|
|
2368
2782
|
self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdate) # skip to brace matching
|
|
2369
2783
|
self.Bind(stc.EVT_STC_CALLTIP_CLICK, self.OnCallTipClick)
|
|
2370
2784
|
self.Bind(stc.EVT_STC_START_DRAG, self.OnDrag)
|
|
@@ -2469,8 +2883,8 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2469
2883
|
'M-j pressed' : (0, self.exec_region),
|
|
2470
2884
|
'C-S-j pressed' : (0, self.exec_region),
|
|
2471
2885
|
'C-h pressed' : (0, self.call_helpTip),
|
|
2472
|
-
'M-h pressed' : (0, self.
|
|
2473
|
-
'C-S-h pressed' : (0, self.
|
|
2886
|
+
'M-h pressed' : (0, self.call_helpDoc),
|
|
2887
|
+
'C-S-h pressed' : (0, self.call_helpDoc),
|
|
2474
2888
|
'. pressed' : (2, self.OnEnterDot),
|
|
2475
2889
|
'tab pressed' : (1, self.call_history_comp),
|
|
2476
2890
|
'M-p pressed' : (1, self.call_history_comp),
|
|
@@ -2482,7 +2896,7 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2482
2896
|
},
|
|
2483
2897
|
1 : { # history auto completion S-mode
|
|
2484
2898
|
'quit' : (0, clear),
|
|
2485
|
-
'
|
|
2899
|
+
'skip' : (0, self.on_indent_line),
|
|
2486
2900
|
'* pressed' : (0, fork),
|
|
2487
2901
|
'enter pressed' : (0, lambda v: self.goto_char(self.eolc)),
|
|
2488
2902
|
'escape pressed' : (0, clear),
|
|
@@ -2490,10 +2904,10 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2490
2904
|
'S-left released' : (1, self.call_history_comp),
|
|
2491
2905
|
'S-right pressed' : (1, skip),
|
|
2492
2906
|
'S-right released' : (1, self.call_history_comp),
|
|
2493
|
-
'tab pressed' : (1, self.
|
|
2494
|
-
'S-tab pressed' : (1, self.
|
|
2495
|
-
'M-p pressed' : (1, self.
|
|
2496
|
-
'M-n pressed' : (1, self.
|
|
2907
|
+
'tab pressed' : (1, _F(self._on_completion, 1)), # 古いヒストリへ進む
|
|
2908
|
+
'S-tab pressed' : (1, _F(self._on_completion, -1)), # 新しいヒストリへ戻る
|
|
2909
|
+
'M-p pressed' : (1, _F(self._on_completion, 1)),
|
|
2910
|
+
'M-n pressed' : (1, _F(self._on_completion, -1)),
|
|
2497
2911
|
'[a-z0-9_] pressed' : (1, skip),
|
|
2498
2912
|
'[a-z0-9_] released' : (1, self.call_history_comp),
|
|
2499
2913
|
'S-[a-z\\] pressed' : (1, skip),
|
|
@@ -2509,7 +2923,7 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2509
2923
|
'quit' : (0, clear_autocomp),
|
|
2510
2924
|
'* pressed' : (0, clear_autocomp, fork),
|
|
2511
2925
|
'tab pressed' : (0, clear, skip),
|
|
2512
|
-
'enter pressed' : (0, clear,
|
|
2926
|
+
'enter pressed' : (0, clear, skip),
|
|
2513
2927
|
'escape pressed' : (0, clear_autocomp),
|
|
2514
2928
|
'up pressed' : (2, skip, self.on_completion_backward),
|
|
2515
2929
|
'down pressed' : (2, skip, self.on_completion_forward),
|
|
@@ -2527,11 +2941,6 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2527
2941
|
'*backspace released' : (2, self.call_word_autocomp),
|
|
2528
2942
|
'C-S-backspace pressed' : (2, ),
|
|
2529
2943
|
'C-j pressed' : (2, self.eval_line),
|
|
2530
|
-
'M-j pressed' : (2, self.exec_region),
|
|
2531
|
-
'C-S-j pressed' : (2, self.exec_region),
|
|
2532
|
-
'C-h pressed' : (2, self.call_helpTip),
|
|
2533
|
-
'M-h pressed' : (2, self.call_helpTip2),
|
|
2534
|
-
'C-S-h pressed' : (2, self.call_helpTip2),
|
|
2535
2944
|
'*alt pressed' : (2, ),
|
|
2536
2945
|
'*ctrl pressed' : (2, ),
|
|
2537
2946
|
'*shift pressed' : (2, ),
|
|
@@ -2542,7 +2951,7 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2542
2951
|
'quit' : (0, clear_autocomp),
|
|
2543
2952
|
'* pressed' : (0, clear_autocomp, fork),
|
|
2544
2953
|
'tab pressed' : (0, clear, skip),
|
|
2545
|
-
'enter pressed' : (0, clear,
|
|
2954
|
+
'enter pressed' : (0, clear, skip),
|
|
2546
2955
|
'escape pressed' : (0, clear_autocomp),
|
|
2547
2956
|
'up pressed' : (3, skip, self.on_completion_backward),
|
|
2548
2957
|
'down pressed' : (3, skip, self.on_completion_forward),
|
|
@@ -2560,11 +2969,6 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2560
2969
|
'*backspace released' : (3, self.call_apropos_autocomp),
|
|
2561
2970
|
'C-S-backspace pressed' : (3, ),
|
|
2562
2971
|
'C-j pressed' : (3, self.eval_line),
|
|
2563
|
-
'M-j pressed' : (3, self.exec_region),
|
|
2564
|
-
'C-S-j pressed' : (3, self.exec_region),
|
|
2565
|
-
'C-h pressed' : (3, self.call_helpTip),
|
|
2566
|
-
'M-h pressed' : (3, self.call_helpTip2),
|
|
2567
|
-
'C-S-h pressed' : (3, self.call_helpTip2),
|
|
2568
2972
|
'*alt pressed' : (3, ),
|
|
2569
2973
|
'*ctrl pressed' : (3, ),
|
|
2570
2974
|
'*shift pressed' : (3, ),
|
|
@@ -2575,7 +2979,7 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2575
2979
|
'quit' : (0, clear_autocomp),
|
|
2576
2980
|
'* pressed' : (0, clear_autocomp, fork),
|
|
2577
2981
|
'tab pressed' : (0, clear, skip),
|
|
2578
|
-
'enter pressed' : (0, clear,
|
|
2982
|
+
'enter pressed' : (0, clear, skip),
|
|
2579
2983
|
'escape pressed' : (0, clear_autocomp),
|
|
2580
2984
|
'up pressed' : (4, skip, self.on_completion_backward),
|
|
2581
2985
|
'down pressed' : (4, skip, self.on_completion_forward),
|
|
@@ -2593,11 +2997,6 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2593
2997
|
'*backspace released' : (4, self.call_text_autocomp),
|
|
2594
2998
|
'C-S-backspace pressed' : (4, ),
|
|
2595
2999
|
'C-j pressed' : (4, self.eval_line),
|
|
2596
|
-
'M-j pressed' : (4, self.exec_region),
|
|
2597
|
-
'C-S-j pressed' : (4, self.exec_region),
|
|
2598
|
-
'C-h pressed' : (4, self.call_helpTip),
|
|
2599
|
-
'M-h pressed' : (4, self.call_helpTip2),
|
|
2600
|
-
'C-S-h pressed' : (4, self.call_helpTip2),
|
|
2601
3000
|
'*alt pressed' : (4, ),
|
|
2602
3001
|
'*ctrl pressed' : (4, ),
|
|
2603
3002
|
'*shift pressed' : (4, ),
|
|
@@ -2608,7 +3007,7 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2608
3007
|
'quit' : (0, clear_autocomp),
|
|
2609
3008
|
'* pressed' : (0, clear_autocomp, fork),
|
|
2610
3009
|
'tab pressed' : (0, clear, skip),
|
|
2611
|
-
'enter pressed' : (0, clear,
|
|
3010
|
+
'enter pressed' : (0, clear, skip),
|
|
2612
3011
|
'escape pressed' : (0, clear_autocomp),
|
|
2613
3012
|
'up pressed' : (5, skip, self.on_completion_backward),
|
|
2614
3013
|
'down pressed' : (5, skip, self.on_completion_forward),
|
|
@@ -2621,7 +3020,7 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2621
3020
|
'S-[a-z\\] pressed' : (5, skip),
|
|
2622
3021
|
'S-[a-z\\] released' : (5, self.call_module_autocomp),
|
|
2623
3022
|
'\\ released' : (5, self.call_module_autocomp),
|
|
2624
|
-
|
|
3023
|
+
'M-m pressed' : (5, _F(self.call_module_autocomp, force=1)),
|
|
2625
3024
|
'*delete pressed' : (5, skip),
|
|
2626
3025
|
'*backspace pressed' : (5, skip_autocomp),
|
|
2627
3026
|
'*backspace released' : (5, self.call_module_autocomp),
|
|
@@ -2669,9 +3068,9 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2669
3068
|
evt.Skip()
|
|
2670
3069
|
|
|
2671
3070
|
def OnCallTipClick(self, evt):
|
|
2672
|
-
self.parent.handler('add_help', self.__calltip)
|
|
2673
3071
|
if self.CallTipActive():
|
|
2674
3072
|
self.CallTipCancel()
|
|
3073
|
+
self.parent.handler('add_help', self._calltip)
|
|
2675
3074
|
evt.Skip()
|
|
2676
3075
|
|
|
2677
3076
|
def OnDrag(self, evt): #<wx._core.StyledTextEvent>
|
|
@@ -2689,7 +3088,7 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2689
3088
|
"""Called when space pressed."""
|
|
2690
3089
|
if not self.CanEdit():
|
|
2691
3090
|
return
|
|
2692
|
-
cmdl = self.
|
|
3091
|
+
cmdl = self.GetTextRange(self.bol, self.cpos)
|
|
2693
3092
|
if re.match(r"import\s*", cmdl)\
|
|
2694
3093
|
or re.match(r"from\s*$", cmdl)\
|
|
2695
3094
|
or re.match(r"from\s+([\w.]+)\s+import\s*", cmdl):
|
|
@@ -2963,22 +3362,18 @@ class Nautilus(Shell, EditorInterface):
|
|
|
2963
3362
|
Note:
|
|
2964
3363
|
Argument `text` is raw output:str with no magic cast.
|
|
2965
3364
|
"""
|
|
2966
|
-
ln = self.
|
|
3365
|
+
ln = self.LineFromPosition(self.bolc)
|
|
2967
3366
|
err = re.findall(py_error_re, text, re.M)
|
|
2968
3367
|
self.add_marker(ln, 1 if not err else 2) # 1:white-arrow 2:red-arrow
|
|
2969
3368
|
return (not err)
|
|
2970
3369
|
|
|
2971
3370
|
def on_interp_error(self, e):
|
|
2972
|
-
|
|
3371
|
+
ln = self.LineFromPosition(self.bolc)
|
|
3372
|
+
self.pointer = ln + e.lineno - 1
|
|
2973
3373
|
|
|
2974
3374
|
## --------------------------------
|
|
2975
3375
|
## Attributes of the shell
|
|
2976
3376
|
## --------------------------------
|
|
2977
|
-
fragmwords = set(keyword.kwlist + dir(builtins)) # to be used in text-comp
|
|
2978
|
-
|
|
2979
|
-
## shell.history is an instance variable of the Shell.
|
|
2980
|
-
## If del shell.history, the history of the class variable is used
|
|
2981
|
-
history = []
|
|
2982
3377
|
|
|
2983
3378
|
@property
|
|
2984
3379
|
def bolc(self):
|
|
@@ -3000,37 +3395,20 @@ class Nautilus(Shell, EditorInterface):
|
|
|
3000
3395
|
break
|
|
3001
3396
|
return self.cpos - lp
|
|
3002
3397
|
|
|
3003
|
-
@property
|
|
3004
|
-
def cmdlc(self):
|
|
3005
|
-
"""Cull command-line (excluding ps1:prompt)."""
|
|
3006
|
-
return self.GetTextRange(self.bol, self.cpos)
|
|
3007
|
-
|
|
3008
3398
|
@property
|
|
3009
3399
|
def cmdline(self):
|
|
3010
|
-
"""Full
|
|
3400
|
+
"""Full multi-line command in the current prompt."""
|
|
3011
3401
|
return self.GetTextRange(self.bolc, self.eolc)
|
|
3012
3402
|
|
|
3013
|
-
@property
|
|
3014
|
-
def cmdline_region(self):
|
|
3015
|
-
lc = self.LineFromPosition(self.bolc)
|
|
3016
|
-
le = self.LineCount
|
|
3017
|
-
return lc, le
|
|
3018
|
-
|
|
3019
3403
|
## cf. getCommand() -> caret-line that starts with a prompt
|
|
3020
3404
|
## cf. getMultilineCommand() -> caret-multi-line that starts with a prompt
|
|
3021
3405
|
## [BUG 4.1.1] Don't use for current prompt --> Fixed in 4.2.0.
|
|
3022
3406
|
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
"""Extract a command from the editor."""
|
|
3026
|
-
return self.getCommand(rstrip=False)
|
|
3027
|
-
|
|
3028
|
-
@property
|
|
3029
|
-
def MultilineCommand(self):
|
|
3030
|
-
"""Extract a multi-line command from the editor.
|
|
3407
|
+
def getMultilineCommand(self):
|
|
3408
|
+
"""Extract a multi-line command which starts with a prompt.
|
|
3031
3409
|
|
|
3032
|
-
|
|
3033
|
-
|
|
3410
|
+
(override) Don't remove trailing ps2 + spaces.
|
|
3411
|
+
Don't invoke ``GotoLine``.
|
|
3034
3412
|
"""
|
|
3035
3413
|
region = self.get_region(self.cline)
|
|
3036
3414
|
if region:
|
|
@@ -3086,13 +3464,13 @@ class Nautilus(Shell, EditorInterface):
|
|
|
3086
3464
|
output = self.GetTextRange(self.__eolc_mark, self.eolc)
|
|
3087
3465
|
|
|
3088
3466
|
input = self.regulate_cmd(input)
|
|
3089
|
-
Shell.addHistory(self, input)
|
|
3467
|
+
Shell.addHistory(self, input) # => self.history
|
|
3090
3468
|
|
|
3091
3469
|
noerr = self.on_text_output(output)
|
|
3092
3470
|
if noerr:
|
|
3093
3471
|
words = re.findall(r"\b[a-zA-Z_][\w.]+", input + output)
|
|
3094
3472
|
self.fragmwords |= set(words)
|
|
3095
|
-
|
|
3473
|
+
command = self.fixLineEndings(command)
|
|
3096
3474
|
self.parent.handler('add_log', command + os.linesep, noerr)
|
|
3097
3475
|
except AttributeError:
|
|
3098
3476
|
## execStartupScript 実行時は出力先 (owner) が存在しない
|
|
@@ -3254,30 +3632,11 @@ class Nautilus(Shell, EditorInterface):
|
|
|
3254
3632
|
def autoCallTipShow(self, command, insertcalltip=True, forceCallTip=False):
|
|
3255
3633
|
"""Display argument spec and docstring in a popup window.
|
|
3256
3634
|
|
|
3257
|
-
(override) Swap anchors to not scroll to the end of the line
|
|
3258
|
-
and display a long hint at the insertion position.
|
|
3635
|
+
(override) Swap anchors to not scroll to the end of the line.
|
|
3259
3636
|
"""
|
|
3260
|
-
vpos = self.GetScrollPos(wx.VERTICAL)
|
|
3261
|
-
hpos = self.GetScrollPos(wx.HORIZONTAL)
|
|
3262
3637
|
Shell.autoCallTipShow(self, command, insertcalltip, forceCallTip)
|
|
3263
3638
|
self.cpos, self.anchor = self.anchor, self.cpos
|
|
3264
|
-
|
|
3265
|
-
self.ScrollToLine(vpos)
|
|
3266
|
-
self.SetXOffset(hpos)
|
|
3267
|
-
|
|
3268
|
-
def CallTipShow(self, pos, tip, N=11):
|
|
3269
|
-
"""Show a call tip containing a definition near position pos.
|
|
3270
|
-
|
|
3271
|
-
(override) Snip the tip of max N lines if it is too long.
|
|
3272
|
-
Keep the tip for calltip-click event.
|
|
3273
|
-
"""
|
|
3274
|
-
self.__calltip = tip
|
|
3275
|
-
lines = tip.splitlines()
|
|
3276
|
-
if len(lines) > N:
|
|
3277
|
-
lines[N+1:] = ["\n...(snip) This tips are too long... "
|
|
3278
|
-
"Click to show more details."
|
|
3279
|
-
]
|
|
3280
|
-
Shell.CallTipShow(self, pos, '\n'.join(lines))
|
|
3639
|
+
self.EnsureCaretVisible()
|
|
3281
3640
|
|
|
3282
3641
|
def eval_line(self, evt):
|
|
3283
3642
|
"""Evaluate the selected word or line.
|
|
@@ -3285,24 +3644,15 @@ class Nautilus(Shell, EditorInterface):
|
|
|
3285
3644
|
if self.CallTipActive():
|
|
3286
3645
|
self.CallTipCancel()
|
|
3287
3646
|
|
|
3288
|
-
def _gen_text():
|
|
3289
|
-
text = self.SelectedText
|
|
3290
|
-
if text:
|
|
3291
|
-
yield text
|
|
3292
|
-
else:
|
|
3293
|
-
yield self.Command
|
|
3294
|
-
yield self.expr_at_caret
|
|
3295
|
-
yield self.MultilineCommand
|
|
3296
|
-
|
|
3297
3647
|
status = "No words"
|
|
3298
|
-
for text in
|
|
3648
|
+
for text in self.gen_text_at_caret():
|
|
3299
3649
|
tokens = split_words(text)
|
|
3300
3650
|
try:
|
|
3301
3651
|
cmd = self.magic_interpret(tokens)
|
|
3302
3652
|
cmd = self.regulate_cmd(cmd)
|
|
3303
3653
|
obj = self.eval(cmd)
|
|
3304
3654
|
except Exception as e:
|
|
3305
|
-
status = "- {}: {!r}".format(e, text)
|
|
3655
|
+
status = "- {} : {!r}".format(e, text)
|
|
3306
3656
|
else:
|
|
3307
3657
|
self.CallTipShow(self.cpos, pformat(obj))
|
|
3308
3658
|
self.message(cmd)
|
|
@@ -3315,7 +3665,7 @@ class Nautilus(Shell, EditorInterface):
|
|
|
3315
3665
|
self.CallTipCancel()
|
|
3316
3666
|
|
|
3317
3667
|
filename = "<input>"
|
|
3318
|
-
text = self.
|
|
3668
|
+
text = self.getMultilineCommand()
|
|
3319
3669
|
if text:
|
|
3320
3670
|
tokens = split_words(text)
|
|
3321
3671
|
try:
|
|
@@ -3337,253 +3687,3 @@ class Nautilus(Shell, EditorInterface):
|
|
|
3337
3687
|
self.message("Evaluated {!r} successfully.".format(filename))
|
|
3338
3688
|
else:
|
|
3339
3689
|
self.message("No region")
|
|
3340
|
-
|
|
3341
|
-
def call_helpTip2(self, evt):
|
|
3342
|
-
"""Show help:str for the selected topic."""
|
|
3343
|
-
if self.CallTipActive():
|
|
3344
|
-
self.CallTipCancel()
|
|
3345
|
-
|
|
3346
|
-
text = self.SelectedText or self.Command or self.expr_at_caret
|
|
3347
|
-
if text:
|
|
3348
|
-
text = introspect.getRoot(text, terminator='(')
|
|
3349
|
-
try:
|
|
3350
|
-
obj = self.eval(text)
|
|
3351
|
-
self.help(obj)
|
|
3352
|
-
except Exception as e:
|
|
3353
|
-
self.message("- {} : {!r}".format(e, text))
|
|
3354
|
-
|
|
3355
|
-
def call_helpTip(self, evt):
|
|
3356
|
-
"""Show tooltips for the selected topic."""
|
|
3357
|
-
if self.CallTipActive():
|
|
3358
|
-
self.CallTipCancel()
|
|
3359
|
-
|
|
3360
|
-
text = self.SelectedText or self.Command or self.expr_at_caret
|
|
3361
|
-
if text:
|
|
3362
|
-
try:
|
|
3363
|
-
p = self.cpos
|
|
3364
|
-
c = self.get_char(p-1)
|
|
3365
|
-
self.autoCallTipShow(text,
|
|
3366
|
-
c == '(' and p == self.eol) # => CallTipShow
|
|
3367
|
-
except Exception as e:
|
|
3368
|
-
self.message("- {} : {!r}".format(e, text))
|
|
3369
|
-
|
|
3370
|
-
def on_completion_forward(self, evt):
|
|
3371
|
-
if self.AutoCompActive():
|
|
3372
|
-
self.on_completion(evt, 1)
|
|
3373
|
-
else:
|
|
3374
|
-
self.handler('quit', evt)
|
|
3375
|
-
|
|
3376
|
-
def on_completion_backward(self, evt):
|
|
3377
|
-
if self.AutoCompActive():
|
|
3378
|
-
self.on_completion(evt, -1)
|
|
3379
|
-
else:
|
|
3380
|
-
self.handler('quit', evt)
|
|
3381
|
-
|
|
3382
|
-
def on_completion_forward_history(self, evt):
|
|
3383
|
-
self.on_completion(evt, 1) # 古いヒストリへ進む
|
|
3384
|
-
|
|
3385
|
-
def on_completion_backward_history(self, evt):
|
|
3386
|
-
self.on_completion(evt, -1) # 新しいヒストリへ戻る
|
|
3387
|
-
|
|
3388
|
-
def on_completion(self, evt, step=0):
|
|
3389
|
-
"""Show completion with selection."""
|
|
3390
|
-
try:
|
|
3391
|
-
N = len(self.__comp_words)
|
|
3392
|
-
j = self.__comp_ind + step
|
|
3393
|
-
j = 0 if j < 0 else j if j < N else N-1
|
|
3394
|
-
word = self.__comp_words[j]
|
|
3395
|
-
n = len(self.__comp_hint)
|
|
3396
|
-
p = self.cpos
|
|
3397
|
-
if not self.SelectedText:
|
|
3398
|
-
p, self.anchor, sty = self.get_following_atom(p) # word-right-selection
|
|
3399
|
-
self.ReplaceSelection(word[n:]) # Modify (or insert) the selected range
|
|
3400
|
-
self.cpos = p # backward selection to the point
|
|
3401
|
-
self.__comp_ind = j
|
|
3402
|
-
except IndexError:
|
|
3403
|
-
self.message("No completion words")
|
|
3404
|
-
|
|
3405
|
-
def _gen_autocomp(self, j, hint, words, sep=' '):
|
|
3406
|
-
"""Call AutoCompShow for the specified words and sep."""
|
|
3407
|
-
## Prepare on_completion_forward/backward
|
|
3408
|
-
self.__comp_ind = j
|
|
3409
|
-
self.__comp_hint = hint
|
|
3410
|
-
self.__comp_words = words
|
|
3411
|
-
if words:
|
|
3412
|
-
self.AutoCompSetSeparator(ord(sep))
|
|
3413
|
-
self.AutoCompShow(len(hint), sep.join(words))
|
|
3414
|
-
|
|
3415
|
-
@staticmethod
|
|
3416
|
-
def _get_last_hint(cmdl):
|
|
3417
|
-
return re.search(r"[\w.]*$", cmdl).group(0) # or ''
|
|
3418
|
-
|
|
3419
|
-
@staticmethod
|
|
3420
|
-
def _get_words_hint(cmdl):
|
|
3421
|
-
text = next(split_words(cmdl, reverse=1), '')
|
|
3422
|
-
return text.rpartition('.') # -> text, sep, hint
|
|
3423
|
-
|
|
3424
|
-
def call_history_comp(self, evt):
|
|
3425
|
-
"""Called when history-comp mode."""
|
|
3426
|
-
if not self.CanEdit():
|
|
3427
|
-
self.handler('quit', evt)
|
|
3428
|
-
return
|
|
3429
|
-
try:
|
|
3430
|
-
cmdl = self.cmdlc
|
|
3431
|
-
if cmdl.isspace() or self.bol != self.bolc:
|
|
3432
|
-
self.handler('fork', evt) # fork [tab pressed] => on_indent_line
|
|
3433
|
-
return
|
|
3434
|
-
|
|
3435
|
-
hint = cmdl.strip()
|
|
3436
|
-
ls = [x.replace('\n', os.linesep + sys.ps2)
|
|
3437
|
-
for x in self.history if x.startswith(hint)] # case-sensitive match
|
|
3438
|
-
words = sorted(set(ls), key=ls.index, reverse=0) # keep order, no duplication
|
|
3439
|
-
|
|
3440
|
-
self.__comp_ind = 0
|
|
3441
|
-
self.__comp_hint = hint
|
|
3442
|
-
self.__comp_words = words
|
|
3443
|
-
|
|
3444
|
-
self.anchor = self.eolc # selection to eol
|
|
3445
|
-
self.on_completion(evt) # show completion always
|
|
3446
|
-
|
|
3447
|
-
## the latest history stacks in the head of the list (time-descending)
|
|
3448
|
-
self.message("[history] {} candidates matched"
|
|
3449
|
-
" with {!r}".format(len(words), hint))
|
|
3450
|
-
except Exception:
|
|
3451
|
-
raise
|
|
3452
|
-
|
|
3453
|
-
def call_text_autocomp(self, evt):
|
|
3454
|
-
"""Called when text-comp mode."""
|
|
3455
|
-
if not self.CanEdit():
|
|
3456
|
-
self.handler('quit', evt)
|
|
3457
|
-
return
|
|
3458
|
-
try:
|
|
3459
|
-
cmdl = self.cmdlc
|
|
3460
|
-
hint = self._get_last_hint(cmdl)
|
|
3461
|
-
|
|
3462
|
-
ls = [x for x in self.fragmwords if x.startswith(hint)] # case-sensitive match
|
|
3463
|
-
words = sorted(ls, key=lambda s:s.upper())
|
|
3464
|
-
|
|
3465
|
-
self._gen_autocomp(0, hint, words)
|
|
3466
|
-
self.message("[text] {} candidates matched"
|
|
3467
|
-
" with {!r}".format(len(words), hint))
|
|
3468
|
-
except Exception:
|
|
3469
|
-
raise
|
|
3470
|
-
|
|
3471
|
-
def call_module_autocomp(self, evt, force=False):
|
|
3472
|
-
"""Called when module-comp mode."""
|
|
3473
|
-
if not self.CanEdit():
|
|
3474
|
-
self.handler('quit', evt)
|
|
3475
|
-
return
|
|
3476
|
-
|
|
3477
|
-
def _continue(hints):
|
|
3478
|
-
if not hints.endswith(' '):
|
|
3479
|
-
h = hints.strip()
|
|
3480
|
-
if not h.endswith(','):
|
|
3481
|
-
lh = h.split(',')[-1].strip() # 'x, y, z|' last hint after ','
|
|
3482
|
-
if ' ' not in lh: # 'x, y as|' contains no spaces.
|
|
3483
|
-
return lh
|
|
3484
|
-
try:
|
|
3485
|
-
cmdl = self.cmdlc
|
|
3486
|
-
hint = self._get_last_hint(cmdl)
|
|
3487
|
-
|
|
3488
|
-
if (m := re.match(r"from\s+([\w.]+)\s+import\s+(.*)", cmdl)):
|
|
3489
|
-
text, hints = m.groups()
|
|
3490
|
-
if not _continue(hints) and not force:
|
|
3491
|
-
self.message("[module]>>> waiting for key input...")
|
|
3492
|
-
return
|
|
3493
|
-
elif hints.endswith('.'):
|
|
3494
|
-
self.message("[module] invalid import syntax.")
|
|
3495
|
-
return
|
|
3496
|
-
if text not in sys.modules:
|
|
3497
|
-
self.message("[module]>>> loading {}...".format(text))
|
|
3498
|
-
try:
|
|
3499
|
-
modules = set(dir(import_module(text)))
|
|
3500
|
-
except ImportError as e:
|
|
3501
|
-
self.message("\b failed:", e)
|
|
3502
|
-
return
|
|
3503
|
-
## Add unimported module names.
|
|
3504
|
-
p = "{}.{}".format(text, hint)
|
|
3505
|
-
keys = [x[len(text)+1:] for x in self.modules if x.startswith(p)]
|
|
3506
|
-
modules.update(k for k in keys if '.' not in k)
|
|
3507
|
-
|
|
3508
|
-
elif (m := re.match(r"(import|from)\s+(.*)", cmdl)):
|
|
3509
|
-
text, hints = m.groups()
|
|
3510
|
-
if not _continue(hints) and not force:
|
|
3511
|
-
self.message("[module]>>> waiting for key input...")
|
|
3512
|
-
return
|
|
3513
|
-
modules = self.modules
|
|
3514
|
-
else:
|
|
3515
|
-
text, sep, hint = self._get_words_hint(cmdl)
|
|
3516
|
-
obj = self.eval(text)
|
|
3517
|
-
modules = set(k for k, v in vars(obj).items() if inspect.ismodule(v))
|
|
3518
|
-
|
|
3519
|
-
P = re.compile(hint)
|
|
3520
|
-
p = re.compile(hint, re.I)
|
|
3521
|
-
words = sorted([x for x in modules if p.match(x)], key=lambda s:s.upper())
|
|
3522
|
-
|
|
3523
|
-
j = next((k for k, w in enumerate(words) if P.match(w)),
|
|
3524
|
-
next((k for k, w in enumerate(words) if p.match(w)), -1))
|
|
3525
|
-
|
|
3526
|
-
self._gen_autocomp(j, hint, words)
|
|
3527
|
-
self.message("[module] {} candidates matched"
|
|
3528
|
-
" with {!r} in {}".format(len(words), hint, text))
|
|
3529
|
-
except re.error as e:
|
|
3530
|
-
self.message("- re:miss compilation {!r} : {!r}".format(e, hint))
|
|
3531
|
-
except SyntaxError as e:
|
|
3532
|
-
self.handler('quit', evt)
|
|
3533
|
-
self.message("- {} : {!r}".format(e, text))
|
|
3534
|
-
except Exception as e:
|
|
3535
|
-
self.message("- {} : {!r}".format(e, text))
|
|
3536
|
-
|
|
3537
|
-
def call_word_autocomp(self, evt):
|
|
3538
|
-
"""Called when word-comp mode."""
|
|
3539
|
-
if not self.CanEdit():
|
|
3540
|
-
self.handler('quit', evt)
|
|
3541
|
-
return
|
|
3542
|
-
try:
|
|
3543
|
-
text, sep, hint = self._get_words_hint(self.cmdlc)
|
|
3544
|
-
obj = self.eval(text)
|
|
3545
|
-
|
|
3546
|
-
P = re.compile(hint)
|
|
3547
|
-
p = re.compile(hint, re.I)
|
|
3548
|
-
words = sorted([x for x in dir(obj) if p.match(x)], key=lambda s:s.upper())
|
|
3549
|
-
|
|
3550
|
-
j = next((k for k, w in enumerate(words) if P.match(w)),
|
|
3551
|
-
next((k for k, w in enumerate(words) if p.match(w)), -1))
|
|
3552
|
-
|
|
3553
|
-
self._gen_autocomp(j, hint, words)
|
|
3554
|
-
self.message("[word] {} candidates matched"
|
|
3555
|
-
" with {!r} in {}".format(len(words), hint, text))
|
|
3556
|
-
except re.error as e:
|
|
3557
|
-
self.message("- re:miss compilation {!r} : {!r}".format(e, hint))
|
|
3558
|
-
except SyntaxError as e:
|
|
3559
|
-
self.handler('quit', evt)
|
|
3560
|
-
self.message("- {} : {!r}".format(e, text))
|
|
3561
|
-
except Exception as e:
|
|
3562
|
-
self.message("- {} : {!r}".format(e, text))
|
|
3563
|
-
|
|
3564
|
-
def call_apropos_autocomp(self, evt):
|
|
3565
|
-
"""Called when apropos mode."""
|
|
3566
|
-
if not self.CanEdit():
|
|
3567
|
-
self.handler('quit', evt)
|
|
3568
|
-
return
|
|
3569
|
-
try:
|
|
3570
|
-
text, sep, hint = self._get_words_hint(self.cmdlc)
|
|
3571
|
-
obj = self.eval(text)
|
|
3572
|
-
|
|
3573
|
-
P = re.compile(hint)
|
|
3574
|
-
p = re.compile(hint, re.I)
|
|
3575
|
-
words = sorted([x for x in dir(obj) if p.search(x)], key=lambda s:s.upper())
|
|
3576
|
-
|
|
3577
|
-
j = next((k for k, w in enumerate(words) if P.match(w)),
|
|
3578
|
-
next((k for k, w in enumerate(words) if p.match(w)), -1))
|
|
3579
|
-
|
|
3580
|
-
self._gen_autocomp(j, hint, words)
|
|
3581
|
-
self.message("[apropos] {} candidates matched"
|
|
3582
|
-
" with {!r} in {}".format(len(words), hint, text))
|
|
3583
|
-
except re.error as e:
|
|
3584
|
-
self.message("- re:miss compilation {!r} : {!r}".format(e, hint))
|
|
3585
|
-
except SyntaxError as e:
|
|
3586
|
-
self.handler('quit', evt)
|
|
3587
|
-
self.message("- {} : {!r}".format(e, text))
|
|
3588
|
-
except Exception as e:
|
|
3589
|
-
self.message("- {} : {!r}".format(e, text))
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
mwx/__init__.py,sha256=nN62CGTWjME7Zz2h-jIRB8MxwuErIkHPGrlBzydkF0o,643
|
|
2
2
|
mwx/bookshelf.py,sha256=Y4xI2SrEO22DrI1hyyfFx7DfFZA8znOzX9RWMPsA2BE,5137
|
|
3
|
-
mwx/controls.py,sha256=
|
|
4
|
-
mwx/framework.py,sha256=
|
|
3
|
+
mwx/controls.py,sha256=K4GJB81TXv5q0faTELQgbUmtMQBRIM9yINJdTI0xA3g,47556
|
|
4
|
+
mwx/framework.py,sha256=kKG4rcBiq-PD5v1sHLtI1XRTve0wugG6JwwNbMv5Pa8,75509
|
|
5
5
|
mwx/graphman.py,sha256=Cyhl_Da_HGBfk721gu1r5iwSH9L3yPEG8Fzmc2gx-EU,70462
|
|
6
6
|
mwx/images.py,sha256=_-Eh3xF7Khu42ivkYp97NXIzSNGbjcidqtWjZQFGtqE,47827
|
|
7
7
|
mwx/matplot2.py,sha256=xCJ_ZzdDEWmzctpPaOrzTnwXyHINP4nfFHweoTZa6ug,32899
|
|
8
8
|
mwx/matplot2g.py,sha256=wiZFDFuQe3ax71fmyeR_9hvAmgT-4nVfZ30UByv8Nv8,64379
|
|
9
9
|
mwx/matplot2lg.py,sha256=JRWjWnLJUytbSq6wxs4P0gbVUr3xoLSF6Wwqd5V_pJI,27404
|
|
10
10
|
mwx/mgplt.py,sha256=ITzxA97yDwr_35BUk5OqnyskSuKVDbpf2AQCKY1jHTI,5671
|
|
11
|
-
mwx/nutshell.py,sha256=
|
|
11
|
+
mwx/nutshell.py,sha256=iVJGFh45ZtXs_g8LGi1UNI6H-3jI2pDkYNc2eF3T-7k,142853
|
|
12
12
|
mwx/utilus.py,sha256=mmqB4P_3mTi7SrFleMiN1599Jm0Us0XKnNA6v2xglSs,37333
|
|
13
13
|
mwx/wxmon.py,sha256=f3V24EF7kdMlYF7usLYK9QE5KU6fSu0jVqsvwAiA-Ag,12647
|
|
14
14
|
mwx/wxpdb.py,sha256=lLowkkAgMhPFHAfklD7wZHq0qbSMjRxnBFtSajmVgME,19133
|
|
@@ -21,8 +21,8 @@ mwx/plugins/frame_listview.py,sha256=hbApzZWa9-BmQthu7uZBlBbGbtf4iJ_prO8IhxoGMs8
|
|
|
21
21
|
mwx/plugins/line_profile.py,sha256=--9NIc3x5EfRB3L59JvD7rzENQHyiYfu7wWJo6AuMkA,820
|
|
22
22
|
mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
|
|
23
23
|
mwx/py/filling.py,sha256=fumUG1F5M9TL-Dfqni4G85uk7TmvnUunTbdcPDV0vfo,16857
|
|
24
|
-
mwxlib-0.
|
|
25
|
-
mwxlib-0.
|
|
26
|
-
mwxlib-0.
|
|
27
|
-
mwxlib-0.
|
|
28
|
-
mwxlib-0.
|
|
24
|
+
mwxlib-0.98.0.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
|
|
25
|
+
mwxlib-0.98.0.dist-info/METADATA,sha256=qAaHXqyArN_ZNCNoeukt6YxYGPQ-n8h9JIgfAcKuBnU,1880
|
|
26
|
+
mwxlib-0.98.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
27
|
+
mwxlib-0.98.0.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
|
|
28
|
+
mwxlib-0.98.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|