mwxlib 1.6.10__py3-none-any.whl → 1.7.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/bookshelf.py +26 -22
- mwx/controls.py +142 -143
- mwx/framework.py +105 -105
- mwx/graphman.py +85 -85
- mwx/matplot2.py +82 -81
- mwx/matplot2g.py +165 -165
- mwx/matplot2lg.py +57 -57
- mwx/mgplt.py +12 -12
- mwx/nutshell.py +305 -287
- mwx/plugins/ffmpeg_view.py +15 -15
- mwx/plugins/fft_view.py +4 -4
- mwx/plugins/frame_listview.py +26 -26
- mwx/plugins/line_profile.py +1 -1
- mwx/utilus.py +40 -40
- mwx/wxmon.py +20 -20
- mwx/wxpdb.py +45 -45
- mwx/wxwil.py +11 -11
- mwx/wxwit.py +15 -15
- {mwxlib-1.6.10.dist-info → mwxlib-1.7.0.dist-info}/METADATA +1 -1
- mwxlib-1.7.0.dist-info/RECORD +28 -0
- mwxlib-1.6.10.dist-info/RECORD +0 -28
- {mwxlib-1.6.10.dist-info → mwxlib-1.7.0.dist-info}/WHEEL +0 -0
- {mwxlib-1.6.10.dist-info → mwxlib-1.7.0.dist-info}/top_level.txt +0 -0
mwx/nutshell.py
CHANGED
|
@@ -181,14 +181,14 @@ class AutoCompInterfaceMixin:
|
|
|
181
181
|
history = [] # used in history-comp mode
|
|
182
182
|
modules = set() # used in module-comp mode
|
|
183
183
|
fragmwords = set(keyword.kwlist + dir(builtins)) # used in text-comp mode
|
|
184
|
-
|
|
184
|
+
|
|
185
185
|
def __init__(self):
|
|
186
186
|
## cf. sys.modules
|
|
187
187
|
if not self.modules:
|
|
188
188
|
force = wx.GetKeyState(wx.WXK_CONTROL)\
|
|
189
189
|
& wx.GetKeyState(wx.WXK_SHIFT)
|
|
190
190
|
AutoCompInterfaceMixin.modules = set(find_modules(force))
|
|
191
|
-
|
|
191
|
+
|
|
192
192
|
def CallTipShow(self, pos, tip, N=11):
|
|
193
193
|
"""Show a call tip containing a definition near position pos.
|
|
194
194
|
|
|
@@ -203,7 +203,7 @@ class AutoCompInterfaceMixin:
|
|
|
203
203
|
tip = '\n'.join(lines)
|
|
204
204
|
self._calltips[-1] = True # snipped (needs to be shown)
|
|
205
205
|
super().CallTipShow(pos, tip)
|
|
206
|
-
|
|
206
|
+
|
|
207
207
|
def autoCallTipShow(self, command, insertcalltip=True):
|
|
208
208
|
"""Display argument spec and docstring in a popup window.
|
|
209
209
|
|
|
@@ -223,7 +223,7 @@ class AutoCompInterfaceMixin:
|
|
|
223
223
|
## In case there isn't enough room, only go back to bol fallback.
|
|
224
224
|
tippos = max(self.bol, p - len(name) - 1)
|
|
225
225
|
self.CallTipShow(tippos, tip)
|
|
226
|
-
|
|
226
|
+
|
|
227
227
|
def call_helpDoc(self, evt):
|
|
228
228
|
"""Show help:str for the selected topic."""
|
|
229
229
|
if self.CallTipActive():
|
|
@@ -237,7 +237,7 @@ class AutoCompInterfaceMixin:
|
|
|
237
237
|
self.help(obj)
|
|
238
238
|
except Exception as e:
|
|
239
239
|
self.message(e)
|
|
240
|
-
|
|
240
|
+
|
|
241
241
|
def call_helpTip(self, evt):
|
|
242
242
|
"""Show a calltip for the selected function."""
|
|
243
243
|
if self.CallTipActive():
|
|
@@ -248,19 +248,19 @@ class AutoCompInterfaceMixin:
|
|
|
248
248
|
p = self.cpos
|
|
249
249
|
self.autoCallTipShow(text,
|
|
250
250
|
p == self.eol and self.get_char(p-1) == '(') # => CallTipShow
|
|
251
|
-
|
|
251
|
+
|
|
252
252
|
def on_completion_forward(self, evt):
|
|
253
253
|
if not self.AutoCompActive():
|
|
254
254
|
self.handler('quit', evt)
|
|
255
255
|
return
|
|
256
256
|
self._on_completion(1)
|
|
257
|
-
|
|
257
|
+
|
|
258
258
|
def on_completion_backward(self, evt):
|
|
259
259
|
if not self.AutoCompActive():
|
|
260
260
|
self.handler('quit', evt)
|
|
261
261
|
return
|
|
262
262
|
self._on_completion(-1)
|
|
263
|
-
|
|
263
|
+
|
|
264
264
|
def _on_completion(self, step=0):
|
|
265
265
|
"""Show completion with selection."""
|
|
266
266
|
try:
|
|
@@ -280,7 +280,7 @@ class AutoCompInterfaceMixin:
|
|
|
280
280
|
self.__comp_ind = j
|
|
281
281
|
except IndexError:
|
|
282
282
|
self.message("No completion words")
|
|
283
|
-
|
|
283
|
+
|
|
284
284
|
def _gen_autocomp(self, j, hint, words, sep=' ', mode=True):
|
|
285
285
|
## Prepare on_completion_forward/backward
|
|
286
286
|
self.__comp_ind = j
|
|
@@ -292,7 +292,7 @@ class AutoCompInterfaceMixin:
|
|
|
292
292
|
elif words:
|
|
293
293
|
self.AutoCompSetSeparator(ord(sep))
|
|
294
294
|
self.AutoCompShow(len(hint), sep.join(words))
|
|
295
|
-
|
|
295
|
+
|
|
296
296
|
def _get_words_hint(self):
|
|
297
297
|
cmdl = self.GetTextRange(self.bol, self.cpos)
|
|
298
298
|
if cmdl.endswith(' '): # 前の文字が空白の場合はスキップする
|
|
@@ -300,12 +300,12 @@ class AutoCompInterfaceMixin:
|
|
|
300
300
|
else:
|
|
301
301
|
text = next(split_words(cmdl, reverse=1), '')
|
|
302
302
|
return text.rpartition('.') # -> text, sep, hint
|
|
303
|
-
|
|
303
|
+
|
|
304
304
|
def clear_autocomp(self, evt):
|
|
305
305
|
if self.AutoCompActive():
|
|
306
306
|
self.AutoCompCancel()
|
|
307
307
|
self.message("")
|
|
308
|
-
|
|
308
|
+
|
|
309
309
|
def call_history_comp(self, evt):
|
|
310
310
|
"""Called when history-comp mode."""
|
|
311
311
|
if not self.CanEdit():
|
|
@@ -326,7 +326,7 @@ class AutoCompInterfaceMixin:
|
|
|
326
326
|
self._gen_autocomp(0, hint, words, mode=False)
|
|
327
327
|
self.message("[history] {} candidates matched"
|
|
328
328
|
" with {!r}".format(len(words), hint))
|
|
329
|
-
|
|
329
|
+
|
|
330
330
|
def call_text_autocomp(self, evt):
|
|
331
331
|
"""Called when text-comp mode."""
|
|
332
332
|
if not self.CanEdit():
|
|
@@ -344,7 +344,7 @@ class AutoCompInterfaceMixin:
|
|
|
344
344
|
self._gen_autocomp(0, hint, words)
|
|
345
345
|
self.message("[text] {} candidates matched"
|
|
346
346
|
" with {!r}".format(len(words), hint))
|
|
347
|
-
|
|
347
|
+
|
|
348
348
|
def call_module_autocomp(self, evt, force=False):
|
|
349
349
|
"""Called when module-comp mode."""
|
|
350
350
|
if not self.CanEdit():
|
|
@@ -412,7 +412,7 @@ class AutoCompInterfaceMixin:
|
|
|
412
412
|
self.message("- {} : {!r}".format(e, text))
|
|
413
413
|
except Exception as e:
|
|
414
414
|
self.message("- {} : {!r}".format(e, text))
|
|
415
|
-
|
|
415
|
+
|
|
416
416
|
def call_word_autocomp(self, evt):
|
|
417
417
|
"""Called when word-comp mode."""
|
|
418
418
|
if not self.CanEdit():
|
|
@@ -425,7 +425,7 @@ class AutoCompInterfaceMixin:
|
|
|
425
425
|
self.message("- No autocompletion candidates or hints found.")
|
|
426
426
|
return
|
|
427
427
|
try:
|
|
428
|
-
## dir = introspect.getAttributeNames @TODO in wx ver 4.2.3
|
|
428
|
+
## dir = introspect.getAttributeNames # @TODO in wx ver 4.2.3
|
|
429
429
|
obj = self.eval(text)
|
|
430
430
|
P = re.compile(hint)
|
|
431
431
|
p = re.compile(hint, re.I)
|
|
@@ -444,7 +444,7 @@ class AutoCompInterfaceMixin:
|
|
|
444
444
|
self.message("- {} : {!r}".format(e, text))
|
|
445
445
|
except Exception as e:
|
|
446
446
|
self.message("- {} : {!r}".format(e, text))
|
|
447
|
-
|
|
447
|
+
|
|
448
448
|
def call_apropos_autocomp(self, evt):
|
|
449
449
|
"""Called when apropos mode."""
|
|
450
450
|
if not self.CanEdit():
|
|
@@ -457,7 +457,7 @@ class AutoCompInterfaceMixin:
|
|
|
457
457
|
self.message("- No autocompletion candidates or hints found.")
|
|
458
458
|
return
|
|
459
459
|
try:
|
|
460
|
-
## dir = introspect.getAttributeNames @TODO in wx ver 4.2.3.
|
|
460
|
+
## dir = introspect.getAttributeNames # @TODO in wx ver 4.2.3.
|
|
461
461
|
obj = self.eval(text)
|
|
462
462
|
P = re.compile(hint)
|
|
463
463
|
p = re.compile(hint, re.I)
|
|
@@ -524,7 +524,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
524
524
|
## 'C-S-l pressed' : (0, _F(self.recenter)), # overrides delete-line
|
|
525
525
|
## 'C-S-f pressed' : (0, _F(self.set_mark)), # overrides mark
|
|
526
526
|
'C-space pressed' : (0, _F(self.set_mark)),
|
|
527
|
-
'C-S-space pressed' : (0, _F(self.
|
|
527
|
+
'C-S-space pressed' : (0, _F(self.toggle_pointer)),
|
|
528
528
|
'C-backspace pressed' : (0, _F(self.backward_kill_word)),
|
|
529
529
|
'S-backspace pressed' : (0, _F(self.backward_kill_line)),
|
|
530
530
|
'C-delete pressed' : (0, _F(self.kill_word)),
|
|
@@ -699,16 +699,16 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
699
699
|
|
|
700
700
|
self.__mark = -1
|
|
701
701
|
self.__stylus = {}
|
|
702
|
-
|
|
702
|
+
|
|
703
703
|
__dnd_flag = 0
|
|
704
|
-
|
|
704
|
+
|
|
705
705
|
def OnDrag(self, evt): #<wx._core.StyledTextEvent>
|
|
706
706
|
if isinstance(self, Shell):
|
|
707
707
|
EditorInterface.__dnd_flag = (evt.Position < self.bolc) # readonly
|
|
708
708
|
else:
|
|
709
709
|
EditorInterface.__dnd_flag = 0
|
|
710
710
|
evt.Skip()
|
|
711
|
-
|
|
711
|
+
|
|
712
712
|
def OnDragging(self, evt): #<wx._core.StyledTextEvent>
|
|
713
713
|
if isinstance(self, Shell):
|
|
714
714
|
if evt.Position < self.bolc: # target is readonly
|
|
@@ -721,11 +721,11 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
721
721
|
## from shell to buffer
|
|
722
722
|
evt.DragResult = wx.DragCopy if wx.GetKeyState(wx.WXK_CONTROL) else wx.DragNone
|
|
723
723
|
evt.Skip()
|
|
724
|
-
|
|
724
|
+
|
|
725
725
|
def OnDragged(self, evt): #<wx._core.StyledTextEvent>
|
|
726
726
|
EditorInterface.__dnd_flag = 0
|
|
727
727
|
evt.Skip()
|
|
728
|
-
|
|
728
|
+
|
|
729
729
|
## --------------------------------
|
|
730
730
|
## Marker attributes of the editor
|
|
731
731
|
## --------------------------------
|
|
@@ -736,86 +736,90 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
736
736
|
3: "pointer",
|
|
737
737
|
4: "red-pointer",
|
|
738
738
|
}
|
|
739
|
-
|
|
739
|
+
|
|
740
740
|
def get_marker(self, n):
|
|
741
741
|
return self.MarkerNext(0, 1<<n)
|
|
742
|
-
|
|
742
|
+
|
|
743
743
|
def set_marker(self, line, n):
|
|
744
744
|
if line != -1:
|
|
745
745
|
self.MarkerDeleteAll(n)
|
|
746
746
|
self.add_marker(line, n)
|
|
747
747
|
else:
|
|
748
748
|
self.del_marker(n)
|
|
749
|
-
|
|
749
|
+
|
|
750
750
|
def add_marker(self, line, n):
|
|
751
751
|
if self.MarkerAdd(line, n):
|
|
752
752
|
self.EnsureVisible(line) # expand if folded
|
|
753
753
|
self.handler('{}_set'.format(self.marker_names[n]), line)
|
|
754
|
-
|
|
754
|
+
|
|
755
755
|
def del_marker(self, n):
|
|
756
756
|
line = self.MarkerNext(0, 1<<n)
|
|
757
757
|
if line != -1:
|
|
758
758
|
self.MarkerDeleteAll(n)
|
|
759
759
|
self.handler('{}_unset'.format(self.marker_names[n]), line)
|
|
760
|
-
|
|
760
|
+
|
|
761
761
|
def goto_marker(self, markerMask, selection=False):
|
|
762
762
|
line = self.MarkerNext(0, markerMask)
|
|
763
763
|
if line != -1:
|
|
764
764
|
self.EnsureVisible(line) # expand if folded
|
|
765
765
|
self.goto_line(line, selection)
|
|
766
766
|
self.recenter()
|
|
767
|
-
|
|
767
|
+
|
|
768
768
|
def goto_next_marker(self, markerMask, selection=False):
|
|
769
769
|
line = self.MarkerNext(self.cline+1, markerMask)
|
|
770
770
|
if line == -1:
|
|
771
771
|
line = self.LineCount
|
|
772
772
|
self.goto_line(line, selection)
|
|
773
|
-
|
|
773
|
+
|
|
774
774
|
def goto_previous_marker(self, markerMask, selection=False):
|
|
775
775
|
line = self.MarkerPrevious(self.cline-1, markerMask)
|
|
776
776
|
if line == -1:
|
|
777
777
|
line = 0
|
|
778
778
|
self.goto_line(line, selection)
|
|
779
|
-
|
|
779
|
+
|
|
780
780
|
white_arrow = property(
|
|
781
781
|
lambda self: self.get_marker(1),
|
|
782
782
|
lambda self, v: self.set_marker(v, 1), # [arrow_set]
|
|
783
|
-
lambda self: self.del_marker(1)
|
|
784
|
-
|
|
783
|
+
lambda self: self.del_marker(1), # [arrow_unset]
|
|
784
|
+
doc="Arrow marker used to indicate success.")
|
|
785
|
+
|
|
785
786
|
red_arrow = property(
|
|
786
787
|
lambda self: self.get_marker(2),
|
|
787
788
|
lambda self, v: self.set_marker(v, 2), # [red-arrow_set]
|
|
788
|
-
lambda self: self.del_marker(2)
|
|
789
|
-
|
|
789
|
+
lambda self: self.del_marker(2), # [red-arrow_unset]
|
|
790
|
+
doc="Arrow marker used to indicate failure.")
|
|
791
|
+
|
|
790
792
|
pointer = property(
|
|
791
793
|
lambda self: self.get_marker(3),
|
|
792
794
|
lambda self, v: self.set_marker(v, 3), # [pointer_set]
|
|
793
|
-
lambda self: self.del_marker(3)
|
|
794
|
-
|
|
795
|
+
lambda self: self.del_marker(3), # [pointer_unset]
|
|
796
|
+
doc="Arrow marker used to indicate breakpoint.")
|
|
797
|
+
|
|
795
798
|
red_pointer = property(
|
|
796
799
|
lambda self: self.get_marker(4),
|
|
797
800
|
lambda self, v: self.set_marker(v, 4), # [red-pointer_set]
|
|
798
|
-
lambda self: self.del_marker(4)
|
|
799
|
-
|
|
801
|
+
lambda self: self.del_marker(4), # [red-pointer_unset]
|
|
802
|
+
doc="Arrow marker used to indicate exception.")
|
|
803
|
+
|
|
800
804
|
@property
|
|
801
805
|
def markline(self):
|
|
802
806
|
return self.MarkerNext(0, 1<<0)
|
|
803
|
-
|
|
807
|
+
|
|
804
808
|
@markline.setter
|
|
805
809
|
def markline(self, v):
|
|
806
810
|
if v != -1:
|
|
807
|
-
self.mark = self.PositionFromLine(v)
|
|
811
|
+
self.mark = self.PositionFromLine(v) # [mark_set]
|
|
808
812
|
else:
|
|
809
813
|
del self.mark # [mark_unset]
|
|
810
|
-
|
|
814
|
+
|
|
811
815
|
@markline.deleter
|
|
812
816
|
def markline(self):
|
|
813
817
|
del self.mark
|
|
814
|
-
|
|
818
|
+
|
|
815
819
|
@property
|
|
816
820
|
def mark(self):
|
|
817
821
|
return self.__mark
|
|
818
|
-
|
|
822
|
+
|
|
819
823
|
@mark.setter
|
|
820
824
|
def mark(self, v):
|
|
821
825
|
if v != -1:
|
|
@@ -824,24 +828,24 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
824
828
|
self.set_marker(ln, 0) # [mark_set]
|
|
825
829
|
else:
|
|
826
830
|
del self.mark
|
|
827
|
-
|
|
831
|
+
|
|
828
832
|
@mark.deleter
|
|
829
833
|
def mark(self):
|
|
830
834
|
v = self.__mark
|
|
831
835
|
if v != -1:
|
|
832
836
|
self.__mark = -1
|
|
833
837
|
self.del_marker(0) # [mark_unset]
|
|
834
|
-
|
|
838
|
+
|
|
835
839
|
def set_mark(self):
|
|
836
840
|
self.mark = self.cpos
|
|
837
|
-
|
|
838
|
-
def
|
|
841
|
+
|
|
842
|
+
def toggle_pointer(self):
|
|
839
843
|
if self.pointer == self.cline: # toggle
|
|
840
844
|
self.pointer = -1
|
|
841
845
|
else:
|
|
842
846
|
self.pointer = self.cline # reset
|
|
843
847
|
self.red_pointer = -1
|
|
844
|
-
|
|
848
|
+
|
|
845
849
|
def exchange_point_and_mark(self):
|
|
846
850
|
p = self.cpos
|
|
847
851
|
q = self.mark
|
|
@@ -851,7 +855,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
851
855
|
self.mark = p
|
|
852
856
|
else:
|
|
853
857
|
self.message("No marks")
|
|
854
|
-
|
|
858
|
+
|
|
855
859
|
## --------------------------------
|
|
856
860
|
## Attributes of the editor
|
|
857
861
|
## --------------------------------
|
|
@@ -873,7 +877,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
873
877
|
stc.STC_P_CLASSNAME : 'class',
|
|
874
878
|
stc.STC_P_DEFNAME : 'def',
|
|
875
879
|
}
|
|
876
|
-
|
|
880
|
+
|
|
877
881
|
def get_style(self, pos):
|
|
878
882
|
c = self.get_char(pos)
|
|
879
883
|
st = self.GetStyleAt(pos)
|
|
@@ -890,11 +894,11 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
890
894
|
if c in "({[": return 'lparen'
|
|
891
895
|
if c in ")}]": return 'rparen'
|
|
892
896
|
return sty
|
|
893
|
-
|
|
897
|
+
|
|
894
898
|
def get_char(self, pos):
|
|
895
899
|
"""Return the character at the given position."""
|
|
896
900
|
return chr(self.GetCharAt(pos))
|
|
897
|
-
|
|
901
|
+
|
|
898
902
|
def get_text(self, start, end):
|
|
899
903
|
"""Retrieve a range of text.
|
|
900
904
|
|
|
@@ -906,37 +910,40 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
906
910
|
p = max(start, 0)
|
|
907
911
|
q = min(end, self.TextLength)
|
|
908
912
|
return self.GetTextRange(p, q)
|
|
909
|
-
|
|
913
|
+
|
|
910
914
|
anchor = property(
|
|
911
915
|
lambda self: self.GetAnchor(),
|
|
912
|
-
lambda self, v: self.SetAnchor(v)
|
|
913
|
-
|
|
916
|
+
lambda self, v: self.SetAnchor(v),
|
|
917
|
+
doc="Position of the opposite end of the selection to the caret.")
|
|
918
|
+
|
|
914
919
|
cpos = property(
|
|
915
920
|
lambda self: self.GetCurrentPos(),
|
|
916
|
-
lambda self, v: self.SetCurrentPos(v)
|
|
917
|
-
|
|
921
|
+
lambda self, v: self.SetCurrentPos(v),
|
|
922
|
+
doc="Position of the caret.")
|
|
923
|
+
|
|
918
924
|
cline = property(
|
|
919
925
|
lambda self: self.GetCurrentLine(),
|
|
920
|
-
lambda self, v: self.SetCurrentPos(self.PositionFromLine(v))
|
|
921
|
-
|
|
926
|
+
lambda self, v: self.SetCurrentPos(self.PositionFromLine(v)),
|
|
927
|
+
doc="Line number of the line with the caret.")
|
|
928
|
+
|
|
922
929
|
@property
|
|
923
930
|
def bol(self):
|
|
924
931
|
"""Beginning of line."""
|
|
925
932
|
text, lp = self.CurLine
|
|
926
933
|
return self.cpos - lp
|
|
927
|
-
|
|
934
|
+
|
|
928
935
|
@property
|
|
929
936
|
def eol(self):
|
|
930
937
|
"""End of line."""
|
|
931
938
|
text, lp = self.CurLine
|
|
932
939
|
text = text.strip('\r\n') # remove linesep: '\r' and '\n'
|
|
933
940
|
return (self.cpos - lp + len(text.encode()))
|
|
934
|
-
|
|
941
|
+
|
|
935
942
|
@property
|
|
936
943
|
def line_at_caret(self):
|
|
937
944
|
"""Text of the range (bol, eol) at the caret-line."""
|
|
938
945
|
return self.GetTextRange(self.bol, self.eol)
|
|
939
|
-
|
|
946
|
+
|
|
940
947
|
@property
|
|
941
948
|
def expr_at_caret(self):
|
|
942
949
|
"""A syntax unit (expression) at the caret-line."""
|
|
@@ -962,7 +969,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
962
969
|
if sty not in styles:
|
|
963
970
|
break
|
|
964
971
|
return self.GetTextRange(start, end).strip()
|
|
965
|
-
|
|
972
|
+
|
|
966
973
|
@property
|
|
967
974
|
def topic_at_caret(self):
|
|
968
975
|
"""Topic word at the caret or selected substring.
|
|
@@ -982,23 +989,23 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
982
989
|
self.WordRightEnd()
|
|
983
990
|
q = self.cpos
|
|
984
991
|
return self.GetTextRange(p, q)
|
|
985
|
-
|
|
992
|
+
|
|
986
993
|
## --------------------------------
|
|
987
994
|
## Python syntax and indentation
|
|
988
995
|
## --------------------------------
|
|
989
|
-
|
|
996
|
+
|
|
990
997
|
def on_indent_line(self, evt):
|
|
991
998
|
if self.SelectedText:
|
|
992
999
|
evt.Skip()
|
|
993
1000
|
else:
|
|
994
1001
|
self.py_indent_line()
|
|
995
|
-
|
|
1002
|
+
|
|
996
1003
|
def on_outdent_line(self, evt):
|
|
997
1004
|
if self.SelectedText:
|
|
998
1005
|
evt.Skip()
|
|
999
1006
|
else:
|
|
1000
1007
|
self.py_outdent_line()
|
|
1001
|
-
|
|
1008
|
+
|
|
1002
1009
|
@editable
|
|
1003
1010
|
def py_indent_line(self):
|
|
1004
1011
|
"""Indent the current line."""
|
|
@@ -1010,7 +1017,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1010
1017
|
if indent >= 0:
|
|
1011
1018
|
self.Replace(self.bol, p, ' '*indent)
|
|
1012
1019
|
self.goto_char(self.bol + indent + offset)
|
|
1013
|
-
|
|
1020
|
+
|
|
1014
1021
|
@editable
|
|
1015
1022
|
def py_outdent_line(self):
|
|
1016
1023
|
"""Outdent the current line."""
|
|
@@ -1022,7 +1029,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1022
1029
|
if indent >= 0:
|
|
1023
1030
|
self.Replace(self.bol, p, ' '*indent)
|
|
1024
1031
|
self.goto_char(self.bol + indent + offset)
|
|
1025
|
-
|
|
1032
|
+
|
|
1026
1033
|
def py_current_indent(self):
|
|
1027
1034
|
"""Calculate indent spaces from previous line."""
|
|
1028
1035
|
text = self.GetLine(self.cline - 1)
|
|
@@ -1032,7 +1039,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1032
1039
|
if re.match(py_outdent_re, lstr):
|
|
1033
1040
|
indent -= 4
|
|
1034
1041
|
return indent
|
|
1035
|
-
|
|
1042
|
+
|
|
1036
1043
|
def py_electric_indent(self):
|
|
1037
1044
|
"""Calculate indent spaces for the following line."""
|
|
1038
1045
|
## [BUG ver 4.2.0] The last char is replaced with b'\x00'.
|
|
@@ -1040,7 +1047,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1040
1047
|
## return self.py_calc_indentation(text[:lp].decode())
|
|
1041
1048
|
text, lp = self.CurLine
|
|
1042
1049
|
return self.py_calc_indentation(text[:lp])
|
|
1043
|
-
|
|
1050
|
+
|
|
1044
1051
|
@classmethod
|
|
1045
1052
|
def py_calc_indentation(self, text):
|
|
1046
1053
|
"""Return indent spaces for the command text."""
|
|
@@ -1054,7 +1061,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1054
1061
|
if re.match(py_closing_re, lstr):
|
|
1055
1062
|
return indent - 4
|
|
1056
1063
|
return indent
|
|
1057
|
-
|
|
1064
|
+
|
|
1058
1065
|
@classmethod
|
|
1059
1066
|
def py_strip_indents(self, text):
|
|
1060
1067
|
"""Return left-stripped text and the number of indent spaces."""
|
|
@@ -1062,7 +1069,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1062
1069
|
lstr = text.lstrip(' \t')
|
|
1063
1070
|
indent = len(text) - len(lstr)
|
|
1064
1071
|
return lstr, indent
|
|
1065
|
-
|
|
1072
|
+
|
|
1066
1073
|
@classmethod
|
|
1067
1074
|
def py_strip_prompts(self, text):
|
|
1068
1075
|
"""Return text without a leading prompt."""
|
|
@@ -1071,16 +1078,16 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1071
1078
|
text = text[len(ps):]
|
|
1072
1079
|
break
|
|
1073
1080
|
return text
|
|
1074
|
-
|
|
1081
|
+
|
|
1075
1082
|
@classmethod
|
|
1076
1083
|
def py_strip_comments(self, text):
|
|
1077
1084
|
"""Return text without comments."""
|
|
1078
1085
|
return ''.join(split_tokens(text, comment=False))
|
|
1079
|
-
|
|
1086
|
+
|
|
1080
1087
|
## --------------------------------
|
|
1081
1088
|
## Fold / Unfold functions
|
|
1082
1089
|
## --------------------------------
|
|
1083
|
-
|
|
1090
|
+
|
|
1084
1091
|
def show_folder(self, show=True):
|
|
1085
1092
|
"""Show folder margin.
|
|
1086
1093
|
|
|
@@ -1102,7 +1109,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1102
1109
|
self.SetMarginSensitive(2, False)
|
|
1103
1110
|
self.SetFoldMarginColour(True, 'black')
|
|
1104
1111
|
self.SetFoldMarginHiColour(True, 'black')
|
|
1105
|
-
|
|
1112
|
+
|
|
1106
1113
|
def OnMarginClick(self, evt): #<wx._stc.StyledTextEvent>
|
|
1107
1114
|
lc = self.LineFromPosition(evt.Position)
|
|
1108
1115
|
level = self.GetFoldLevel(lc) ^ stc.STC_FOLDLEVELBASE
|
|
@@ -1114,7 +1121,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1114
1121
|
self.handler('select_lines', evt)
|
|
1115
1122
|
else:
|
|
1116
1123
|
self.handler('select_line', evt)
|
|
1117
|
-
|
|
1124
|
+
|
|
1118
1125
|
def OnMarginRClick(self, evt): #<wx._stc.StyledTextEvent>
|
|
1119
1126
|
"""Popup context menu."""
|
|
1120
1127
|
def _Icon(key):
|
|
@@ -1127,7 +1134,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1127
1134
|
(wx.ID_UP, "&Expand ALL", _Icon(wx.ART_PLUS),
|
|
1128
1135
|
lambda v: self.FoldAll(1)),
|
|
1129
1136
|
])
|
|
1130
|
-
|
|
1137
|
+
|
|
1131
1138
|
def toggle_fold(self, lc):
|
|
1132
1139
|
"""Similar to ToggleFold, but the top header containing
|
|
1133
1140
|
the specified line switches between expanded and contracted.
|
|
@@ -1140,7 +1147,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1140
1147
|
self.ToggleFold(lc)
|
|
1141
1148
|
self.ensureLineOnScreen(lc)
|
|
1142
1149
|
return lc
|
|
1143
|
-
|
|
1150
|
+
|
|
1144
1151
|
def get_indent_region(self, line):
|
|
1145
1152
|
"""Line numbers of folding head and tail containing the line."""
|
|
1146
1153
|
lc = line
|
|
@@ -1156,38 +1163,38 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1156
1163
|
break
|
|
1157
1164
|
le += 1
|
|
1158
1165
|
return lc, le
|
|
1159
|
-
|
|
1166
|
+
|
|
1160
1167
|
def on_linesel_begin(self, evt):
|
|
1161
1168
|
"""Called when a line of text selection begins."""
|
|
1162
1169
|
self.cpos = self.anchor = evt.Position #<select_line>
|
|
1163
1170
|
self.CaptureMouse()
|
|
1164
1171
|
evt.Skip()
|
|
1165
|
-
|
|
1172
|
+
|
|
1166
1173
|
def on_linesel_next(self, evt):
|
|
1167
1174
|
"""Called when next line of text selection begins."""
|
|
1168
1175
|
self.cpos = evt.Position #<select_lines>
|
|
1169
1176
|
self.CaptureMouse()
|
|
1170
1177
|
evt.Skip()
|
|
1171
|
-
|
|
1178
|
+
|
|
1172
1179
|
def on_linesel_motion(self, evt):
|
|
1173
1180
|
"""Called when a line of text selection is changing."""
|
|
1174
1181
|
self.cpos = self.PositionFromPoint(evt.Position)
|
|
1175
1182
|
self.EnsureCaretVisible()
|
|
1176
1183
|
evt.Skip()
|
|
1177
|
-
|
|
1184
|
+
|
|
1178
1185
|
def on_linesel_end(self, evt):
|
|
1179
1186
|
"""Called when a line of text selection ends."""
|
|
1180
1187
|
if self.HasCapture():
|
|
1181
1188
|
self.ReleaseMouse()
|
|
1182
1189
|
evt.Skip()
|
|
1183
|
-
|
|
1190
|
+
|
|
1184
1191
|
## --------------------------------
|
|
1185
1192
|
## Preferences / Appearance
|
|
1186
1193
|
## --------------------------------
|
|
1187
|
-
|
|
1194
|
+
|
|
1188
1195
|
def get_stylus(self):
|
|
1189
1196
|
return self.__stylus
|
|
1190
|
-
|
|
1197
|
+
|
|
1191
1198
|
def set_stylus(self, spec=None, **kwargs):
|
|
1192
1199
|
"""Set style spec for wx.stc.StyleSetSpec."""
|
|
1193
1200
|
spec = spec and spec.copy() or {}
|
|
@@ -1246,7 +1253,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1246
1253
|
## Apply the rest of the style
|
|
1247
1254
|
for key, value in spec.items():
|
|
1248
1255
|
self.StyleSetSpec(key, value)
|
|
1249
|
-
|
|
1256
|
+
|
|
1250
1257
|
def match_paren(self):
|
|
1251
1258
|
self.SetIndicatorCurrent(3)
|
|
1252
1259
|
self.IndicatorClearRange(0, self.TextLength)
|
|
@@ -1269,13 +1276,13 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1269
1276
|
self.BraceBadLight(p)
|
|
1270
1277
|
else:
|
|
1271
1278
|
self.BraceHighlight(-1,-1) # no highlight
|
|
1272
|
-
|
|
1279
|
+
|
|
1273
1280
|
def over(self, mode=1):
|
|
1274
1281
|
"""Set insert or overtype.
|
|
1275
1282
|
mode in {0:insert, 1:over, None:toggle}
|
|
1276
1283
|
"""
|
|
1277
1284
|
self.Overtype = mode if mode is not None else not self.Overtype
|
|
1278
|
-
|
|
1285
|
+
|
|
1279
1286
|
def wrap(self, mode=1):
|
|
1280
1287
|
"""Set whether text is word wrapped.
|
|
1281
1288
|
|
|
@@ -1283,7 +1290,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1283
1290
|
3:whitespace-wrap, None:toggle}
|
|
1284
1291
|
"""
|
|
1285
1292
|
self.WrapMode = mode if mode is not None else not self.WrapMode
|
|
1286
|
-
|
|
1293
|
+
|
|
1287
1294
|
def recenter(self, ln=None):
|
|
1288
1295
|
"""Scroll the cursor line to the center of screen.
|
|
1289
1296
|
If ln=0, the cursor moves to the top of the screen.
|
|
@@ -1293,13 +1300,13 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1293
1300
|
m = n//2 if ln is None else ln % n if ln < n else n # ln[0:n]
|
|
1294
1301
|
vl = self._calc_vline(self.cline)
|
|
1295
1302
|
self.ScrollToLine(vl - m)
|
|
1296
|
-
|
|
1303
|
+
|
|
1297
1304
|
def _calc_vline(self, line):
|
|
1298
1305
|
"""Virtual line number in the buffer window."""
|
|
1299
1306
|
pos = self.PositionFromLine(line)
|
|
1300
1307
|
w, h = self.PointFromPosition(pos)
|
|
1301
|
-
return self.FirstVisibleLine + h//self.TextHeight(
|
|
1302
|
-
|
|
1308
|
+
return self.FirstVisibleLine + h // self.TextHeight(line)
|
|
1309
|
+
|
|
1303
1310
|
def ensureLineOnScreen(self, line):
|
|
1304
1311
|
"""Ensure a particular line is visible by scrolling the buffer
|
|
1305
1312
|
without expanding any header line hiding it.
|
|
@@ -1311,7 +1318,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1311
1318
|
self.ScrollToLine(vl)
|
|
1312
1319
|
elif vl > hl + n - 1:
|
|
1313
1320
|
self.ScrollToLine(vl - n + 1)
|
|
1314
|
-
|
|
1321
|
+
|
|
1315
1322
|
def ensureLineMoreOnScreen(self, line, offset=0):
|
|
1316
1323
|
"""Ensure a particular line is visible by scrolling the buffer
|
|
1317
1324
|
without expanding any header line hiding it.
|
|
@@ -1322,11 +1329,11 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1322
1329
|
vl = self._calc_vline(line)
|
|
1323
1330
|
if not hl + offset < vl < hl + n - 1 - offset:
|
|
1324
1331
|
self.ScrollToLine(vl - n//2)
|
|
1325
|
-
|
|
1332
|
+
|
|
1326
1333
|
## --------------------------------
|
|
1327
1334
|
## Search functions
|
|
1328
1335
|
## --------------------------------
|
|
1329
|
-
|
|
1336
|
+
|
|
1330
1337
|
def DoFindNext(self, findData):
|
|
1331
1338
|
"""Find the search text defined in `findData`.
|
|
1332
1339
|
|
|
@@ -1367,13 +1374,13 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1367
1374
|
self.EnsureVisible(self.cline) # expand if folded
|
|
1368
1375
|
self.EnsureCaretVisible()
|
|
1369
1376
|
return loc
|
|
1370
|
-
|
|
1377
|
+
|
|
1371
1378
|
def DoReplaceNext(self, findData):
|
|
1372
1379
|
if self.SelectedText == findData.FindString:
|
|
1373
1380
|
if self.CanEdit():
|
|
1374
1381
|
self.ReplaceSelection(findData.ReplaceString)
|
|
1375
1382
|
return self.DoFindNext(findData)
|
|
1376
|
-
|
|
1383
|
+
|
|
1377
1384
|
def DoReplaceAll(self, findData):
|
|
1378
1385
|
with self.save_excursion():
|
|
1379
1386
|
locs = [-1]
|
|
@@ -1389,17 +1396,17 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1389
1396
|
self.ReplaceTarget(findData.ReplaceString)
|
|
1390
1397
|
count += 1
|
|
1391
1398
|
return count
|
|
1392
|
-
|
|
1399
|
+
|
|
1393
1400
|
def get_right_paren(self, p):
|
|
1394
1401
|
if self.get_char(p) in "({[<": # left-parentheses, <
|
|
1395
1402
|
q = self.BraceMatch(p)
|
|
1396
1403
|
return q if q < 0 else q+1
|
|
1397
|
-
|
|
1404
|
+
|
|
1398
1405
|
def get_left_paren(self, p):
|
|
1399
1406
|
if self.get_char(p-1) in ")}]>": # right-parentheses, >
|
|
1400
1407
|
q = self.BraceMatch(p-1)
|
|
1401
1408
|
return q
|
|
1402
|
-
|
|
1409
|
+
|
|
1403
1410
|
def get_right_quotation(self, p):
|
|
1404
1411
|
st = self.get_style(p)
|
|
1405
1412
|
if st == 'moji':
|
|
@@ -1408,7 +1415,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1408
1415
|
while self.get_style(p) == st and p < self.TextLength:
|
|
1409
1416
|
p += 1
|
|
1410
1417
|
return p
|
|
1411
|
-
|
|
1418
|
+
|
|
1412
1419
|
def get_left_quotation(self, p):
|
|
1413
1420
|
st = self.get_style(p-1)
|
|
1414
1421
|
if st == 'moji':
|
|
@@ -1417,7 +1424,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1417
1424
|
while self.get_style(p-1) == st and p > 0:
|
|
1418
1425
|
p -= 1
|
|
1419
1426
|
return p
|
|
1420
|
-
|
|
1427
|
+
|
|
1421
1428
|
def get_following_atom(self, p):
|
|
1422
1429
|
q = p
|
|
1423
1430
|
st = self.get_style(p)
|
|
@@ -1433,7 +1440,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1433
1440
|
while self.get_style(q) == st and q < self.TextLength:
|
|
1434
1441
|
q += 1
|
|
1435
1442
|
return p, q, st
|
|
1436
|
-
|
|
1443
|
+
|
|
1437
1444
|
def get_preceding_atom(self, p):
|
|
1438
1445
|
q = p
|
|
1439
1446
|
st = self.get_style(p-1)
|
|
@@ -1448,7 +1455,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1448
1455
|
while self.get_style(p-1) == st and p > 0:
|
|
1449
1456
|
p -= 1
|
|
1450
1457
|
return p, q, st
|
|
1451
|
-
|
|
1458
|
+
|
|
1452
1459
|
def grep_forward(self, pattern, flags=re.M):
|
|
1453
1460
|
orig = self.eol if (self.markline == self.cline) else self.cpos
|
|
1454
1461
|
text = self.GetTextRange(orig, self.TextLength)
|
|
@@ -1460,7 +1467,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1460
1467
|
self.mark = self.cpos
|
|
1461
1468
|
self.EnsureVisible(self.cline)
|
|
1462
1469
|
yield err
|
|
1463
|
-
|
|
1470
|
+
|
|
1464
1471
|
def grep_backward(self, pattern, flags=re.M):
|
|
1465
1472
|
text = self.GetTextRange(0, self.cpos)
|
|
1466
1473
|
errs = re.finditer(pattern, text, flags)
|
|
@@ -1471,10 +1478,10 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1471
1478
|
self.mark = self.cpos
|
|
1472
1479
|
self.EnsureVisible(self.cline)
|
|
1473
1480
|
yield err
|
|
1474
|
-
|
|
1481
|
+
|
|
1475
1482
|
def grep(self, pattern, flags=re.M):
|
|
1476
1483
|
yield from re.finditer(pattern.encode(), self.TextRaw, flags)
|
|
1477
|
-
|
|
1484
|
+
|
|
1478
1485
|
def filter_text(self):
|
|
1479
1486
|
"""Show indicators for the selected text."""
|
|
1480
1487
|
self.__itextlines = []
|
|
@@ -1507,7 +1514,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1507
1514
|
self.TopLevelParent.findData.Flags &= ~wx.FR_WHOLEWORD
|
|
1508
1515
|
except AttributeError:
|
|
1509
1516
|
pass
|
|
1510
|
-
|
|
1517
|
+
|
|
1511
1518
|
def on_itext_enter(self, evt):
|
|
1512
1519
|
"""Called when entering filter_text mode."""
|
|
1513
1520
|
if not self.__itextlines:
|
|
@@ -1526,13 +1533,13 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1526
1533
|
self.Bind(stc.EVT_STC_AUTOCOMP_SELECTION, self.on_itext_selection)
|
|
1527
1534
|
|
|
1528
1535
|
## self.StyleSetSize(stc.STC_STYLE_DEFAULT, pts)
|
|
1529
|
-
|
|
1536
|
+
|
|
1530
1537
|
def on_itext_exit(self, evt):
|
|
1531
1538
|
"""Called when exiting filter_text mode."""
|
|
1532
1539
|
if self.AutoCompActive():
|
|
1533
1540
|
self.AutoCompCancel()
|
|
1534
1541
|
self.Unbind(stc.EVT_STC_AUTOCOMP_SELECTION, handler=self.on_itext_selection)
|
|
1535
|
-
|
|
1542
|
+
|
|
1536
1543
|
def on_itext_selection(self, evt):
|
|
1537
1544
|
"""Called when filter_text is selected."""
|
|
1538
1545
|
i = self.AutoCompGetCurrent()
|
|
@@ -1544,11 +1551,11 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1544
1551
|
self.goto_line(line)
|
|
1545
1552
|
self.recenter()
|
|
1546
1553
|
self.on_itext_exit(evt)
|
|
1547
|
-
|
|
1554
|
+
|
|
1548
1555
|
## --------------------------------
|
|
1549
1556
|
## goto / skip / selection / etc.
|
|
1550
1557
|
## --------------------------------
|
|
1551
|
-
|
|
1558
|
+
|
|
1552
1559
|
def goto_char(self, pos, selection=False, interactive=False):
|
|
1553
1560
|
"""Goto char position with selection."""
|
|
1554
1561
|
if pos is None or pos < 0:
|
|
@@ -1579,7 +1586,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1579
1586
|
for k in modkeys:
|
|
1580
1587
|
vk.KeyDown(k) # restore modifier key state
|
|
1581
1588
|
return True
|
|
1582
|
-
|
|
1589
|
+
|
|
1583
1590
|
def goto_line(self, ln, selection=False):
|
|
1584
1591
|
"""Goto line with selection."""
|
|
1585
1592
|
if ln is None or ln < 0:
|
|
@@ -1591,60 +1598,60 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1591
1598
|
else:
|
|
1592
1599
|
self.GotoLine(ln)
|
|
1593
1600
|
return True
|
|
1594
|
-
|
|
1601
|
+
|
|
1595
1602
|
def skip_chars_forward(self, chars):
|
|
1596
1603
|
p = self.cpos
|
|
1597
1604
|
while self.get_char(p) in chars and p < self.TextLength:
|
|
1598
1605
|
p += 1
|
|
1599
1606
|
self.goto_char(p)
|
|
1600
|
-
|
|
1607
|
+
|
|
1601
1608
|
def skip_chars_backward(self, chars):
|
|
1602
1609
|
p = self.cpos
|
|
1603
1610
|
while self.get_char(p-1) in chars and p > 0:
|
|
1604
1611
|
p -= 1
|
|
1605
1612
|
self.goto_char(p)
|
|
1606
|
-
|
|
1613
|
+
|
|
1607
1614
|
def back_to_indentation(self):
|
|
1608
1615
|
text = self.line_at_caret # w/ no-prompt
|
|
1609
1616
|
lstr = text.lstrip() # w/ no-indent
|
|
1610
1617
|
p = self.bol + len(text) - len(lstr)
|
|
1611
1618
|
self.goto_char(p, interactive=True)
|
|
1612
1619
|
self.ScrollToColumn(0)
|
|
1613
|
-
|
|
1620
|
+
|
|
1614
1621
|
def beginning_of_line(self):
|
|
1615
1622
|
self.goto_char(self.bol, interactive=True)
|
|
1616
1623
|
self.ScrollToColumn(0)
|
|
1617
|
-
|
|
1624
|
+
|
|
1618
1625
|
def end_of_line(self):
|
|
1619
1626
|
self.goto_char(self.eol, interactive=True)
|
|
1620
|
-
|
|
1627
|
+
|
|
1621
1628
|
def beginning_of_buffer(self):
|
|
1622
1629
|
self.mark = self.cpos
|
|
1623
1630
|
self.goto_char(0, interactive=True)
|
|
1624
|
-
|
|
1631
|
+
|
|
1625
1632
|
def end_of_buffer(self):
|
|
1626
1633
|
self.mark = self.cpos
|
|
1627
1634
|
self.goto_char(self.TextLength, interactive=True)
|
|
1628
|
-
|
|
1635
|
+
|
|
1629
1636
|
def goto_matched_paren(self):
|
|
1630
1637
|
p = self.cpos
|
|
1631
1638
|
return (self.goto_char(self.get_left_paren(p))
|
|
1632
1639
|
or self.goto_char(self.get_right_paren(p))
|
|
1633
1640
|
or self.goto_char(self.get_left_quotation(p))
|
|
1634
1641
|
or self.goto_char(self.get_right_quotation(p)))
|
|
1635
|
-
|
|
1642
|
+
|
|
1636
1643
|
def selection_forward_word_or_paren(self):
|
|
1637
1644
|
p = self.cpos
|
|
1638
1645
|
return (self.goto_char(self.get_right_paren(p), selection=True)
|
|
1639
1646
|
or self.goto_char(self.get_right_quotation(p), selection=True)
|
|
1640
1647
|
or self.WordRightEndExtend())
|
|
1641
|
-
|
|
1648
|
+
|
|
1642
1649
|
def selection_backward_word_or_paren(self):
|
|
1643
1650
|
p = self.cpos
|
|
1644
1651
|
return (self.goto_char(self.get_left_paren(p), selection=True)
|
|
1645
1652
|
or self.goto_char(self.get_left_quotation(p), selection=True)
|
|
1646
1653
|
or self.WordLeftExtend())
|
|
1647
|
-
|
|
1654
|
+
|
|
1648
1655
|
@contextmanager
|
|
1649
1656
|
def save_excursion(self):
|
|
1650
1657
|
"""Save buffer excursion."""
|
|
@@ -1657,7 +1664,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1657
1664
|
self.GotoPos(p)
|
|
1658
1665
|
self.ScrollToLine(vpos)
|
|
1659
1666
|
self.SetXOffset(hpos)
|
|
1660
|
-
|
|
1667
|
+
|
|
1661
1668
|
@contextmanager
|
|
1662
1669
|
def pre_selection(self):
|
|
1663
1670
|
"""Save buffer cpos and anchor."""
|
|
@@ -1670,7 +1677,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1670
1677
|
self.cpos = p
|
|
1671
1678
|
else:
|
|
1672
1679
|
self.anchor = q
|
|
1673
|
-
|
|
1680
|
+
|
|
1674
1681
|
@contextmanager
|
|
1675
1682
|
def save_attributes(self, **kwargs):
|
|
1676
1683
|
"""Save buffer attributes (e.g. ReadOnly=False)."""
|
|
@@ -1682,44 +1689,42 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1682
1689
|
finally:
|
|
1683
1690
|
for k, v in kwargs.items():
|
|
1684
1691
|
setattr(self, k, v)
|
|
1685
|
-
|
|
1692
|
+
|
|
1686
1693
|
def off_readonly(self):
|
|
1687
1694
|
"""Disables buffer read-only lock temporarily."""
|
|
1688
1695
|
return self.save_attributes(ReadOnly=False)
|
|
1689
|
-
|
|
1696
|
+
|
|
1690
1697
|
def off_undocollection(self):
|
|
1691
1698
|
"""Disables buffer undo stack temporarily."""
|
|
1692
1699
|
return self.save_attributes(UndoCollection=False)
|
|
1693
|
-
|
|
1700
|
+
|
|
1694
1701
|
## --------------------------------
|
|
1695
1702
|
## Edit: comment / insert / kill
|
|
1696
1703
|
## --------------------------------
|
|
1697
|
-
comment_prefix = "
|
|
1698
|
-
|
|
1704
|
+
comment_prefix = "#"
|
|
1705
|
+
|
|
1699
1706
|
@editable
|
|
1700
1707
|
def comment_out_selection(self, from_=None, to_=None):
|
|
1701
1708
|
"""Comment out the selected text."""
|
|
1702
1709
|
if from_ is not None: self.anchor = from_
|
|
1703
1710
|
if to_ is not None: self.cpos = to_
|
|
1704
|
-
prefix = self.comment_prefix
|
|
1705
1711
|
with self.pre_selection():
|
|
1706
|
-
text = re.sub("^",
|
|
1707
|
-
## Don't comment out the last (blank) line.
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
text = text[:-len(prefix)]
|
|
1712
|
+
text = re.sub("^", self.comment_prefix + ' ', self.SelectedText, flags=re.M)
|
|
1713
|
+
## Don't comment out the last (blank) line in a multiline selection.
|
|
1714
|
+
if '\n' in text:
|
|
1715
|
+
text = text.rstrip(self.comment_prefix + ' ')
|
|
1711
1716
|
self.ReplaceSelection(text)
|
|
1712
|
-
|
|
1717
|
+
|
|
1713
1718
|
@editable
|
|
1714
1719
|
def uncomment_selection(self, from_=None, to_=None):
|
|
1715
1720
|
"""Uncomment the selected text."""
|
|
1716
1721
|
if from_ is not None: self.anchor = from_
|
|
1717
1722
|
if to_ is not None: self.cpos = to_
|
|
1718
1723
|
with self.pre_selection():
|
|
1719
|
-
text = re.sub("
|
|
1724
|
+
text = re.sub(f"^{self.comment_prefix}+ ", "", self.SelectedText, flags=re.M)
|
|
1720
1725
|
if text != self.SelectedText:
|
|
1721
1726
|
self.ReplaceSelection(text)
|
|
1722
|
-
|
|
1727
|
+
|
|
1723
1728
|
@editable
|
|
1724
1729
|
def comment_out_line(self):
|
|
1725
1730
|
if self.SelectedText:
|
|
@@ -1735,7 +1740,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1735
1740
|
self.goto_char(self.bol + min(j, k))
|
|
1736
1741
|
self.comment_out_selection(self.cpos, self.eol)
|
|
1737
1742
|
self.LineDown()
|
|
1738
|
-
|
|
1743
|
+
|
|
1739
1744
|
@editable
|
|
1740
1745
|
def uncomment_line(self):
|
|
1741
1746
|
if self.SelectedText:
|
|
@@ -1744,31 +1749,31 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1744
1749
|
self.back_to_indentation()
|
|
1745
1750
|
self.uncomment_selection(self.cpos, self.eol)
|
|
1746
1751
|
self.LineDown()
|
|
1747
|
-
|
|
1752
|
+
|
|
1748
1753
|
@editable
|
|
1749
1754
|
def eat_white_forward(self):
|
|
1750
1755
|
p = self.cpos
|
|
1751
1756
|
self.skip_chars_forward(' \t')
|
|
1752
1757
|
self.Replace(p, self.cpos, '')
|
|
1753
|
-
|
|
1758
|
+
|
|
1754
1759
|
@editable
|
|
1755
1760
|
def eat_white_backward(self):
|
|
1756
1761
|
p = self.cpos
|
|
1757
1762
|
self.skip_chars_backward(' \t')
|
|
1758
1763
|
self.Replace(max(self.cpos, self.bol), p, '')
|
|
1759
|
-
|
|
1764
|
+
|
|
1760
1765
|
@editable
|
|
1761
1766
|
def kill_word(self):
|
|
1762
1767
|
if not self.SelectedText:
|
|
1763
1768
|
self.WordRightEndExtend()
|
|
1764
1769
|
self.ReplaceSelection('')
|
|
1765
|
-
|
|
1770
|
+
|
|
1766
1771
|
@editable
|
|
1767
1772
|
def backward_kill_word(self):
|
|
1768
1773
|
if not self.SelectedText:
|
|
1769
1774
|
self.WordLeftExtend()
|
|
1770
1775
|
self.ReplaceSelection('')
|
|
1771
|
-
|
|
1776
|
+
|
|
1772
1777
|
@editable
|
|
1773
1778
|
def kill_line(self):
|
|
1774
1779
|
if not self.SelectedText:
|
|
@@ -1781,7 +1786,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1781
1786
|
else:
|
|
1782
1787
|
self.cpos = self.eol
|
|
1783
1788
|
self.ReplaceSelection('')
|
|
1784
|
-
|
|
1789
|
+
|
|
1785
1790
|
@editable
|
|
1786
1791
|
def backward_kill_line(self):
|
|
1787
1792
|
if not self.SelectedText:
|
|
@@ -1794,7 +1799,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1794
1799
|
else:
|
|
1795
1800
|
self.cpos = self.bol
|
|
1796
1801
|
self.ReplaceSelection('')
|
|
1797
|
-
|
|
1802
|
+
|
|
1798
1803
|
@editable
|
|
1799
1804
|
def insert_space_like_tab(self):
|
|
1800
1805
|
"""Insert half-width spaces forward as if feeling like [tab].
|
|
@@ -1803,7 +1808,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1803
1808
|
self.eat_white_forward()
|
|
1804
1809
|
_text, lp = self.CurLine
|
|
1805
1810
|
self.WriteText(' ' * (4 - lp % 4))
|
|
1806
|
-
|
|
1811
|
+
|
|
1807
1812
|
@editable
|
|
1808
1813
|
def delete_backward_space_like_tab(self):
|
|
1809
1814
|
"""Delete half-width spaces backward as if feeling like [S-tab].
|
|
@@ -1825,19 +1830,19 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
1825
1830
|
@property
|
|
1826
1831
|
def message(self):
|
|
1827
1832
|
return self.parent.message
|
|
1828
|
-
|
|
1833
|
+
|
|
1829
1834
|
@property
|
|
1830
1835
|
def name(self):
|
|
1831
1836
|
"""buffer-name (basename)."""
|
|
1832
1837
|
return os.path.basename(self.__filename or '')
|
|
1833
|
-
|
|
1838
|
+
|
|
1834
1839
|
Name = name # page.window.Name for save/loadPerspective
|
|
1835
|
-
|
|
1840
|
+
|
|
1836
1841
|
@property
|
|
1837
1842
|
def filename(self):
|
|
1838
1843
|
"""buffer-file-name."""
|
|
1839
1844
|
return self.__filename
|
|
1840
|
-
|
|
1845
|
+
|
|
1841
1846
|
def update_filestamp(self, fn):
|
|
1842
1847
|
self.__path = Path(fn)
|
|
1843
1848
|
if self.__path.is_file():
|
|
@@ -1854,7 +1859,7 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
1854
1859
|
if self.__filename != fn:
|
|
1855
1860
|
self.__filename = fn
|
|
1856
1861
|
self.update_caption()
|
|
1857
|
-
|
|
1862
|
+
|
|
1858
1863
|
@property
|
|
1859
1864
|
def mtdelta(self):
|
|
1860
1865
|
"""Timestamp delta (for checking external mod).
|
|
@@ -1872,21 +1877,21 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
1872
1877
|
except OSError:
|
|
1873
1878
|
pass
|
|
1874
1879
|
return self.__mtime
|
|
1875
|
-
|
|
1880
|
+
|
|
1876
1881
|
@property
|
|
1877
1882
|
def need_buffer_save(self):
|
|
1878
1883
|
"""Return whether the buffer should be saved.
|
|
1879
1884
|
The file has been modified internally.
|
|
1880
1885
|
"""
|
|
1881
1886
|
return self.mtdelta is not None and self.IsModified()
|
|
1882
|
-
|
|
1887
|
+
|
|
1883
1888
|
@property
|
|
1884
1889
|
def need_buffer_load(self):
|
|
1885
1890
|
"""Return whether the buffer should be loaded.
|
|
1886
1891
|
The file has been modified externally.
|
|
1887
1892
|
"""
|
|
1888
1893
|
return self.mtdelta is not None and self.mtdelta > 0
|
|
1889
|
-
|
|
1894
|
+
|
|
1890
1895
|
@property
|
|
1891
1896
|
def caption_prefix(self):
|
|
1892
1897
|
prefix = ''
|
|
@@ -1901,7 +1906,7 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
1901
1906
|
if prefix:
|
|
1902
1907
|
prefix += ' '
|
|
1903
1908
|
return prefix
|
|
1904
|
-
|
|
1909
|
+
|
|
1905
1910
|
def update_caption(self):
|
|
1906
1911
|
caption = self.caption_prefix + self.name
|
|
1907
1912
|
try:
|
|
@@ -1909,7 +1914,7 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
1909
1914
|
self.parent.handler('buffer_caption_updated', self)
|
|
1910
1915
|
except AttributeError:
|
|
1911
1916
|
pass
|
|
1912
|
-
|
|
1917
|
+
|
|
1913
1918
|
def __init__(self, parent, filename, **kwargs):
|
|
1914
1919
|
EditWindow.__init__(self, parent, **kwargs)
|
|
1915
1920
|
EditorInterface.__init__(self)
|
|
@@ -1976,6 +1981,7 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
1976
1981
|
'* pressed' : (0, skip),
|
|
1977
1982
|
'* released' : (0, skip, dispatch),
|
|
1978
1983
|
'*button* pressed' : (0, skip, dispatch),
|
|
1984
|
+
'Lbutton pressed' : (0, self.on_left_down),
|
|
1979
1985
|
'escape pressed' : (-1, self.on_enter_escmap),
|
|
1980
1986
|
'C-h pressed' : (0, self.call_helpTip),
|
|
1981
1987
|
'. pressed' : (2, self.OnEnterDot),
|
|
@@ -2042,23 +2048,23 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2042
2048
|
|
|
2043
2049
|
self.show_folder()
|
|
2044
2050
|
self.set_stylus(Stylus.py_text_mode)
|
|
2045
|
-
|
|
2051
|
+
|
|
2046
2052
|
def __contains__(self, code):
|
|
2047
2053
|
if inspect.iscode(code) and self.code:
|
|
2048
2054
|
return code is self.code\
|
|
2049
2055
|
or code in self.code.co_consts
|
|
2050
|
-
|
|
2056
|
+
|
|
2051
2057
|
def trace_position(self):
|
|
2052
2058
|
_text, lp = self.CurLine
|
|
2053
2059
|
self.message("{:>6d}:{} ({})".format(self.cline, lp, self.cpos), pane=-1)
|
|
2054
|
-
|
|
2060
|
+
|
|
2055
2061
|
def OnUpdate(self, evt): #<wx._stc.StyledTextEvent>
|
|
2056
2062
|
if evt.Updated & (stc.STC_UPDATE_SELECTION | stc.STC_UPDATE_CONTENT):
|
|
2057
2063
|
self.trace_position()
|
|
2058
2064
|
if evt.Updated & stc.STC_UPDATE_CONTENT:
|
|
2059
2065
|
self.handler('buffer_modified', self)
|
|
2060
2066
|
evt.Skip()
|
|
2061
|
-
|
|
2067
|
+
|
|
2062
2068
|
def OnCallTipClick(self, evt): #<wx._stc.StyledTextEvent>
|
|
2063
2069
|
if self.CallTipActive():
|
|
2064
2070
|
self.CallTipCancel()
|
|
@@ -2066,7 +2072,7 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2066
2072
|
if more:
|
|
2067
2073
|
self.CallTipShow(pos, tip, N=None)
|
|
2068
2074
|
evt.Skip()
|
|
2069
|
-
|
|
2075
|
+
|
|
2070
2076
|
def OnIndicatorClick(self, evt): #<wx._stc.StyledTextEvent>
|
|
2071
2077
|
if self.SelectedText or not wx.GetKeyState(wx.WXK_CONTROL):
|
|
2072
2078
|
## Processing text selection, dragging, or dragging+
|
|
@@ -2086,7 +2092,7 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2086
2092
|
else:
|
|
2087
2093
|
## Note: post-call for the confirmation dialog.
|
|
2088
2094
|
wx.CallAfter(self.parent.load_file, url)
|
|
2089
|
-
|
|
2095
|
+
|
|
2090
2096
|
def on_buffer_modified(self, buf):
|
|
2091
2097
|
"""Called when the buffer is modified."""
|
|
2092
2098
|
self.SetIndicatorCurrent(2)
|
|
@@ -2094,15 +2100,15 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2094
2100
|
for m in self.grep(url_re):
|
|
2095
2101
|
p, q = m.span()
|
|
2096
2102
|
self.IndicatorFillRange(p, q-p)
|
|
2097
|
-
|
|
2103
|
+
|
|
2098
2104
|
def OnSavePointLeft(self, evt):
|
|
2099
2105
|
self.update_caption()
|
|
2100
2106
|
evt.Skip()
|
|
2101
|
-
|
|
2107
|
+
|
|
2102
2108
|
def OnSavePointReached(self, evt):
|
|
2103
2109
|
self.update_caption()
|
|
2104
2110
|
evt.Skip()
|
|
2105
|
-
|
|
2111
|
+
|
|
2106
2112
|
def OnEnterDot(self, evt):
|
|
2107
2113
|
if not self.CanEdit():
|
|
2108
2114
|
self.handler('quit', evt)
|
|
@@ -2111,36 +2117,49 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2111
2117
|
lst = self.get_style(p-1)
|
|
2112
2118
|
rst = self.get_style(p)
|
|
2113
2119
|
if lst not in ('moji', 'word', 'rparen') or rst == 'word':
|
|
2114
|
-
self.handler('quit', evt)
|
|
2120
|
+
self.handler('quit', evt) # Don't enter autocomp
|
|
2115
2121
|
evt.Skip()
|
|
2116
|
-
|
|
2122
|
+
|
|
2117
2123
|
def on_buffer_activated(self, buf):
|
|
2118
2124
|
"""Called when the buffer is activated."""
|
|
2119
2125
|
self.update_caption()
|
|
2120
2126
|
self.trace_position()
|
|
2121
|
-
|
|
2127
|
+
|
|
2122
2128
|
def on_buffer_inactivated(self, buf):
|
|
2123
2129
|
"""Called when the buffer is inactivated."""
|
|
2124
2130
|
pass
|
|
2125
|
-
|
|
2131
|
+
|
|
2132
|
+
def on_left_down(self, evt):
|
|
2133
|
+
pos = self.PositionFromPoint(evt.Position)
|
|
2134
|
+
ln = self.LineFromPosition(pos)
|
|
2135
|
+
ann_text = self.AnnotationGetText(ln)
|
|
2136
|
+
if ann_text:
|
|
2137
|
+
if pos == self.GetLineEndPosition(ln): # Check eol (not clicked yet).
|
|
2138
|
+
if wx.TheClipboard.Open():
|
|
2139
|
+
wx.TheClipboard.SetData(wx.TextDataObject(ann_text))
|
|
2140
|
+
wx.TheClipboard.Close()
|
|
2141
|
+
self.message("Annotation copied.")
|
|
2142
|
+
self.AnnotationClearLine(ln)
|
|
2143
|
+
evt.Skip()
|
|
2144
|
+
|
|
2126
2145
|
def on_enter_escmap(self, evt):
|
|
2127
2146
|
self.message("ESC-")
|
|
2128
|
-
|
|
2147
|
+
|
|
2129
2148
|
def on_exit_escmap(self, evt):
|
|
2130
2149
|
self.message("ESC {}".format(evt.key))
|
|
2131
2150
|
self.AnnotationClearAll()
|
|
2132
|
-
|
|
2151
|
+
|
|
2133
2152
|
## --------------------------------
|
|
2134
2153
|
## File I/O
|
|
2135
2154
|
## --------------------------------
|
|
2136
|
-
|
|
2155
|
+
|
|
2137
2156
|
def _load_textfile(self, text):
|
|
2138
2157
|
with self.off_readonly():
|
|
2139
2158
|
self.Text = text
|
|
2140
2159
|
self.EmptyUndoBuffer()
|
|
2141
2160
|
self.SetSavePoint()
|
|
2142
2161
|
self.handler('buffer_loaded', self)
|
|
2143
|
-
|
|
2162
|
+
|
|
2144
2163
|
def _load_file(self, filename):
|
|
2145
2164
|
"""Wrapped method of LoadFile."""
|
|
2146
2165
|
if self.LoadFile(filename):
|
|
@@ -2150,7 +2169,7 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2150
2169
|
self.handler('buffer_loaded', self)
|
|
2151
2170
|
return True
|
|
2152
2171
|
return False
|
|
2153
|
-
|
|
2172
|
+
|
|
2154
2173
|
def _save_file(self, filename):
|
|
2155
2174
|
"""Wrapped method of SaveFile."""
|
|
2156
2175
|
if self.SaveFile(filename):
|
|
@@ -2159,7 +2178,7 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2159
2178
|
self.handler('buffer_saved', self)
|
|
2160
2179
|
return True
|
|
2161
2180
|
return False
|
|
2162
|
-
|
|
2181
|
+
|
|
2163
2182
|
def LoadFile(self, filename):
|
|
2164
2183
|
"""Load the contents of file into the editor.
|
|
2165
2184
|
|
|
@@ -2169,7 +2188,7 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2169
2188
|
with self.off_readonly():
|
|
2170
2189
|
self.Text = i.read()
|
|
2171
2190
|
return True
|
|
2172
|
-
|
|
2191
|
+
|
|
2173
2192
|
def SaveFile(self, filename):
|
|
2174
2193
|
"""Write the contents of the editor to file.
|
|
2175
2194
|
|
|
@@ -2178,33 +2197,33 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2178
2197
|
with open(filename, "w", encoding='utf-8', newline='') as o:
|
|
2179
2198
|
o.write(self.Text)
|
|
2180
2199
|
return True
|
|
2181
|
-
|
|
2200
|
+
|
|
2182
2201
|
## --------------------------------
|
|
2183
2202
|
## Python eval / exec
|
|
2184
2203
|
## --------------------------------
|
|
2185
|
-
|
|
2204
|
+
|
|
2186
2205
|
@property
|
|
2187
2206
|
def locals(self): # internal use only
|
|
2188
2207
|
try:
|
|
2189
2208
|
return self.parent.parent.current_shell.locals
|
|
2190
2209
|
except AttributeError:
|
|
2191
2210
|
return None
|
|
2192
|
-
|
|
2211
|
+
|
|
2193
2212
|
@property
|
|
2194
2213
|
def globals(self): # internal use only
|
|
2195
2214
|
try:
|
|
2196
2215
|
return self.parent.parent.current_shell.globals
|
|
2197
2216
|
except AttributeError:
|
|
2198
2217
|
return None
|
|
2199
|
-
|
|
2218
|
+
|
|
2200
2219
|
def eval(self, text):
|
|
2201
2220
|
return eval(text, self.globals, self.locals) # using current shell namespace
|
|
2202
|
-
|
|
2221
|
+
|
|
2203
2222
|
def exec(self, text):
|
|
2204
2223
|
exec(text, self.globals, self.locals) # using current shell namespace
|
|
2205
2224
|
dispatcher.send(signal='Interpreter.push',
|
|
2206
2225
|
sender=self, command=None, more=False)
|
|
2207
|
-
|
|
2226
|
+
|
|
2208
2227
|
def eval_line(self):
|
|
2209
2228
|
"""Evaluate the selected word or line and show calltips."""
|
|
2210
2229
|
if self.CallTipActive():
|
|
@@ -2229,7 +2248,7 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2229
2248
|
return
|
|
2230
2249
|
if not text:
|
|
2231
2250
|
self.message("No words")
|
|
2232
|
-
|
|
2251
|
+
|
|
2233
2252
|
def exec_region(self):
|
|
2234
2253
|
"""Execute a region of code."""
|
|
2235
2254
|
try:
|
|
@@ -2238,7 +2257,6 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2238
2257
|
dispatcher.send(signal='Interpreter.push',
|
|
2239
2258
|
sender=self, command=None, more=False)
|
|
2240
2259
|
except BdbQuit:
|
|
2241
|
-
self.red_pointer = self.cline
|
|
2242
2260
|
pass
|
|
2243
2261
|
except Exception as e:
|
|
2244
2262
|
msg = traceback.format_exc()
|
|
@@ -2275,7 +2293,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2275
2293
|
@property
|
|
2276
2294
|
def message(self):
|
|
2277
2295
|
return self.parent.message
|
|
2278
|
-
|
|
2296
|
+
|
|
2279
2297
|
def __init__(self, parent, name="book", **kwargs):
|
|
2280
2298
|
kwargs.setdefault('style',
|
|
2281
2299
|
(aui.AUI_NB_DEFAULT_STYLE | aui.AUI_NB_TOP)
|
|
@@ -2325,13 +2343,13 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2325
2343
|
'M-down pressed' : (0, _F(self.next_buffer)),
|
|
2326
2344
|
},
|
|
2327
2345
|
})
|
|
2328
|
-
|
|
2346
|
+
|
|
2329
2347
|
def OnDestroy(self, evt):
|
|
2330
2348
|
obj = evt.EventObject
|
|
2331
2349
|
if isinstance(obj, Buffer):
|
|
2332
2350
|
self.handler('buffer_deleted', obj)
|
|
2333
2351
|
evt.Skip()
|
|
2334
|
-
|
|
2352
|
+
|
|
2335
2353
|
def OnPageClose(self, evt): #<wx._aui.AuiNotebookEvent>
|
|
2336
2354
|
buf = self.GetPage(evt.Selection)
|
|
2337
2355
|
if buf.need_buffer_save:
|
|
@@ -2345,12 +2363,12 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2345
2363
|
evt.Veto()
|
|
2346
2364
|
return
|
|
2347
2365
|
evt.Skip()
|
|
2348
|
-
|
|
2366
|
+
|
|
2349
2367
|
def OnPageClosed(self, evt): #<wx._aui.AuiNotebookEvent>
|
|
2350
2368
|
if self.PageCount == 0:
|
|
2351
2369
|
self.new_buffer()
|
|
2352
2370
|
evt.Skip()
|
|
2353
|
-
|
|
2371
|
+
|
|
2354
2372
|
def set_attributes(self, buf=None, **kwargs):
|
|
2355
2373
|
"""Set multiple properties at once to the buffer(s).
|
|
2356
2374
|
|
|
@@ -2379,20 +2397,20 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2379
2397
|
self.defaultBufferStyle.update(kwargs)
|
|
2380
2398
|
for buf in self.get_all_buffers():
|
|
2381
2399
|
_setattribute(buf, self.defaultBufferStyle)
|
|
2382
|
-
|
|
2400
|
+
|
|
2383
2401
|
def on_buffer_activated(self, buf):
|
|
2384
2402
|
"""Called when the buffer is activated."""
|
|
2385
2403
|
title = "{} file: {}".format(self.Name, buf.filename)
|
|
2386
2404
|
self.parent.handler('title_window', title)
|
|
2387
|
-
|
|
2405
|
+
|
|
2388
2406
|
def on_buffer_inactivated(self, buf):
|
|
2389
2407
|
"""Called when the buffer is inactivated."""
|
|
2390
2408
|
pass
|
|
2391
|
-
|
|
2409
|
+
|
|
2392
2410
|
## --------------------------------
|
|
2393
2411
|
## Buffer list controls
|
|
2394
2412
|
## --------------------------------
|
|
2395
|
-
|
|
2413
|
+
|
|
2396
2414
|
def get_all_buffers(self, fn=None):
|
|
2397
2415
|
"""Yields all buffers with specified fn:filename or code."""
|
|
2398
2416
|
if fn is None:
|
|
@@ -2406,7 +2424,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2406
2424
|
for buf in self.get_pages(Buffer):
|
|
2407
2425
|
if fn is buf or fn in buf: # check code
|
|
2408
2426
|
yield buf
|
|
2409
|
-
|
|
2427
|
+
|
|
2410
2428
|
@property
|
|
2411
2429
|
def menu(self):
|
|
2412
2430
|
"""Yields context menu."""
|
|
@@ -2417,22 +2435,22 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2417
2435
|
lambda v: v.Check(buf is self.buffer))
|
|
2418
2436
|
|
|
2419
2437
|
return (_menu(j+1, x) for j, x in enumerate(self.get_all_buffers()))
|
|
2420
|
-
|
|
2438
|
+
|
|
2421
2439
|
@property
|
|
2422
2440
|
def buffer(self):
|
|
2423
2441
|
"""Return the currently selected page or None."""
|
|
2424
2442
|
return self.CurrentPage
|
|
2425
|
-
|
|
2443
|
+
|
|
2426
2444
|
def find_buffer(self, fn):
|
|
2427
2445
|
"""Find a buffer with specified fn:filename or code."""
|
|
2428
2446
|
return next(self.get_all_buffers(fn), None)
|
|
2429
|
-
|
|
2447
|
+
|
|
2430
2448
|
def swap_buffer(self, buf, lineno=0):
|
|
2431
2449
|
self.swap_page(buf)
|
|
2432
2450
|
if lineno:
|
|
2433
2451
|
buf.markline = lineno - 1
|
|
2434
2452
|
buf.goto_marker(1)
|
|
2435
|
-
|
|
2453
|
+
|
|
2436
2454
|
def create_buffer(self, filename, index=None):
|
|
2437
2455
|
"""Create a new buffer (internal use only)."""
|
|
2438
2456
|
with wx.FrozenWindow(self):
|
|
@@ -2443,7 +2461,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2443
2461
|
self.InsertPage(index, buf, buf.name) # => [buffer_activated]
|
|
2444
2462
|
self.handler('buffer_new', buf)
|
|
2445
2463
|
return buf
|
|
2446
|
-
|
|
2464
|
+
|
|
2447
2465
|
def new_buffer(self):
|
|
2448
2466
|
"""Create a new default buffer."""
|
|
2449
2467
|
buf = self.default_buffer
|
|
@@ -2455,7 +2473,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2455
2473
|
## buf.EmptyUndoBuffer()
|
|
2456
2474
|
buf.SetFocus()
|
|
2457
2475
|
return buf
|
|
2458
|
-
|
|
2476
|
+
|
|
2459
2477
|
def delete_buffer(self, buf=None):
|
|
2460
2478
|
"""Pop the current buffer from the buffer list."""
|
|
2461
2479
|
if not buf:
|
|
@@ -2465,12 +2483,12 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2465
2483
|
self.DeletePage(j) # the focus moves
|
|
2466
2484
|
if not self.buffer: # no buffers
|
|
2467
2485
|
wx.CallAfter(self.new_buffer) # Note: post-call to avoid a crash.
|
|
2468
|
-
|
|
2486
|
+
|
|
2469
2487
|
def delete_all_buffers(self):
|
|
2470
2488
|
"""Initialize list of buffers."""
|
|
2471
2489
|
self.DeleteAllPages()
|
|
2472
2490
|
wx.CallAfter(self.new_buffer) # Note: post-call to avoid a crash.
|
|
2473
|
-
|
|
2491
|
+
|
|
2474
2492
|
def next_buffer(self):
|
|
2475
2493
|
if self.Selection < self.PageCount - 1:
|
|
2476
2494
|
self.Selection += 1
|
|
@@ -2481,7 +2499,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2481
2499
|
other_editor = books[k+1]
|
|
2482
2500
|
other_editor.Selection = 0
|
|
2483
2501
|
other_editor.CurrentPage.SetFocus()
|
|
2484
|
-
|
|
2502
|
+
|
|
2485
2503
|
def previous_buffer(self):
|
|
2486
2504
|
if self.Selection > 0:
|
|
2487
2505
|
self.Selection -= 1
|
|
@@ -2492,7 +2510,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2492
2510
|
other_editor = books[k-1]
|
|
2493
2511
|
other_editor.Selection = other_editor.PageCount - 1
|
|
2494
2512
|
other_editor.CurrentPage.SetFocus()
|
|
2495
|
-
|
|
2513
|
+
|
|
2496
2514
|
## --------------------------------
|
|
2497
2515
|
## File I/O
|
|
2498
2516
|
## --------------------------------
|
|
@@ -2500,7 +2518,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2500
2518
|
"PY files (*.py)|*.py",
|
|
2501
2519
|
"ALL files (*.*)|*.*",
|
|
2502
2520
|
]
|
|
2503
|
-
|
|
2521
|
+
|
|
2504
2522
|
def load_cache(self, filename, lineno=0):
|
|
2505
2523
|
"""Load a file from cache using linecache.
|
|
2506
2524
|
Note:
|
|
@@ -2521,7 +2539,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2521
2539
|
self.swap_buffer(buf, lineno)
|
|
2522
2540
|
return True
|
|
2523
2541
|
return False
|
|
2524
|
-
|
|
2542
|
+
|
|
2525
2543
|
def load_file(self, filename, lineno=0, verbose=True, **kwargs):
|
|
2526
2544
|
"""Load a file into an existing or new buffer.
|
|
2527
2545
|
The requests module is required to use URL extension.
|
|
@@ -2560,7 +2578,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2560
2578
|
self.post_message("Failed to load:", e)
|
|
2561
2579
|
self.delete_buffer(buf)
|
|
2562
2580
|
return False
|
|
2563
|
-
|
|
2581
|
+
|
|
2564
2582
|
def find_file(self, filename=None):
|
|
2565
2583
|
"""Open the specified file."""
|
|
2566
2584
|
if not filename:
|
|
@@ -2577,7 +2595,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2577
2595
|
self.swap_buffer(buf)
|
|
2578
2596
|
self.post_message("New file.")
|
|
2579
2597
|
return retval
|
|
2580
|
-
|
|
2598
|
+
|
|
2581
2599
|
def save_file(self, filename, buf=None, verbose=True):
|
|
2582
2600
|
"""Save the current buffer to a file.
|
|
2583
2601
|
"""
|
|
@@ -2601,7 +2619,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2601
2619
|
except (OSError, UnicodeDecodeError) as e:
|
|
2602
2620
|
self.post_message("Failed to save:", e)
|
|
2603
2621
|
return False
|
|
2604
|
-
|
|
2622
|
+
|
|
2605
2623
|
def load_buffer(self, buf=None):
|
|
2606
2624
|
"""Confirm the load with the dialog."""
|
|
2607
2625
|
buf = buf or self.buffer
|
|
@@ -2614,7 +2632,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2614
2632
|
return None
|
|
2615
2633
|
else:
|
|
2616
2634
|
return self.load_file(buf.filename, buf.markline+1)
|
|
2617
|
-
|
|
2635
|
+
|
|
2618
2636
|
def save_buffer(self, buf=None):
|
|
2619
2637
|
"""Confirm the save with the dialog."""
|
|
2620
2638
|
buf = buf or self.buffer
|
|
@@ -2627,7 +2645,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2627
2645
|
return None
|
|
2628
2646
|
else:
|
|
2629
2647
|
return self.save_file(buf.filename, buf)
|
|
2630
|
-
|
|
2648
|
+
|
|
2631
2649
|
def save_buffer_as(self, buf=None):
|
|
2632
2650
|
"""Confirm the saveas with the dialog."""
|
|
2633
2651
|
buf = buf or self.buffer
|
|
@@ -2638,12 +2656,12 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2638
2656
|
style=wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dlg:
|
|
2639
2657
|
if dlg.ShowModal() == wx.ID_OK:
|
|
2640
2658
|
return self.save_file(dlg.Path, buf)
|
|
2641
|
-
|
|
2659
|
+
|
|
2642
2660
|
def save_all_buffers(self):
|
|
2643
2661
|
for buf in self.get_all_buffers():
|
|
2644
2662
|
if buf.need_buffer_save:
|
|
2645
2663
|
self.save_buffer(buf)
|
|
2646
|
-
|
|
2664
|
+
|
|
2647
2665
|
def kill_buffer(self, buf=None):
|
|
2648
2666
|
"""Confirm the close with the dialog."""
|
|
2649
2667
|
buf = buf or self.buffer
|
|
@@ -2657,7 +2675,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2657
2675
|
self.post_message("The close has been canceled.")
|
|
2658
2676
|
return None
|
|
2659
2677
|
self.delete_buffer(buf)
|
|
2660
|
-
|
|
2678
|
+
|
|
2661
2679
|
def kill_all_buffers(self):
|
|
2662
2680
|
for buf in self.get_all_buffers():
|
|
2663
2681
|
if buf.need_buffer_save:
|
|
@@ -2680,7 +2698,7 @@ class Interpreter(interpreter.Interpreter):
|
|
|
2680
2698
|
|
|
2681
2699
|
self.parent = interpShell
|
|
2682
2700
|
self.globals = self.locals
|
|
2683
|
-
|
|
2701
|
+
|
|
2684
2702
|
def runcode(self, code):
|
|
2685
2703
|
"""Execute a code object.
|
|
2686
2704
|
|
|
@@ -2696,7 +2714,7 @@ class Interpreter(interpreter.Interpreter):
|
|
|
2696
2714
|
## ex. KeyboardInterrupt:
|
|
2697
2715
|
if wx.IsBusy():
|
|
2698
2716
|
wx.EndBusyCursor()
|
|
2699
|
-
|
|
2717
|
+
|
|
2700
2718
|
def showtraceback(self):
|
|
2701
2719
|
"""Display the exception that just occurred.
|
|
2702
2720
|
|
|
@@ -2713,7 +2731,7 @@ class Interpreter(interpreter.Interpreter):
|
|
|
2713
2731
|
self.parent.handler('interp_error', v)
|
|
2714
2732
|
except AttributeError:
|
|
2715
2733
|
pass
|
|
2716
|
-
|
|
2734
|
+
|
|
2717
2735
|
def showsyntaxerror(self, filename=None, **kwargs):
|
|
2718
2736
|
"""Display the syntax error that just occurred.
|
|
2719
2737
|
|
|
@@ -2797,11 +2815,11 @@ class Nautilus(EditorInterface, Shell):
|
|
|
2797
2815
|
@property
|
|
2798
2816
|
def message(self):
|
|
2799
2817
|
return self.parent.message
|
|
2800
|
-
|
|
2818
|
+
|
|
2801
2819
|
@property
|
|
2802
2820
|
def target(self):
|
|
2803
2821
|
return self.__target
|
|
2804
|
-
|
|
2822
|
+
|
|
2805
2823
|
@target.setter
|
|
2806
2824
|
def target(self, obj):
|
|
2807
2825
|
"""Reset the shell target object; Rename the parent title.
|
|
@@ -2821,34 +2839,34 @@ class Nautilus(EditorInterface, Shell):
|
|
|
2821
2839
|
except AttributeError:
|
|
2822
2840
|
pass
|
|
2823
2841
|
self.parent.handler('title_window', obj)
|
|
2824
|
-
|
|
2842
|
+
|
|
2825
2843
|
@property
|
|
2826
2844
|
def locals(self):
|
|
2827
2845
|
return self.interp.locals
|
|
2828
|
-
|
|
2846
|
+
|
|
2829
2847
|
@locals.setter
|
|
2830
2848
|
def locals(self, v): # internal use only
|
|
2831
2849
|
self.interp.locals = v
|
|
2832
|
-
|
|
2850
|
+
|
|
2833
2851
|
@locals.deleter
|
|
2834
2852
|
def locals(self): # internal use only
|
|
2835
2853
|
self.interp.locals = self.__target.__dict__
|
|
2836
|
-
|
|
2854
|
+
|
|
2837
2855
|
@property
|
|
2838
2856
|
def globals(self):
|
|
2839
2857
|
return self.interp.globals
|
|
2840
|
-
|
|
2858
|
+
|
|
2841
2859
|
@globals.setter
|
|
2842
2860
|
def globals(self, v): # internal use only
|
|
2843
2861
|
self.interp.globals = v
|
|
2844
|
-
|
|
2862
|
+
|
|
2845
2863
|
@globals.deleter
|
|
2846
2864
|
def globals(self): # internal use only
|
|
2847
2865
|
self.interp.globals = self.__target.__dict__
|
|
2848
2866
|
self.interp.globals.update(self.__globals)
|
|
2849
|
-
|
|
2867
|
+
|
|
2850
2868
|
__globals = {}
|
|
2851
|
-
|
|
2869
|
+
|
|
2852
2870
|
def __init__(self, parent, target, name="root",
|
|
2853
2871
|
introText=None,
|
|
2854
2872
|
startupScript=None,
|
|
@@ -3113,16 +3131,16 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3113
3131
|
del self.red_arrow
|
|
3114
3132
|
|
|
3115
3133
|
self.__text = ''
|
|
3116
|
-
|
|
3134
|
+
|
|
3117
3135
|
def trace_position(self):
|
|
3118
3136
|
_text, lp = self.CurLine
|
|
3119
3137
|
self.message("{:>6d}:{} ({})".format(self.cline, lp, self.cpos), pane=-1)
|
|
3120
|
-
|
|
3138
|
+
|
|
3121
3139
|
def OnDestroy(self, evt):
|
|
3122
3140
|
if evt.EventObject is self:
|
|
3123
3141
|
self.handler('shell_deleted', self)
|
|
3124
3142
|
evt.Skip()
|
|
3125
|
-
|
|
3143
|
+
|
|
3126
3144
|
def OnUpdate(self, evt): #<wx._stc.StyledTextEvent>
|
|
3127
3145
|
if evt.Updated & (stc.STC_UPDATE_SELECTION | stc.STC_UPDATE_CONTENT):
|
|
3128
3146
|
self.trace_position()
|
|
@@ -3137,13 +3155,13 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3137
3155
|
if evt.Updated & stc.STC_UPDATE_CONTENT:
|
|
3138
3156
|
self.handler('shell_modified', self)
|
|
3139
3157
|
evt.Skip()
|
|
3140
|
-
|
|
3158
|
+
|
|
3141
3159
|
def OnCallTipClick(self, evt):
|
|
3142
3160
|
if self.CallTipActive():
|
|
3143
3161
|
self.CallTipCancel()
|
|
3144
3162
|
self.parent.handler('add_help', self._calltips[1])
|
|
3145
3163
|
evt.Skip()
|
|
3146
|
-
|
|
3164
|
+
|
|
3147
3165
|
def OnSpace(self, evt):
|
|
3148
3166
|
"""Called when space pressed."""
|
|
3149
3167
|
if not self.CanEdit():
|
|
@@ -3156,7 +3174,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3156
3174
|
self.handler('M-m pressed', None) # => call_module_autocomp
|
|
3157
3175
|
return
|
|
3158
3176
|
evt.Skip()
|
|
3159
|
-
|
|
3177
|
+
|
|
3160
3178
|
def OnBackspace(self, evt):
|
|
3161
3179
|
"""Called when backspace pressed.
|
|
3162
3180
|
Backspace-guard from autocomp eating over a prompt whitespace.
|
|
@@ -3165,7 +3183,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3165
3183
|
self.handler('quit', evt) # Don't eat backward prompt
|
|
3166
3184
|
return
|
|
3167
3185
|
evt.Skip()
|
|
3168
|
-
|
|
3186
|
+
|
|
3169
3187
|
@editable
|
|
3170
3188
|
def backward_kill_word(self): # (override)
|
|
3171
3189
|
if not self.SelectedText:
|
|
@@ -3181,7 +3199,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3181
3199
|
if self.cpos < q:
|
|
3182
3200
|
self.cpos = q # Don't skip back ps2:prompt
|
|
3183
3201
|
self.ReplaceSelection('')
|
|
3184
|
-
|
|
3202
|
+
|
|
3185
3203
|
@editable
|
|
3186
3204
|
def backward_kill_line(self): # (override)
|
|
3187
3205
|
if not self.SelectedText:
|
|
@@ -3198,7 +3216,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3198
3216
|
else:
|
|
3199
3217
|
self.WordLeftExtend() # Select cr/lf chunks
|
|
3200
3218
|
self.ReplaceSelection('')
|
|
3201
|
-
|
|
3219
|
+
|
|
3202
3220
|
def OnEnter(self, evt):
|
|
3203
3221
|
"""Called when enter pressed."""
|
|
3204
3222
|
if not self.CanEdit():
|
|
@@ -3228,7 +3246,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3228
3246
|
|
|
3229
3247
|
self.exec_cmdline()
|
|
3230
3248
|
## evt.Skip() # => processLine
|
|
3231
|
-
|
|
3249
|
+
|
|
3232
3250
|
def OnEnterDot(self, evt):
|
|
3233
3251
|
"""Called when dot [.] pressed."""
|
|
3234
3252
|
if not self.CanEdit():
|
|
@@ -3242,14 +3260,14 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3242
3260
|
elif lst in ('space', 'sep', 'lparen'):
|
|
3243
3261
|
self.ReplaceSelection('self')
|
|
3244
3262
|
elif lst not in ('moji', 'word', 'rparen') or rst == 'word':
|
|
3245
|
-
self.handler('quit', evt)
|
|
3263
|
+
self.handler('quit', evt) # Don't enter autocomp
|
|
3246
3264
|
evt.Skip()
|
|
3247
|
-
|
|
3265
|
+
|
|
3248
3266
|
def on_enter_escmap(self, evt):
|
|
3249
3267
|
self.__caret_mode = self.CaretPeriod
|
|
3250
3268
|
self.CaretPeriod = 0
|
|
3251
3269
|
self.message("ESC-")
|
|
3252
|
-
|
|
3270
|
+
|
|
3253
3271
|
def on_exit_escmap(self, evt):
|
|
3254
3272
|
self.CaretPeriod = self.__caret_mode
|
|
3255
3273
|
self.message("ESC {}".format(evt.key))
|
|
@@ -3258,13 +3276,13 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3258
3276
|
self.promptPosEnd = 0 # Enabale write(prompt).
|
|
3259
3277
|
self.prompt()
|
|
3260
3278
|
self.AnnotationClearAll()
|
|
3261
|
-
|
|
3279
|
+
|
|
3262
3280
|
def on_enter_notemode(self, evt):
|
|
3263
3281
|
self.noteMode = True
|
|
3264
3282
|
self.__caret_mode = self.CaretForeground
|
|
3265
3283
|
self.CaretForeground = 'red'
|
|
3266
3284
|
self.message("Note mode")
|
|
3267
|
-
|
|
3285
|
+
|
|
3268
3286
|
def on_exit_notemode(self, evt):
|
|
3269
3287
|
self.noteMode = False
|
|
3270
3288
|
self.CaretForeground = self.__caret_mode
|
|
@@ -3272,23 +3290,23 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3272
3290
|
self.promptPosEnd = 0 # Enabale write(prompt).
|
|
3273
3291
|
self.prompt()
|
|
3274
3292
|
self.message("")
|
|
3275
|
-
|
|
3293
|
+
|
|
3276
3294
|
def goto_next_white_arrow(self):
|
|
3277
3295
|
self.goto_next_marker(0b010) # next white-arrow
|
|
3278
|
-
|
|
3296
|
+
|
|
3279
3297
|
def goto_previous_white_arrow(self):
|
|
3280
3298
|
self.goto_previous_marker(0b010) # previous white-arrow
|
|
3281
|
-
|
|
3299
|
+
|
|
3282
3300
|
def goto_next_mark_arrow(self, selection=False):
|
|
3283
3301
|
self.goto_next_marker(0b110, selection) # next white/red-arrow
|
|
3284
|
-
|
|
3302
|
+
|
|
3285
3303
|
def goto_previous_mark_arrow(self, selection=False):
|
|
3286
3304
|
self.goto_previous_marker(0b110, selection) # previous white/red-arrow
|
|
3287
|
-
|
|
3305
|
+
|
|
3288
3306
|
## --------------------------------
|
|
3289
3307
|
## Magic caster of the shell
|
|
3290
3308
|
## --------------------------------
|
|
3291
|
-
|
|
3309
|
+
|
|
3292
3310
|
@classmethod
|
|
3293
3311
|
def magic(self, cmd):
|
|
3294
3312
|
"""Called before command pushed.
|
|
@@ -3300,7 +3318,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3300
3318
|
elif cmd[0] == '?': cmd = 'info({})'.format(cmd[1:])
|
|
3301
3319
|
elif cmd[0] == '!': cmd = 'sx({!r})'.format(cmd[1:])
|
|
3302
3320
|
return cmd
|
|
3303
|
-
|
|
3321
|
+
|
|
3304
3322
|
@classmethod
|
|
3305
3323
|
def magic_interpret(self, tokens):
|
|
3306
3324
|
"""Called when [Enter] command, or eval-time for tooltip.
|
|
@@ -3384,7 +3402,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3384
3402
|
|
|
3385
3403
|
lhs += c # store in lhs; no more processing
|
|
3386
3404
|
return lhs
|
|
3387
|
-
|
|
3405
|
+
|
|
3388
3406
|
def on_shell_deleted(self, shell):
|
|
3389
3407
|
"""Called before shell:self is killed.
|
|
3390
3408
|
Delete target shell to prevent referencing the dead shell.
|
|
@@ -3397,7 +3415,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3397
3415
|
except AttributeError:
|
|
3398
3416
|
pass
|
|
3399
3417
|
wx.CallAfter(_del)
|
|
3400
|
-
|
|
3418
|
+
|
|
3401
3419
|
def on_shell_activated(self, shell):
|
|
3402
3420
|
"""Called when the shell:self is activated.
|
|
3403
3421
|
Reset localvars assigned for the shell target. cf. target.setter.
|
|
@@ -3411,7 +3429,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3411
3429
|
except AttributeError:
|
|
3412
3430
|
pass
|
|
3413
3431
|
self.parent.handler('title_window', obj)
|
|
3414
|
-
|
|
3432
|
+
|
|
3415
3433
|
def on_shell_inactivated(self, shell):
|
|
3416
3434
|
"""Called when shell:self is inactivated.
|
|
3417
3435
|
Remove target localvars assigned for the shell target.
|
|
@@ -3420,7 +3438,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3420
3438
|
self.AutoCompCancel()
|
|
3421
3439
|
if self.CallTipActive():
|
|
3422
3440
|
self.CallTipCancel()
|
|
3423
|
-
|
|
3441
|
+
|
|
3424
3442
|
def on_text_input(self, text):
|
|
3425
3443
|
"""Called when [Enter] text (before push).
|
|
3426
3444
|
Mark points, reset history point, etc.
|
|
@@ -3431,7 +3449,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3431
3449
|
if text.rstrip():
|
|
3432
3450
|
self.__eolc_mark = self.eolc
|
|
3433
3451
|
self.historyIndex = -1
|
|
3434
|
-
|
|
3452
|
+
|
|
3435
3453
|
def on_text_output(self, text):
|
|
3436
3454
|
"""Called when [Enter] text (after push).
|
|
3437
3455
|
Set markers at the last command line.
|
|
@@ -3443,25 +3461,25 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3443
3461
|
err = re.findall(py_error_re, text, re.M)
|
|
3444
3462
|
self.add_marker(ln, 1 if not err else 2) # 1:white-arrow 2:red-arrow
|
|
3445
3463
|
return (not err)
|
|
3446
|
-
|
|
3464
|
+
|
|
3447
3465
|
def on_interp_error(self, e):
|
|
3448
3466
|
ln = self.LineFromPosition(self.bolc)
|
|
3449
3467
|
self.red_pointer = ln + e.lineno - 1
|
|
3450
|
-
|
|
3468
|
+
|
|
3451
3469
|
## --------------------------------
|
|
3452
3470
|
## Attributes of the shell
|
|
3453
3471
|
## --------------------------------
|
|
3454
|
-
|
|
3472
|
+
|
|
3455
3473
|
@property
|
|
3456
3474
|
def bolc(self):
|
|
3457
3475
|
"""Beginning of command-line."""
|
|
3458
3476
|
return self.promptPosEnd
|
|
3459
|
-
|
|
3477
|
+
|
|
3460
3478
|
@property
|
|
3461
3479
|
def eolc(self):
|
|
3462
3480
|
"""End of command-line."""
|
|
3463
3481
|
return self.TextLength
|
|
3464
|
-
|
|
3482
|
+
|
|
3465
3483
|
@property
|
|
3466
3484
|
def bol(self):
|
|
3467
3485
|
"""Beginning of line (override) excluding prompt."""
|
|
@@ -3471,16 +3489,16 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3471
3489
|
lp -= len(ps)
|
|
3472
3490
|
break
|
|
3473
3491
|
return self.cpos - lp
|
|
3474
|
-
|
|
3492
|
+
|
|
3475
3493
|
@property
|
|
3476
3494
|
def cmdline(self):
|
|
3477
3495
|
"""Full multi-line command in the current prompt."""
|
|
3478
3496
|
return self.GetTextRange(self.bolc, self.eolc)
|
|
3479
|
-
|
|
3497
|
+
|
|
3480
3498
|
## cf. getCommand() -> caret-line that starts with a prompt
|
|
3481
3499
|
## cf. getMultilineCommand() -> caret-multi-line that starts with a prompt
|
|
3482
3500
|
## [BUG ver 4.1.1] Don't use for current prompt --> Fixed in wx ver 4.2.0.
|
|
3483
|
-
|
|
3501
|
+
|
|
3484
3502
|
def getMultilineCommand(self, rstrip=True):
|
|
3485
3503
|
"""Extract a multi-line command which starts with a prompt.
|
|
3486
3504
|
|
|
@@ -3498,7 +3516,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3498
3516
|
command = command.replace('\n', os.linesep + sys.ps2)
|
|
3499
3517
|
return command
|
|
3500
3518
|
return ''
|
|
3501
|
-
|
|
3519
|
+
|
|
3502
3520
|
def get_command_region(self, line):
|
|
3503
3521
|
"""Line numbers of prompt head and tail containing the line."""
|
|
3504
3522
|
lc = line
|
|
@@ -3516,11 +3534,11 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3516
3534
|
break
|
|
3517
3535
|
le += 1
|
|
3518
3536
|
return lc, le
|
|
3519
|
-
|
|
3537
|
+
|
|
3520
3538
|
## --------------------------------
|
|
3521
3539
|
## Execution methods of the shell
|
|
3522
3540
|
## --------------------------------
|
|
3523
|
-
|
|
3541
|
+
|
|
3524
3542
|
def push(self, command, **kwargs):
|
|
3525
3543
|
"""Send command to the interpreter for execution.
|
|
3526
3544
|
|
|
@@ -3528,7 +3546,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3528
3546
|
"""
|
|
3529
3547
|
self.on_text_input(command)
|
|
3530
3548
|
Shell.push(self, command, **kwargs)
|
|
3531
|
-
|
|
3549
|
+
|
|
3532
3550
|
def addHistory(self, command):
|
|
3533
3551
|
"""Add command to the command history.
|
|
3534
3552
|
|
|
@@ -3558,7 +3576,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3558
3576
|
## execStartupScript 実行時は出力先 (owner) が存在しない
|
|
3559
3577
|
## shell.__init__ よりも先に実行される
|
|
3560
3578
|
pass
|
|
3561
|
-
|
|
3579
|
+
|
|
3562
3580
|
def setBuiltinKeywords(self):
|
|
3563
3581
|
"""Create pseudo keywords as part of builtins.
|
|
3564
3582
|
|
|
@@ -3569,7 +3587,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3569
3587
|
builtins.ls = ls
|
|
3570
3588
|
builtins.pwd = pwd
|
|
3571
3589
|
builtins.sx = sx
|
|
3572
|
-
|
|
3590
|
+
|
|
3573
3591
|
def execStartupScript(self, su):
|
|
3574
3592
|
"""Execute the user's PYTHONSTARTUP script if they have one.
|
|
3575
3593
|
|
|
@@ -3588,7 +3606,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3588
3606
|
self.push("")
|
|
3589
3607
|
self.interp.startupScript = None
|
|
3590
3608
|
self.__globals = {k: self.locals[k] for k in (self.locals.keys() - keys)}
|
|
3591
|
-
|
|
3609
|
+
|
|
3592
3610
|
def Paste(self, rectangle=False):
|
|
3593
3611
|
"""Replace selection with clipboard contents.
|
|
3594
3612
|
|
|
@@ -3612,7 +3630,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3612
3630
|
command = command.replace('\n', os.linesep + ps)
|
|
3613
3631
|
self.ReplaceSelection(command)
|
|
3614
3632
|
wx.TheClipboard.Close()
|
|
3615
|
-
|
|
3633
|
+
|
|
3616
3634
|
def regulate_cmd(self, text):
|
|
3617
3635
|
"""Regulate text to executable command.
|
|
3618
3636
|
|
|
@@ -3626,14 +3644,14 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3626
3644
|
return (text.replace(os.linesep + sys.ps1, lf)
|
|
3627
3645
|
.replace(os.linesep + sys.ps2, lf)
|
|
3628
3646
|
.replace(os.linesep, lf))
|
|
3629
|
-
|
|
3647
|
+
|
|
3630
3648
|
def clear(self):
|
|
3631
3649
|
"""Delete all text (override) put new prompt."""
|
|
3632
3650
|
self.ClearAll()
|
|
3633
3651
|
self.promptPosStart = 0
|
|
3634
3652
|
self.promptPosEnd = 0
|
|
3635
3653
|
self.prompt()
|
|
3636
|
-
|
|
3654
|
+
|
|
3637
3655
|
def write(self, text, pos=None):
|
|
3638
3656
|
"""Display text in the shell.
|
|
3639
3657
|
|
|
@@ -3645,29 +3663,29 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3645
3663
|
self.goto_char(pos)
|
|
3646
3664
|
if self.CanEdit():
|
|
3647
3665
|
Shell.write(self, text) # => AddText
|
|
3648
|
-
|
|
3666
|
+
|
|
3649
3667
|
## input = classmethod(Shell.ask)
|
|
3650
|
-
|
|
3668
|
+
|
|
3651
3669
|
def info(self, obj):
|
|
3652
3670
|
"""Short information."""
|
|
3653
3671
|
doc = inspect.getdoc(obj)\
|
|
3654
3672
|
or "No information about {}".format(obj)
|
|
3655
3673
|
self.parent.handler('add_help', doc, typename(obj)) or print(doc)
|
|
3656
|
-
|
|
3674
|
+
|
|
3657
3675
|
def help(self, obj):
|
|
3658
3676
|
"""Full description."""
|
|
3659
3677
|
doc = pydoc.plain(pydoc.render_doc(obj))\
|
|
3660
3678
|
or "No description about {}".format(obj)
|
|
3661
3679
|
self.parent.handler('add_help', doc, typename(obj)) or print(doc)
|
|
3662
|
-
|
|
3680
|
+
|
|
3663
3681
|
def eval(self, text):
|
|
3664
3682
|
return eval(text, self.globals, self.locals)
|
|
3665
|
-
|
|
3683
|
+
|
|
3666
3684
|
def exec(self, text):
|
|
3667
3685
|
exec(text, self.globals, self.locals)
|
|
3668
3686
|
dispatcher.send(signal='Interpreter.push',
|
|
3669
3687
|
sender=self, command=None, more=False)
|
|
3670
|
-
|
|
3688
|
+
|
|
3671
3689
|
def exec_cmdline(self):
|
|
3672
3690
|
"""Execute command-line directly.
|
|
3673
3691
|
|
|
@@ -3719,7 +3737,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3719
3737
|
for cmd in commands:
|
|
3720
3738
|
self.write(cmd)
|
|
3721
3739
|
self.processLine()
|
|
3722
|
-
|
|
3740
|
+
|
|
3723
3741
|
def eval_line(self):
|
|
3724
3742
|
"""Evaluate the selected word or line and show calltips."""
|
|
3725
3743
|
if self.CallTipActive():
|
|
@@ -3747,7 +3765,7 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3747
3765
|
return
|
|
3748
3766
|
if not text:
|
|
3749
3767
|
self.message("No words")
|
|
3750
|
-
|
|
3768
|
+
|
|
3751
3769
|
def exec_region(self):
|
|
3752
3770
|
"""Execute a region of code."""
|
|
3753
3771
|
if self.CallTipActive():
|