mwxlib 0.98.1__py3-none-any.whl → 0.98.6__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 +5 -4
- mwx/framework.py +38 -41
- mwx/graphman.py +49 -57
- mwx/matplot2g.py +3 -3
- mwx/mgplt.py +1 -1
- mwx/nutshell.py +112 -107
- mwx/plugins/ffmpeg_view.py +2 -2
- mwx/utilus.py +1 -1
- mwxlib-0.98.6.dist-info/METADATA +228 -0
- {mwxlib-0.98.1.dist-info → mwxlib-0.98.6.dist-info}/RECORD +13 -13
- {mwxlib-0.98.1.dist-info → mwxlib-0.98.6.dist-info}/WHEEL +1 -1
- mwxlib-0.98.1.dist-info/METADATA +0 -54
- {mwxlib-0.98.1.dist-info → mwxlib-0.98.6.dist-info}/LICENSE +0 -0
- {mwxlib-0.98.1.dist-info → mwxlib-0.98.6.dist-info}/top_level.txt +0 -0
mwx/nutshell.py
CHANGED
|
@@ -10,7 +10,6 @@ import traceback
|
|
|
10
10
|
import inspect
|
|
11
11
|
import builtins
|
|
12
12
|
import operator
|
|
13
|
-
import dis
|
|
14
13
|
import pydoc
|
|
15
14
|
import keyword
|
|
16
15
|
import linecache
|
|
@@ -102,12 +101,13 @@ class AutoCompInterfaceMixin:
|
|
|
102
101
|
(override) Snip the tip of max N lines if it is too long.
|
|
103
102
|
Keep the tip for calltip-click event.
|
|
104
103
|
"""
|
|
105
|
-
self._calltips =
|
|
104
|
+
self._calltips = [pos, tip, False]
|
|
106
105
|
lines = tip.splitlines()
|
|
107
106
|
if N and len(lines) > N > 0:
|
|
108
107
|
lines[N+1:] = ["\n...(snip) This tips are too long... "
|
|
109
108
|
"Click to show more details."]
|
|
110
109
|
tip = '\n'.join(lines)
|
|
110
|
+
self._calltips[-1] = True # snipped (needs to be shown)
|
|
111
111
|
super().CallTipShow(pos, tip)
|
|
112
112
|
|
|
113
113
|
def autoCallTipShow(self, command, insertcalltip=True):
|
|
@@ -142,7 +142,7 @@ class AutoCompInterfaceMixin:
|
|
|
142
142
|
self.message("- {} : {!r}".format(e, text))
|
|
143
143
|
|
|
144
144
|
def call_helpTip(self, evt):
|
|
145
|
-
"""Show
|
|
145
|
+
"""Show a calltip for the selected function."""
|
|
146
146
|
if self.CallTipActive():
|
|
147
147
|
self.CallTipCancel()
|
|
148
148
|
|
|
@@ -174,8 +174,11 @@ class AutoCompInterfaceMixin:
|
|
|
174
174
|
n = len(self.__comp_hint)
|
|
175
175
|
p = self.cpos
|
|
176
176
|
if not self.SelectedText:
|
|
177
|
-
p,
|
|
178
|
-
|
|
177
|
+
p, q, sty = self.get_following_atom(p) # word-right-selection
|
|
178
|
+
if sty == 'word':
|
|
179
|
+
self.anchor = q
|
|
180
|
+
with self.off_undocollection():
|
|
181
|
+
self.ReplaceSelection(word[n:])
|
|
179
182
|
self.cpos = p # backward selection to the point
|
|
180
183
|
self.__comp_ind = j
|
|
181
184
|
except IndexError:
|
|
@@ -264,7 +267,7 @@ class AutoCompInterfaceMixin:
|
|
|
264
267
|
self.message("[module]>>> loading {}...".format(text))
|
|
265
268
|
modules = set(dir(import_module(text)))
|
|
266
269
|
except ImportError as e:
|
|
267
|
-
self.message("\b failed
|
|
270
|
+
self.message("\b failed.", e)
|
|
268
271
|
return
|
|
269
272
|
else:
|
|
270
273
|
## Add unimported module names.
|
|
@@ -356,7 +359,7 @@ class AutoCompInterfaceMixin:
|
|
|
356
359
|
self.message("- {} : {!r}".format(e, text))
|
|
357
360
|
|
|
358
361
|
|
|
359
|
-
class EditorInterface(CtrlInterface):
|
|
362
|
+
class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
360
363
|
"""Interface of Python code editor.
|
|
361
364
|
|
|
362
365
|
Note:
|
|
@@ -364,6 +367,7 @@ class EditorInterface(CtrlInterface):
|
|
|
364
367
|
"""
|
|
365
368
|
def __init__(self):
|
|
366
369
|
CtrlInterface.__init__(self)
|
|
370
|
+
AutoCompInterfaceMixin.__init__(self)
|
|
367
371
|
|
|
368
372
|
def dispatch(evt):
|
|
369
373
|
"""Fork events to the parent."""
|
|
@@ -414,8 +418,8 @@ class EditorInterface(CtrlInterface):
|
|
|
414
418
|
'C-S-; pressed' : (0, _F(self.comment_out_line)),
|
|
415
419
|
'C-: pressed' : (0, _F(self.uncomment_line)),
|
|
416
420
|
'C-S-: pressed' : (0, _F(self.uncomment_line)),
|
|
417
|
-
'select_line' : (
|
|
418
|
-
'select_lines' : (
|
|
421
|
+
'select_line' : (11, self.on_linesel_begin),
|
|
422
|
+
'select_lines' : (11, self.on_linesel_next),
|
|
419
423
|
},
|
|
420
424
|
10 : {
|
|
421
425
|
'quit' : (0, self.on_itext_exit),
|
|
@@ -424,8 +428,8 @@ class EditorInterface(CtrlInterface):
|
|
|
424
428
|
'down pressed' : (10, skip),
|
|
425
429
|
'enter pressed' : (0, self.on_itext_selection),
|
|
426
430
|
},
|
|
427
|
-
|
|
428
|
-
'*Ldrag move' : (
|
|
431
|
+
11 : {
|
|
432
|
+
'*Ldrag move' : (11, self.on_linesel_motion),
|
|
429
433
|
'capture_lost' : (0, self.on_linesel_end),
|
|
430
434
|
'Lbutton released' : (0, self.on_linesel_end),
|
|
431
435
|
},
|
|
@@ -871,22 +875,10 @@ class EditorInterface(CtrlInterface):
|
|
|
871
875
|
q = self.cpos
|
|
872
876
|
return self.GetTextRange(p, q)
|
|
873
877
|
|
|
874
|
-
def gen_text_at_caret(self):
|
|
875
|
-
"""Generates the selected text,
|
|
876
|
-
otherwise the line or expression at the caret.
|
|
877
|
-
"""
|
|
878
|
-
def _gen_text():
|
|
879
|
-
text = self.SelectedText
|
|
880
|
-
if text:
|
|
881
|
-
yield text
|
|
882
|
-
else:
|
|
883
|
-
yield self.line_at_caret
|
|
884
|
-
yield self.expr_at_caret
|
|
885
|
-
return filter(None, _gen_text())
|
|
886
|
-
|
|
887
878
|
## --------------------------------
|
|
888
879
|
## Python syntax and indentation
|
|
889
880
|
## --------------------------------
|
|
881
|
+
|
|
890
882
|
def on_indent_line(self, evt):
|
|
891
883
|
if self.SelectedText:
|
|
892
884
|
evt.Skip()
|
|
@@ -1191,10 +1183,10 @@ class EditorInterface(CtrlInterface):
|
|
|
1191
1183
|
"""
|
|
1192
1184
|
n = self.LinesOnScreen() # lines completely visible
|
|
1193
1185
|
m = n//2 if ln is None else ln % n if ln < n else n # ln[0:n]
|
|
1194
|
-
vl = self.
|
|
1186
|
+
vl = self._calc_vline(self.cline)
|
|
1195
1187
|
self.ScrollToLine(vl - m)
|
|
1196
1188
|
|
|
1197
|
-
def
|
|
1189
|
+
def _calc_vline(self, line):
|
|
1198
1190
|
"""Virtual line numberin the buffer window."""
|
|
1199
1191
|
pos = self.PositionFromLine(line)
|
|
1200
1192
|
w, h = self.PointFromPosition(pos)
|
|
@@ -1206,7 +1198,7 @@ class EditorInterface(CtrlInterface):
|
|
|
1206
1198
|
"""
|
|
1207
1199
|
n = self.LinesOnScreen() # lines completely visible
|
|
1208
1200
|
hl = self.FirstVisibleLine
|
|
1209
|
-
vl = self.
|
|
1201
|
+
vl = self._calc_vline(line)
|
|
1210
1202
|
if vl < hl:
|
|
1211
1203
|
self.ScrollToLine(vl)
|
|
1212
1204
|
elif vl > hl + n - 1:
|
|
@@ -1219,7 +1211,7 @@ class EditorInterface(CtrlInterface):
|
|
|
1219
1211
|
"""
|
|
1220
1212
|
n = self.LinesOnScreen() # lines completely visible
|
|
1221
1213
|
hl = self.FirstVisibleLine
|
|
1222
|
-
vl = self.
|
|
1214
|
+
vl = self._calc_vline(line)
|
|
1223
1215
|
if not hl + offset < vl < hl + n - 1 - offset:
|
|
1224
1216
|
self.ScrollToLine(vl - n//2)
|
|
1225
1217
|
|
|
@@ -1512,16 +1504,6 @@ class EditorInterface(CtrlInterface):
|
|
|
1512
1504
|
else:
|
|
1513
1505
|
self.anchor = q
|
|
1514
1506
|
|
|
1515
|
-
@contextmanager
|
|
1516
|
-
def off_readonly(self):
|
|
1517
|
-
"""Set buffer to be writable (ReadOnly=False) temporarily."""
|
|
1518
|
-
r = self.ReadOnly
|
|
1519
|
-
try:
|
|
1520
|
-
self.ReadOnly = 0
|
|
1521
|
-
yield
|
|
1522
|
-
finally:
|
|
1523
|
-
self.ReadOnly = r
|
|
1524
|
-
|
|
1525
1507
|
@contextmanager
|
|
1526
1508
|
def save_attributes(self, **kwargs):
|
|
1527
1509
|
"""Save buffer attributes (e.g. ReadOnly=False)."""
|
|
@@ -1534,6 +1516,14 @@ class EditorInterface(CtrlInterface):
|
|
|
1534
1516
|
for k, v in kwargs.items():
|
|
1535
1517
|
setattr(self, k, v)
|
|
1536
1518
|
|
|
1519
|
+
def off_readonly(self):
|
|
1520
|
+
"""Disables buffer read-only lock temporarily."""
|
|
1521
|
+
return self.save_attributes(ReadOnly=False)
|
|
1522
|
+
|
|
1523
|
+
def off_undocollection(self):
|
|
1524
|
+
"""Disables buffer undo stack temporarily."""
|
|
1525
|
+
return self.save_attributes(UndoCollection=False)
|
|
1526
|
+
|
|
1537
1527
|
## --------------------------------
|
|
1538
1528
|
## Edit: comment / insert / kill
|
|
1539
1529
|
## --------------------------------
|
|
@@ -1640,7 +1630,7 @@ class EditorInterface(CtrlInterface):
|
|
|
1640
1630
|
self.ReplaceSelection('')
|
|
1641
1631
|
|
|
1642
1632
|
|
|
1643
|
-
class Buffer(
|
|
1633
|
+
class Buffer(EditorInterface, EditWindow):
|
|
1644
1634
|
"""Python code buffer.
|
|
1645
1635
|
|
|
1646
1636
|
Attributes:
|
|
@@ -1766,7 +1756,6 @@ class Buffer(AutoCompInterfaceMixin, EditorInterface, EditWindow):
|
|
|
1766
1756
|
def __init__(self, parent, filename=None, **kwargs):
|
|
1767
1757
|
EditWindow.__init__(self, parent, **kwargs)
|
|
1768
1758
|
EditorInterface.__init__(self)
|
|
1769
|
-
AutoCompInterfaceMixin.__init__(self)
|
|
1770
1759
|
|
|
1771
1760
|
self.parent = parent
|
|
1772
1761
|
self.__filename = filename
|
|
@@ -1795,18 +1784,18 @@ class Buffer(AutoCompInterfaceMixin, EditorInterface, EditWindow):
|
|
|
1795
1784
|
def clear(evt):
|
|
1796
1785
|
## """Clear selection and message, no skip."""
|
|
1797
1786
|
## *do not* clear autocomp, so that the event can skip to AutoComp properly.
|
|
1798
|
-
## if self.AutoCompActive():
|
|
1799
|
-
## self.AutoCompCancel() # may delete selection
|
|
1800
1787
|
if self.CanEdit():
|
|
1801
|
-
self.
|
|
1788
|
+
with self.off_undocollection():
|
|
1789
|
+
self.ReplaceSelection("")
|
|
1802
1790
|
self.message("")
|
|
1803
1791
|
|
|
1804
1792
|
def clear_autocomp(evt):
|
|
1805
|
-
## """Clear
|
|
1793
|
+
## """Clear autocomp, selection, and message."""
|
|
1806
1794
|
if self.AutoCompActive():
|
|
1807
1795
|
self.AutoCompCancel()
|
|
1808
1796
|
if self.CanEdit():
|
|
1809
|
-
self.
|
|
1797
|
+
with self.off_undocollection():
|
|
1798
|
+
self.ReplaceSelection("")
|
|
1810
1799
|
self.message("")
|
|
1811
1800
|
|
|
1812
1801
|
def fork(evt):
|
|
@@ -1840,7 +1829,7 @@ class Buffer(AutoCompInterfaceMixin, EditorInterface, EditWindow):
|
|
|
1840
1829
|
'* released' : (0, skip, dispatch),
|
|
1841
1830
|
'escape pressed' : (-1, self.on_enter_escmap),
|
|
1842
1831
|
'C-h pressed' : (0, self.call_helpTip),
|
|
1843
|
-
'. pressed' : (2,
|
|
1832
|
+
'. pressed' : (2, self.OnEnterDot),
|
|
1844
1833
|
'M-. pressed' : (2, self.call_word_autocomp),
|
|
1845
1834
|
'M-/ pressed' : (3, self.call_apropos_autocomp),
|
|
1846
1835
|
},
|
|
@@ -1922,7 +1911,9 @@ class Buffer(AutoCompInterfaceMixin, EditorInterface, EditWindow):
|
|
|
1922
1911
|
def OnCallTipClick(self, evt):
|
|
1923
1912
|
if self.CallTipActive():
|
|
1924
1913
|
self.CallTipCancel()
|
|
1925
|
-
self.
|
|
1914
|
+
pos, tip, more = self._calltips
|
|
1915
|
+
if more:
|
|
1916
|
+
self.CallTipShow(pos, tip, N=None)
|
|
1926
1917
|
evt.Skip()
|
|
1927
1918
|
|
|
1928
1919
|
def OnIndicatorClick(self, evt):
|
|
@@ -1960,6 +1951,14 @@ class Buffer(AutoCompInterfaceMixin, EditorInterface, EditWindow):
|
|
|
1960
1951
|
self.update_caption()
|
|
1961
1952
|
evt.Skip()
|
|
1962
1953
|
|
|
1954
|
+
def OnEnterDot(self, evt):
|
|
1955
|
+
p = self.cpos
|
|
1956
|
+
st = self.get_style(p-1)
|
|
1957
|
+
rst = self.get_style(p)
|
|
1958
|
+
if st not in ('moji', 'word', 'rparen') or rst == 'word':
|
|
1959
|
+
self.handler('quit', evt) # don't enter autocomp
|
|
1960
|
+
evt.Skip()
|
|
1961
|
+
|
|
1963
1962
|
def on_activated(self, buf):
|
|
1964
1963
|
"""Called when the buffer is activated."""
|
|
1965
1964
|
self.update_caption()
|
|
@@ -2052,6 +2051,22 @@ class Buffer(AutoCompInterfaceMixin, EditorInterface, EditWindow):
|
|
|
2052
2051
|
dispatcher.send(signal='Interpreter.push',
|
|
2053
2052
|
sender=self, command=None, more=False)
|
|
2054
2053
|
|
|
2054
|
+
def gen_text_at_caret(self):
|
|
2055
|
+
"""Generates the selected text,
|
|
2056
|
+
otherwise the line or expression at the caret.
|
|
2057
|
+
"""
|
|
2058
|
+
def _gen_text():
|
|
2059
|
+
text = self.SelectedText
|
|
2060
|
+
if text:
|
|
2061
|
+
yield text
|
|
2062
|
+
else:
|
|
2063
|
+
yield self.line_at_caret
|
|
2064
|
+
yield self.expr_at_caret
|
|
2065
|
+
return filter(None, _gen_text())
|
|
2066
|
+
|
|
2067
|
+
def eval_line(self):
|
|
2068
|
+
self.py_eval_line(self.globals, self.locals)
|
|
2069
|
+
|
|
2055
2070
|
def py_eval_line(self, globals=None, locals=None):
|
|
2056
2071
|
if self.CallTipActive():
|
|
2057
2072
|
self.CallTipCancel()
|
|
@@ -2068,6 +2083,9 @@ class Buffer(AutoCompInterfaceMixin, EditorInterface, EditWindow):
|
|
|
2068
2083
|
return
|
|
2069
2084
|
self.message(status)
|
|
2070
2085
|
|
|
2086
|
+
def exec_region(self):
|
|
2087
|
+
self.py_exec_region(self.globals, self.locals)
|
|
2088
|
+
|
|
2071
2089
|
def py_exec_region(self, globals=None, locals=None, filename=None):
|
|
2072
2090
|
if not filename:
|
|
2073
2091
|
filename = self.filename
|
|
@@ -2100,23 +2118,6 @@ class Buffer(AutoCompInterfaceMixin, EditorInterface, EditWindow):
|
|
|
2100
2118
|
self.handler('buffer_region_executed', self)
|
|
2101
2119
|
self.message("Evaluated {!r} successfully.".format(filename))
|
|
2102
2120
|
self.AnnotationClearAll()
|
|
2103
|
-
|
|
2104
|
-
def py_get_region(self, line):
|
|
2105
|
-
"""Line numbers of code head and tail containing the line.
|
|
2106
|
-
|
|
2107
|
-
Requires a code object.
|
|
2108
|
-
If the code doesn't exist, return the folding region.
|
|
2109
|
-
"""
|
|
2110
|
-
if not self.code:
|
|
2111
|
-
return self.get_region(line)
|
|
2112
|
-
lc, le = 0, self.LineCount
|
|
2113
|
-
linestarts = list(dis.findlinestarts(self.code))
|
|
2114
|
-
for i, ln in reversed(linestarts):
|
|
2115
|
-
if line >= ln-1:
|
|
2116
|
-
lc = ln-1
|
|
2117
|
-
break
|
|
2118
|
-
le = ln-1
|
|
2119
|
-
return lc, le
|
|
2120
2121
|
|
|
2121
2122
|
|
|
2122
2123
|
class EditorBook(AuiNotebook, CtrlInterface):
|
|
@@ -2402,7 +2403,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2402
2403
|
return True
|
|
2403
2404
|
return False
|
|
2404
2405
|
except Exception as e:
|
|
2405
|
-
self.post_message(f"Failed to load {filename!r}
|
|
2406
|
+
self.post_message(f"Failed to load {filename!r}.", e)
|
|
2406
2407
|
self.delete_buffer(buf)
|
|
2407
2408
|
return False
|
|
2408
2409
|
|
|
@@ -2410,6 +2411,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2410
2411
|
"""Open the specified file."""
|
|
2411
2412
|
if not filename:
|
|
2412
2413
|
with wx.FileDialog(self, "Open buffer",
|
|
2414
|
+
defaultDir=os.path.dirname(self.buffer.filename),
|
|
2413
2415
|
wildcard='|'.join(self.wildcards),
|
|
2414
2416
|
style=wx.FD_OPEN|wx.FD_MULTIPLE) as dlg:
|
|
2415
2417
|
if dlg.ShowModal() == wx.ID_OK:
|
|
@@ -2444,7 +2446,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2444
2446
|
return True
|
|
2445
2447
|
return False
|
|
2446
2448
|
except Exception as e:
|
|
2447
|
-
self.post_message(f"Failed to save {filename!r}
|
|
2449
|
+
self.post_message(f"Failed to save {filename!r}.", e)
|
|
2448
2450
|
return False
|
|
2449
2451
|
|
|
2450
2452
|
def load_buffer(self, buf=None):
|
|
@@ -2477,6 +2479,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2477
2479
|
"""Confirm the saveas with the dialog."""
|
|
2478
2480
|
buf = buf or self.buffer
|
|
2479
2481
|
with wx.FileDialog(self, "Save buffer as",
|
|
2482
|
+
defaultDir=os.path.dirname(self.buffer.filename),
|
|
2480
2483
|
defaultFile=re.sub(r'[\/:*?"<>|]', '_', buf.name),
|
|
2481
2484
|
wildcard='|'.join(self.wildcards),
|
|
2482
2485
|
style=wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dlg:
|
|
@@ -2519,11 +2522,10 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2519
2522
|
class Interpreter(interpreter.Interpreter):
|
|
2520
2523
|
"""Interpreter based on code.InteractiveInterpreter.
|
|
2521
2524
|
"""
|
|
2522
|
-
def __init__(self, *args, **kwargs):
|
|
2523
|
-
parent = kwargs.pop('interpShell')
|
|
2525
|
+
def __init__(self, interpShell, *args, **kwargs):
|
|
2524
2526
|
interpreter.Interpreter.__init__(self, *args, **kwargs)
|
|
2525
2527
|
|
|
2526
|
-
self.parent =
|
|
2528
|
+
self.parent = interpShell
|
|
2527
2529
|
self.globals = self.locals
|
|
2528
2530
|
|
|
2529
2531
|
def runcode(self, code):
|
|
@@ -2587,7 +2589,7 @@ class Interpreter(interpreter.Interpreter):
|
|
|
2587
2589
|
return interpreter.Interpreter.getCallTip(self) # dummy
|
|
2588
2590
|
|
|
2589
2591
|
|
|
2590
|
-
class Nautilus(
|
|
2592
|
+
class Nautilus(EditorInterface, Shell):
|
|
2591
2593
|
"""Nautilus in the Shell.
|
|
2592
2594
|
|
|
2593
2595
|
Facade objects for accessing the APIs:
|
|
@@ -2624,8 +2626,8 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
2624
2626
|
|
|
2625
2627
|
C-up : [0] retrieve previous history
|
|
2626
2628
|
C-down : [0] retrieve next history
|
|
2627
|
-
C-j, M-j : [0]
|
|
2628
|
-
C-h, M-h : [0]
|
|
2629
|
+
C-j, M-j : [0] tooltip of eval (for the selected or focused word)
|
|
2630
|
+
C-h, M-h : [0] calltip of help (for the selected or focused func)
|
|
2629
2631
|
TAB : [1] history-comp
|
|
2630
2632
|
M-p : [1] retrieve previous history in history-comp mode
|
|
2631
2633
|
M-n : [1] retrieve next history in history-comp mode
|
|
@@ -2697,7 +2699,9 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
2697
2699
|
raise TypeError("primitive objects cannot be targeted")
|
|
2698
2700
|
|
|
2699
2701
|
self.__target = obj
|
|
2700
|
-
self.
|
|
2702
|
+
self.locals = obj.__dict__
|
|
2703
|
+
self.globals = obj.__dict__
|
|
2704
|
+
self.globals.update(self.__globals)
|
|
2701
2705
|
try:
|
|
2702
2706
|
obj.self = obj
|
|
2703
2707
|
obj.this = inspect.getmodule(obj)
|
|
@@ -2730,9 +2734,9 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
2730
2734
|
@globals.deleter
|
|
2731
2735
|
def globals(self): # internal use only
|
|
2732
2736
|
self.interp.globals = self.__target.__dict__
|
|
2737
|
+
self.interp.globals.update(self.__globals)
|
|
2733
2738
|
|
|
2734
|
-
|
|
2735
|
-
wrap = EditorInterface.wrap
|
|
2739
|
+
__globals = {}
|
|
2736
2740
|
|
|
2737
2741
|
def __init__(self, parent, target, name="root",
|
|
2738
2742
|
introText=None,
|
|
@@ -2741,14 +2745,13 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
2741
2745
|
**kwargs):
|
|
2742
2746
|
Shell.__init__(self, parent,
|
|
2743
2747
|
locals=target.__dict__,
|
|
2744
|
-
interpShell=self,
|
|
2748
|
+
interpShell=self, # **kwds of InterpClass
|
|
2745
2749
|
InterpClass=Interpreter,
|
|
2746
2750
|
introText=introText,
|
|
2747
2751
|
startupScript=startupScript,
|
|
2748
|
-
execStartupScript=execStartupScript, #
|
|
2752
|
+
execStartupScript=execStartupScript, # executes ~/.py
|
|
2749
2753
|
**kwargs)
|
|
2750
2754
|
EditorInterface.__init__(self)
|
|
2751
|
-
AutoCompInterfaceMixin.__init__(self)
|
|
2752
2755
|
|
|
2753
2756
|
self.parent = parent #: parent<ShellFrame> is not Parent<AuiNotebook>
|
|
2754
2757
|
self.target = target
|
|
@@ -2780,28 +2783,20 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
2780
2783
|
def clear(evt):
|
|
2781
2784
|
## """Clear selection and message, no skip."""
|
|
2782
2785
|
## *do not* clear autocomp, so that the event can skip to AutoComp properly.
|
|
2783
|
-
## if self.AutoCompActive():
|
|
2784
|
-
## self.AutoCompCancel() # may delete selection
|
|
2785
2786
|
if self.CanEdit():
|
|
2786
|
-
self.
|
|
2787
|
+
with self.off_undocollection():
|
|
2788
|
+
self.ReplaceSelection("")
|
|
2787
2789
|
self.message("")
|
|
2788
2790
|
|
|
2789
2791
|
def clear_autocomp(evt):
|
|
2790
|
-
## """Clear
|
|
2792
|
+
## """Clear autocomp, selection, and message."""
|
|
2791
2793
|
if self.AutoCompActive():
|
|
2792
2794
|
self.AutoCompCancel()
|
|
2793
2795
|
if self.CanEdit():
|
|
2794
|
-
self.
|
|
2796
|
+
with self.off_undocollection():
|
|
2797
|
+
self.ReplaceSelection("")
|
|
2795
2798
|
self.message("")
|
|
2796
2799
|
|
|
2797
|
-
def skip_autocomp(evt):
|
|
2798
|
-
## """Don't eat backward prompt whitespace."""
|
|
2799
|
-
## Prevent autocomp from eating prompts.
|
|
2800
|
-
## Quit to avoid backspace over the last non-continuation prompt.
|
|
2801
|
-
if self.cpos == self.bolc:
|
|
2802
|
-
self.handler('quit', evt)
|
|
2803
|
-
evt.Skip()
|
|
2804
|
-
|
|
2805
2800
|
def fork(evt):
|
|
2806
2801
|
self.handler.fork(self.handler.current_event, evt)
|
|
2807
2802
|
|
|
@@ -2844,7 +2839,6 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
2844
2839
|
'C-enter pressed' : (0, _F(self.insertLineBreak)),
|
|
2845
2840
|
'C-S-enter pressed' : (0, _F(self.insertLineBreak)),
|
|
2846
2841
|
'*enter pressed' : (0, ), # -> OnShowCompHistory 無効
|
|
2847
|
-
'left pressed' : (0, self.OnBackspace),
|
|
2848
2842
|
'C-[ pressed' : (0, _F(self.goto_previous_mark_arrow)),
|
|
2849
2843
|
'C-S-[ pressed' : (0, _F(self.goto_previous_mark_arrow, selection=1)),
|
|
2850
2844
|
'C-] pressed' : (0, _F(self.goto_next_mark_arrow)),
|
|
@@ -2859,10 +2853,8 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
2859
2853
|
'C-S-insert pressed' : (0, _F(self.Paste, rectangle=1)),
|
|
2860
2854
|
'C-j pressed' : (0, self.eval_line),
|
|
2861
2855
|
'M-j pressed' : (0, self.exec_region),
|
|
2862
|
-
'C-S-j pressed' : (0, self.exec_region),
|
|
2863
2856
|
'C-h pressed' : (0, self.call_helpTip),
|
|
2864
2857
|
'M-h pressed' : (0, self.call_helpDoc),
|
|
2865
|
-
'C-S-h pressed' : (0, self.call_helpDoc),
|
|
2866
2858
|
'. pressed' : (2, self.OnEnterDot),
|
|
2867
2859
|
'tab pressed' : (1, self.call_history_comp),
|
|
2868
2860
|
'M-p pressed' : (1, self.call_history_comp),
|
|
@@ -2915,7 +2907,7 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
2915
2907
|
'S-[a-z\\] released' : (2, self.call_word_autocomp),
|
|
2916
2908
|
'\\ released' : (2, self.call_word_autocomp),
|
|
2917
2909
|
'*delete pressed' : (2, skip),
|
|
2918
|
-
'*backspace pressed' : (2,
|
|
2910
|
+
'*backspace pressed' : (2, self.OnBackspace),
|
|
2919
2911
|
'*backspace released' : (2, self.call_word_autocomp),
|
|
2920
2912
|
'C-S-backspace pressed' : (2, ),
|
|
2921
2913
|
'C-j pressed' : (2, self.eval_line),
|
|
@@ -2943,7 +2935,7 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
2943
2935
|
'S-[a-z\\] released' : (3, self.call_apropos_autocomp),
|
|
2944
2936
|
'\\ released' : (3, self.call_apropos_autocomp),
|
|
2945
2937
|
'*delete pressed' : (3, skip),
|
|
2946
|
-
'*backspace pressed' : (3,
|
|
2938
|
+
'*backspace pressed' : (3, self.OnBackspace),
|
|
2947
2939
|
'*backspace released' : (3, self.call_apropos_autocomp),
|
|
2948
2940
|
'C-S-backspace pressed' : (3, ),
|
|
2949
2941
|
'C-j pressed' : (3, self.eval_line),
|
|
@@ -2971,7 +2963,7 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
2971
2963
|
'S-[a-z\\] released' : (4, self.call_text_autocomp),
|
|
2972
2964
|
'\\ released' : (4, self.call_text_autocomp),
|
|
2973
2965
|
'*delete pressed' : (4, skip),
|
|
2974
|
-
'*backspace pressed' : (4,
|
|
2966
|
+
'*backspace pressed' : (4, self.OnBackspace),
|
|
2975
2967
|
'*backspace released' : (4, self.call_text_autocomp),
|
|
2976
2968
|
'C-S-backspace pressed' : (4, ),
|
|
2977
2969
|
'C-j pressed' : (4, self.eval_line),
|
|
@@ -3000,7 +2992,7 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
3000
2992
|
'\\ released' : (5, self.call_module_autocomp),
|
|
3001
2993
|
'M-m pressed' : (5, _F(self.call_module_autocomp, force=1)),
|
|
3002
2994
|
'*delete pressed' : (5, skip),
|
|
3003
|
-
'*backspace pressed' : (5,
|
|
2995
|
+
'*backspace pressed' : (5, self.OnBackspace),
|
|
3004
2996
|
'*backspace released' : (5, self.call_module_autocomp),
|
|
3005
2997
|
'C-S-backspace pressed' : (5, ),
|
|
3006
2998
|
'*alt pressed' : (5, ),
|
|
@@ -3076,12 +3068,11 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
3076
3068
|
evt.Skip()
|
|
3077
3069
|
|
|
3078
3070
|
def OnBackspace(self, evt):
|
|
3079
|
-
"""Called when backspace
|
|
3080
|
-
Backspace-guard from
|
|
3071
|
+
"""Called when backspace pressed.
|
|
3072
|
+
Backspace-guard from autocomp eating over a prompt whitespace.
|
|
3081
3073
|
"""
|
|
3082
3074
|
if self.cpos == self.bolc:
|
|
3083
|
-
|
|
3084
|
-
## so not to backspace over the latest non-continuation prompt
|
|
3075
|
+
self.handler('quit', evt) # don't eat backward prompt
|
|
3085
3076
|
return
|
|
3086
3077
|
evt.Skip()
|
|
3087
3078
|
|
|
@@ -3153,7 +3144,7 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
3153
3144
|
self.ReplaceSelection('self')
|
|
3154
3145
|
elif st not in ('moji', 'word', 'rparen') or rst == 'word':
|
|
3155
3146
|
self.handler('quit', evt) # don't enter autocomp
|
|
3156
|
-
|
|
3147
|
+
evt.Skip()
|
|
3157
3148
|
|
|
3158
3149
|
def on_enter_escmap(self, evt):
|
|
3159
3150
|
self.__caret_mode = self.CaretPeriod
|
|
@@ -3203,7 +3194,7 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
3203
3194
|
def magic(self, cmd):
|
|
3204
3195
|
"""Called before command pushed.
|
|
3205
3196
|
|
|
3206
|
-
(override)
|
|
3197
|
+
(override) Disable old magic: `f x --> f(x)`.
|
|
3207
3198
|
"""
|
|
3208
3199
|
if cmd:
|
|
3209
3200
|
if cmd[0:2] == '??': cmd = 'help({})'.format(cmd[2:])
|
|
@@ -3461,7 +3452,7 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
3461
3452
|
(override) Add globals when executing su:startupScript.
|
|
3462
3453
|
Fix history point.
|
|
3463
3454
|
"""
|
|
3464
|
-
|
|
3455
|
+
keys = set(self.locals.keys()) # check for locals map changes
|
|
3465
3456
|
self.promptPosEnd = self.TextLength # fix history point
|
|
3466
3457
|
if su and os.path.isfile(su):
|
|
3467
3458
|
self.push("print('Startup script executed:', {0!r})\n".format(su))
|
|
@@ -3471,6 +3462,7 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
3471
3462
|
else:
|
|
3472
3463
|
self.push("")
|
|
3473
3464
|
self.interp.startupScript = None
|
|
3465
|
+
self.__globals = {k: self.locals[k] for k in (self.locals.keys() - keys)}
|
|
3474
3466
|
|
|
3475
3467
|
def Paste(self, rectangle=False):
|
|
3476
3468
|
"""Replace selection with clipboard contents.
|
|
@@ -3616,9 +3608,22 @@ class Nautilus(AutoCompInterfaceMixin, EditorInterface, Shell):
|
|
|
3616
3608
|
self.cpos, self.anchor = self.anchor, self.cpos
|
|
3617
3609
|
self.EnsureCaretVisible()
|
|
3618
3610
|
|
|
3619
|
-
def
|
|
3620
|
-
"""
|
|
3611
|
+
def gen_text_at_caret(self):
|
|
3612
|
+
"""Generates the selected text,
|
|
3613
|
+
otherwise the line or expression at the caret.
|
|
3614
|
+
(override) Generates command line (that starts with a prompt).
|
|
3621
3615
|
"""
|
|
3616
|
+
def _gen_text():
|
|
3617
|
+
text = self.SelectedText
|
|
3618
|
+
if text:
|
|
3619
|
+
yield text
|
|
3620
|
+
else:
|
|
3621
|
+
yield self.getCommand() # self.line_at_caret
|
|
3622
|
+
yield self.expr_at_caret
|
|
3623
|
+
return filter(None, _gen_text())
|
|
3624
|
+
|
|
3625
|
+
def eval_line(self, evt):
|
|
3626
|
+
"""Evaluate the selected word or line."""
|
|
3622
3627
|
if self.CallTipActive():
|
|
3623
3628
|
self.CallTipCancel()
|
|
3624
3629
|
|
mwx/plugins/ffmpeg_view.py
CHANGED
|
@@ -122,7 +122,7 @@ class Plugin(Layer):
|
|
|
122
122
|
(1, "&Load file", Icon('open'),
|
|
123
123
|
lambda v: self.load_media()),
|
|
124
124
|
|
|
125
|
-
(2, "&Snapshot", Icon('
|
|
125
|
+
(2, "&Snapshot", Icon('clip'),
|
|
126
126
|
lambda v: self.snapshot(),
|
|
127
127
|
lambda v: v.Enable(self._path is not None)),
|
|
128
128
|
(),
|
|
@@ -175,7 +175,7 @@ class Plugin(Layer):
|
|
|
175
175
|
def load_media(self, path=None):
|
|
176
176
|
if path is None:
|
|
177
177
|
with wx.FileDialog(self, "Choose a media file",
|
|
178
|
-
|
|
178
|
+
style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST) as dlg:
|
|
179
179
|
if dlg.ShowModal() != wx.ID_OK:
|
|
180
180
|
return None
|
|
181
181
|
path = dlg.Path
|