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/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.set_pointer)),
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)) # [arrow_unset]
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)) # [red-arrow_unset]
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)) # [pointer_unset]
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)) # [red-pointer_unset]
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) # [mark_set]
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 set_pointer(self):
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(0)
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("^", prefix, self.SelectedText, flags=re.M)
1707
- ## Don't comment out the last (blank) line.
1708
- lines = text.splitlines()
1709
- if len(lines) > 1 and lines[-1].endswith(prefix):
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("^#+ ", "", self.SelectedText, flags=re.M)
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) # don't enter autocomp
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) # don't enter autocomp
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():