mwxlib 1.4.12__py3-none-any.whl → 1.4.20__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
@@ -1,9 +1,9 @@
1
1
  #! python3
2
2
  """mwxlib Nautilus in the shell.
3
3
  """
4
+ from contextlib import contextmanager
4
5
  from functools import wraps
5
6
  from importlib import import_module
6
- from contextlib import contextmanager
7
7
  from pathlib import Path
8
8
  from pprint import pformat
9
9
  from bdb import BdbQuit
@@ -61,6 +61,7 @@ class Stylus:
61
61
  stc.STC_STYLE_BRACELIGHT : "fore:#000000,back:#ffffb8,bold",
62
62
  stc.STC_STYLE_BRACEBAD : "fore:#000000,back:#ff0000,bold",
63
63
  stc.STC_STYLE_CONTROLCHAR : "size:6",
64
+ stc.STC_STYLE_INDENTGUIDE : "",
64
65
  stc.STC_STYLE_CARETLINE : "fore:#000000,back:#ffff7f,size:2", # optional
65
66
  stc.STC_STYLE_ANNOTATION : "fore:#7f0000,back:#ff7f7f", # optional
66
67
  stc.STC_P_DEFAULT : "fore:#000000",
@@ -69,11 +70,11 @@ class Stylus:
69
70
  stc.STC_P_COMMENTLINE : "fore:#007f7f,back:#ffcfcf",
70
71
  stc.STC_P_COMMENTBLOCK : "fore:#007f7f,back:#ffcfcf,eol",
71
72
  stc.STC_P_NUMBER : "fore:#7f0000",
72
- stc.STC_P_STRINGEOL : "fore:#000000,back:#ffcfcf",
73
73
  stc.STC_P_CHARACTER : "fore:#7f7f7f",
74
74
  stc.STC_P_STRING : "fore:#7f7f7f",
75
75
  stc.STC_P_TRIPLE : "fore:#7f7f7f",
76
76
  stc.STC_P_TRIPLEDOUBLE : "fore:#7f7f7f",
77
+ stc.STC_P_STRINGEOL : "fore:#000000,back:#ffcfcf,eol",
77
78
  stc.STC_P_CLASSNAME : "fore:#7f00ff,bold",
78
79
  stc.STC_P_DEFNAME : "fore:#0000ff,bold",
79
80
  stc.STC_P_WORD : "fore:#0000ff",
@@ -87,6 +88,7 @@ class Stylus:
87
88
  stc.STC_STYLE_BRACELIGHT : "fore:#000000,back:#cccccc,bold",
88
89
  stc.STC_STYLE_BRACEBAD : "fore:#000000,back:#ff0000,bold",
89
90
  stc.STC_STYLE_CONTROLCHAR : "size:6",
91
+ stc.STC_STYLE_INDENTGUIDE : "",
90
92
  stc.STC_STYLE_CARETLINE : "fore:#000000,back:#f0f0ff,size:2", # optional
91
93
  stc.STC_STYLE_ANNOTATION : "fore:#7f0000,back:#ff7f7f", # optional
92
94
  stc.STC_P_DEFAULT : "fore:#000000",
@@ -95,11 +97,11 @@ class Stylus:
95
97
  stc.STC_P_COMMENTLINE : "fore:#007f00,back:#f0fff0",
96
98
  stc.STC_P_COMMENTBLOCK : "fore:#007f00,back:#f0fff0,eol",
97
99
  stc.STC_P_NUMBER : "fore:#e02000",
98
- stc.STC_P_STRINGEOL : "fore:#7f7f7f,back:#ffc0c0,eol",
99
100
  stc.STC_P_CHARACTER : "fore:#7f7f7f",
100
101
  stc.STC_P_STRING : "fore:#7f7f7f",
101
102
  stc.STC_P_TRIPLE : "fore:#7f7f7f",
102
103
  stc.STC_P_TRIPLEDOUBLE : "fore:#7f7f7f",
104
+ stc.STC_P_STRINGEOL : "fore:#7f7f7f,back:#ffc0c0,eol",
103
105
  stc.STC_P_CLASSNAME : "fore:#7f00ff,bold",
104
106
  stc.STC_P_DEFNAME : "fore:#0000ff,bold",
105
107
  stc.STC_P_WORD : "fore:#0000ff",
@@ -113,6 +115,7 @@ class Stylus:
113
115
  stc.STC_STYLE_BRACELIGHT : "fore:#ffffff,back:#202020,bold",
114
116
  stc.STC_STYLE_BRACEBAD : "fore:#ffffff,back:#ff0000,bold",
115
117
  stc.STC_STYLE_CONTROLCHAR : "size:6",
118
+ stc.STC_STYLE_INDENTGUIDE : "",
116
119
  stc.STC_STYLE_CARETLINE : "fore:#ffffff,back:#123460,size:2", # optional
117
120
  stc.STC_STYLE_ANNOTATION : "fore:#7f0000,back:#ff7f7f", # optional
118
121
  stc.STC_P_DEFAULT : "fore:#cccccc",
@@ -121,11 +124,11 @@ class Stylus:
121
124
  stc.STC_P_COMMENTLINE : "fore:#42c18c,back:#004040",
122
125
  stc.STC_P_COMMENTBLOCK : "fore:#42c18c,back:#004040,eol",
123
126
  stc.STC_P_NUMBER : "fore:#ffc080",
124
- stc.STC_P_STRINGEOL : "fore:#cccccc,back:#004040,eol",
125
127
  stc.STC_P_CHARACTER : "fore:#a0a0a0",
126
- stc.STC_P_STRING : "fore:#a0a0a0",
127
- stc.STC_P_TRIPLE : "fore:#a0a0a0,back:#004040",
128
- stc.STC_P_TRIPLEDOUBLE : "fore:#a0a0a0,back:#004040",
128
+ stc.STC_P_STRING : "fore:#a0c0ff",
129
+ stc.STC_P_TRIPLE : "fore:#a0a0a0",
130
+ stc.STC_P_TRIPLEDOUBLE : "fore:#a0c0ff",
131
+ stc.STC_P_STRINGEOL : "fore:#cccccc,back:#400000,eol",
129
132
  stc.STC_P_CLASSNAME : "fore:#61d6d6,bold",
130
133
  stc.STC_P_DEFNAME : "fore:#3a96ff,bold",
131
134
  stc.STC_P_WORD : "fore:#80c0ff",
@@ -201,7 +204,10 @@ class AutoCompInterfaceMixin:
201
204
  super().CallTipShow(pos, tip)
202
205
 
203
206
  def autoCallTipShow(self, command, insertcalltip=True):
204
- """Display argument spec and docstring in a popup window."""
207
+ """Display argument spec and docstring in a popup window.
208
+
209
+ (override) Fix cursor position on calltip insertion.
210
+ """
205
211
  if self.CallTipActive():
206
212
  self.CallTipCancel()
207
213
 
@@ -288,9 +294,17 @@ class AutoCompInterfaceMixin:
288
294
 
289
295
  def _get_words_hint(self):
290
296
  cmdl = self.GetTextRange(self.bol, self.cpos)
291
- text = next(split_words(cmdl, reverse=1), '')
297
+ if cmdl.endswith(' '): # 前の文字が空白の場合はスキップする
298
+ text = ''
299
+ else:
300
+ text = next(split_words(cmdl, reverse=1), '')
292
301
  return text.rpartition('.') # -> text, sep, hint
293
302
 
303
+ def clear_autocomp(self, evt):
304
+ if self.AutoCompActive():
305
+ self.AutoCompCancel()
306
+ self.message("")
307
+
294
308
  def call_history_comp(self, evt):
295
309
  """Called when history-comp mode."""
296
310
  if not self.CanEdit():
@@ -345,8 +359,9 @@ class AutoCompInterfaceMixin:
345
359
  return lh
346
360
 
347
361
  cmdl = self.GetTextRange(self.bol, self.cpos)
348
- hint = re.search(r"[\w.]*$", cmdl).group(0) # extract the last word
362
+ hint = re.search(r"[\w.]*$", cmdl).group(0) # extract the last word including dots
349
363
  try:
364
+ ## from * import ...
350
365
  if (m := re.match(r"from\s+([\w.]+)\s+import\s+(.*)", cmdl)):
351
366
  text, hints = m.groups()
352
367
  if not _continue(hints) and not force:
@@ -366,13 +381,14 @@ class AutoCompInterfaceMixin:
366
381
  q = f"{text}.{hint}".lower()
367
382
  keys = [x[len(text)+1:] for x in self.modules if x.lower().startswith(q)]
368
383
  modules.update(k for k in keys if '.' not in k)
369
-
384
+ ## import ...
370
385
  elif (m := re.match(r"(import|from)\s+(.*)", cmdl)):
371
386
  text, hints = m.groups()
372
387
  if not _continue(hints) and not force:
373
388
  self.message("[module]>>> waiting for key input...")
374
389
  return
375
390
  modules = self.modules
391
+ ## Module X.Y.Z
376
392
  else:
377
393
  text, sep, hint = self._get_words_hint()
378
394
  obj = self.eval(text)
@@ -401,11 +417,15 @@ class AutoCompInterfaceMixin:
401
417
  if not self.CanEdit():
402
418
  self.handler('quit', evt)
403
419
  return
420
+
421
+ text, sep, hint = self._get_words_hint()
422
+ if not text:
423
+ self.handler('quit', evt)
424
+ self.message("- No autocompletion candidates or hints found.")
425
+ return
404
426
  try:
405
- text, sep, hint = self._get_words_hint()
406
- obj = self.eval(text)
407
427
  ## dir = introspect.getAttributeNames @TODO in wx ver 4.2.3
408
-
428
+ obj = self.eval(text)
409
429
  P = re.compile(hint)
410
430
  p = re.compile(hint, re.I)
411
431
  words = sorted([x for x in dir(obj) if p.match(x)], key=lambda s:s.upper())
@@ -429,11 +449,15 @@ class AutoCompInterfaceMixin:
429
449
  if not self.CanEdit():
430
450
  self.handler('quit', evt)
431
451
  return
452
+
453
+ text, sep, hint = self._get_words_hint()
454
+ if not text:
455
+ self.handler('quit', evt)
456
+ self.message("- No autocompletion candidates or hints found.")
457
+ return
432
458
  try:
433
- text, sep, hint = self._get_words_hint()
434
- obj = self.eval(text)
435
459
  ## dir = introspect.getAttributeNames @TODO in wx ver 4.2.3.
436
-
460
+ obj = self.eval(text)
437
461
  P = re.compile(hint)
438
462
  p = re.compile(hint, re.I)
439
463
  words = sorted([x for x in dir(obj) if p.search(x)], key=lambda s:s.upper())
@@ -559,7 +583,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
559
583
  self.SetKeyWords(1, ' '.join(builtins.__dict__)
560
584
  + ' '.join(_dunders(type, int, float, str, bytes,
561
585
  tuple, list, range, operator,))
562
- + ' self this')
586
+ + ' self this shell')
563
587
 
564
588
  ## AutoComp setting
565
589
  self.AutoCompSetAutoHide(False)
@@ -578,16 +602,16 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
578
602
  ## Global style for all languages
579
603
  ## font = wx.Font(9, wx.MODERN, wx.NORMAL, wx.NORMAL, False, "MS Gothic")
580
604
  ## self.StyleSetFont(stc.STC_STYLE_DEFAULT, font)
581
-
582
605
  ## self.StyleClearAll()
583
- ## self.SetSelForeground(True, wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
584
- ## self.SetSelBackground(True, wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT))
606
+ ## => STC_STYLE_DEFAULT に設定したスタイルを他のスタイルに全適用する
585
607
 
586
608
  ## The magin style for line numbers and symbols
587
609
  ## [0] for markers, 10 pixels wide, mask 0b11111
588
610
  ## [1] for numbers, 32 pixels wide, mask 0x01ffffff (~stc.STC_MASK_FOLDERS)
589
611
  ## [2] for borders, 1 pixels wide, mask 0xfe000000 ( stc.STC_MASK_FOLDERS)
590
-
612
+ ##
613
+ ## cf. `EditWindow.setDisplayLineNumbers`
614
+ ##
591
615
  ## 32 bit margin mask
592
616
  ## [0] 1111,1111,1111,1111,1111,1111,1111,1111 = -1 for all markers
593
617
  ## [1] 0000,0001,1111,1111,1111,1111,1111,1111 = 0x01ffffff for markers
@@ -610,7 +634,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
610
634
 
611
635
  self.SetMarginLeft(2) # +1 margin at the left
612
636
 
613
- self.SetFoldFlags(0x10) # draw below if not expanded
637
+ self.SetFoldFlags(stc.STC_FOLDFLAG_LINEAFTER_CONTRACTED)
614
638
 
615
639
  self.SetProperty('fold', '1') # Enable folder property
616
640
 
@@ -724,7 +748,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
724
748
 
725
749
  def add_marker(self, line, n):
726
750
  if self.MarkerAdd(line, n):
727
- self.EnsureVisible(line) # expand if folded
751
+ self.EnsureVisible(line) # expand if folded
728
752
  self.handler('{}_set'.format(self.marker_names[n]), line)
729
753
 
730
754
  def del_marker(self, n):
@@ -736,7 +760,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
736
760
  def goto_marker(self, markerMask, selection=False):
737
761
  line = self.MarkerNext(0, markerMask)
738
762
  if line != -1:
739
- self.EnsureVisible(line) # expand if folded
763
+ self.EnsureVisible(line) # expand if folded
740
764
  self.goto_line(line, selection)
741
765
  self.recenter()
742
766
 
@@ -867,7 +891,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
867
891
  return sty
868
892
 
869
893
  def get_char(self, pos):
870
- """Returns the character at the given position."""
894
+ """Return the character at the given position."""
871
895
  return chr(self.GetCharAt(pos))
872
896
 
873
897
  def get_text(self, start, end):
@@ -1018,7 +1042,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1018
1042
 
1019
1043
  @classmethod
1020
1044
  def py_calc_indentation(self, text):
1021
- """Returns indent spaces for the command text."""
1045
+ """Return indent spaces for the command text."""
1022
1046
  text = self.py_strip_comments(text)
1023
1047
  lstr, indent = self.py_strip_indents(text)
1024
1048
  text = text.rstrip()
@@ -1032,7 +1056,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1032
1056
 
1033
1057
  @classmethod
1034
1058
  def py_strip_indents(self, text):
1035
- """Returns left-stripped text and the number of indent spaces."""
1059
+ """Return left-stripped text and the number of indent spaces."""
1036
1060
  text = self.py_strip_prompts(text) # cf. shell.lstripPrompt(text)
1037
1061
  lstr = text.lstrip(' \t')
1038
1062
  indent = len(text) - len(lstr)
@@ -1040,7 +1064,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1040
1064
 
1041
1065
  @classmethod
1042
1066
  def py_strip_prompts(self, text):
1043
- """Returns text without a leading prompt."""
1067
+ """Return text without a leading prompt."""
1044
1068
  for ps in (sys.ps1, sys.ps2, sys.ps3):
1045
1069
  if text.startswith(ps):
1046
1070
  text = text[len(ps):]
@@ -1049,7 +1073,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1049
1073
 
1050
1074
  @classmethod
1051
1075
  def py_strip_comments(self, text):
1052
- """Returns text without comments."""
1076
+ """Return text without comments."""
1053
1077
  return ''.join(split_tokens(text, comment=False))
1054
1078
 
1055
1079
  ## --------------------------------
@@ -1181,6 +1205,9 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1181
1205
  self.StyleSetSpec(stc.STC_STYLE_DEFAULT, default)
1182
1206
  self.StyleClearAll()
1183
1207
 
1208
+ self.SetSelForeground(True, wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
1209
+ self.SetSelBackground(True, wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT))
1210
+
1184
1211
  ## Add style to the folding margin
1185
1212
  item = _map(spec.get(stc.STC_STYLE_LINENUMBER, ''))
1186
1213
  if item:
@@ -1198,10 +1225,12 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1198
1225
  self.SetFoldMarginColour(True, item.get('fore'))
1199
1226
  self.SetFoldMarginHiColour(True, item.get('fore'))
1200
1227
 
1228
+ self.SetCaretLineVisible(0)
1229
+ self.SetCaretForeground(_map(default).get('fore'))
1230
+
1201
1231
  ## Custom style for caret and line colour
1202
1232
  item = _map(spec.pop(stc.STC_STYLE_CARETLINE, ''))
1203
1233
  if item:
1204
- self.SetCaretLineVisible(0)
1205
1234
  if 'fore' in item:
1206
1235
  self.SetCaretForeground(item['fore'])
1207
1236
  if 'back' in item:
@@ -1293,6 +1322,48 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1293
1322
  if not hl + offset < vl < hl + n - 1 - offset:
1294
1323
  self.ScrollToLine(vl - n//2)
1295
1324
 
1325
+ def DoFindNext(self, findData, findDlg=None):
1326
+ """Find the search text defined in `findData`.
1327
+
1328
+ If found, selects the matched text and scrolls to its line.
1329
+ Typically called from `wx.EVT_FIND` event handlers.
1330
+
1331
+ (override) Enables the whole word search.
1332
+ Returns True if a match is found, False otherwise.
1333
+ """
1334
+ flags = 0
1335
+ if findData.Flags & wx.FR_MATCHCASE: flags |= wx.stc.STC_FIND_MATCHCASE
1336
+ if findData.Flags & wx.FR_WHOLEWORD: flags |= wx.stc.STC_FIND_WHOLEWORD
1337
+ self.SetSearchFlags(flags)
1338
+
1339
+ backward = not (findData.Flags & wx.FR_DOWN)
1340
+ findstring = findData.FindString
1341
+ if backward:
1342
+ self.TargetStart = self.anchor # backward anchor
1343
+ self.TargetEnd = 0
1344
+ else:
1345
+ self.TargetStart = self.cpos # forward anchor
1346
+ self.TargetEnd = self.TextLength
1347
+ loc = self.SearchInTarget(findstring)
1348
+
1349
+ ## If it wasn't found then restart at beginning.
1350
+ if loc == -1:
1351
+ self.TargetStart = self.TextLength if backward else 0
1352
+ loc = self.SearchInTarget(findstring)
1353
+
1354
+ ## Was it still not found?
1355
+ if loc == -1:
1356
+ wx.MessageBox("Unable to find the search text.",
1357
+ "Not found!", wx.OK|wx.ICON_INFORMATION)
1358
+ if findDlg:
1359
+ wx.CallAfter(findDlg.SetFocus)
1360
+ return False
1361
+
1362
+ self.SetSelection(loc, loc + len(findstring))
1363
+ self.EnsureVisible(self.cline) # expand if folded
1364
+ self.EnsureCaretVisible()
1365
+ return True
1366
+
1296
1367
  ## --------------------------------
1297
1368
  ## Search functions
1298
1369
  ## --------------------------------
@@ -1407,17 +1478,22 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1407
1478
  if not text:
1408
1479
  self.message("No words")
1409
1480
  return
1410
- lw = len(text.encode()) # for multi-byte string
1481
+ wholeword = (not self.SelectedText) # Enable or disable whole word search.
1482
+ lw = len(text.encode())
1411
1483
  lines = []
1412
- for p in self.search_text(text, mode=(not self.SelectedText)):
1484
+ for p in self.search_text(text, wholeword):
1413
1485
  lines.append(self.LineFromPosition(p))
1414
1486
  for i in (10, 11,):
1415
1487
  self.SetIndicatorCurrent(i)
1416
1488
  self.IndicatorFillRange(p, lw)
1417
- self.__itextlines = sorted(set(lines)) # keep order, no duplication
1489
+ self.__itextlines = sorted(set(lines)) # keep order, no duplication
1418
1490
  self.message("{}: {} found".format(text, len(lines)))
1419
1491
  try:
1420
1492
  self.TopLevelParent.findData.FindString = text
1493
+ if wholeword:
1494
+ self.TopLevelParent.findData.Flags |= wx.FR_WHOLEWORD
1495
+ else:
1496
+ self.TopLevelParent.findData.Flags &= ~wx.FR_WHOLEWORD
1421
1497
  except AttributeError:
1422
1498
  pass
1423
1499
 
@@ -1453,7 +1529,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1453
1529
  evt.Skip()
1454
1530
  return
1455
1531
  line = self.__itextlines[i]
1456
- self.EnsureVisible(line) # expand if folded
1532
+ self.EnsureVisible(line) # expand if folded
1457
1533
  self.goto_line(line)
1458
1534
  self.recenter()
1459
1535
  self.on_itext_exit(evt)
@@ -1685,8 +1761,12 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1685
1761
  @editable
1686
1762
  def kill_line(self):
1687
1763
  if not self.SelectedText:
1688
- if self.cpos == self.eol:
1689
- self.WordRightEndExtend() # Select cr/lf
1764
+ p = self.cpos
1765
+ if p == self.eol:
1766
+ ## self.WordRightEndExtend() # Select cr/lf chunks
1767
+ if self.get_char(p) == '\r': p += 1
1768
+ if self.get_char(p) == '\n': p += 1
1769
+ self.cpos = p
1690
1770
  else:
1691
1771
  self.cpos = self.eol
1692
1772
  self.ReplaceSelection('')
@@ -1694,8 +1774,12 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1694
1774
  @editable
1695
1775
  def backward_kill_line(self):
1696
1776
  if not self.SelectedText:
1697
- if self.cpos == self.bol:
1698
- self.WordLeftExtend() # Select cr/lf
1777
+ p = self.cpos
1778
+ if p == self.bol:
1779
+ ## self.WordLeftExtend() # Select cr/lf chunks
1780
+ if self.get_char(p-1) == '\n': p -= 1
1781
+ if self.get_char(p-1) == '\r': p -= 1
1782
+ self.cpos = p
1699
1783
  else:
1700
1784
  self.cpos = self.bol
1701
1785
  self.ReplaceSelection('')
@@ -1783,14 +1867,14 @@ class Buffer(EditorInterface, EditWindow):
1783
1867
 
1784
1868
  @property
1785
1869
  def need_buffer_save(self):
1786
- """Returns whether the buffer should be saved.
1870
+ """Return whether the buffer should be saved.
1787
1871
  The file has been modified internally.
1788
1872
  """
1789
1873
  return self.mtdelta is not None and self.IsModified()
1790
1874
 
1791
1875
  @property
1792
1876
  def need_buffer_load(self):
1793
- """Returns whether the buffer should be loaded.
1877
+ """Return whether the buffer should be loaded.
1794
1878
  The file has been modified externally.
1795
1879
  """
1796
1880
  return self.mtdelta is not None and self.mtdelta > 0
@@ -1854,11 +1938,6 @@ class Buffer(EditorInterface, EditWindow):
1854
1938
  self.ReplaceSelection('')
1855
1939
  self.message("")
1856
1940
 
1857
- def clear_autocomp(evt):
1858
- if self.AutoCompActive():
1859
- self.AutoCompCancel()
1860
- self.message("")
1861
-
1862
1941
  def fork(evt):
1863
1942
  self.handler.fork(self.handler.current_event, evt)
1864
1943
 
@@ -1898,8 +1977,8 @@ class Buffer(EditorInterface, EditWindow):
1898
1977
  'M-/ pressed' : (3, self.call_apropos_autocomp),
1899
1978
  },
1900
1979
  2 : { # word auto completion AS-mode
1901
- 'quit' : (0, clear_autocomp),
1902
- '* pressed' : (0, clear_autocomp, fork),
1980
+ 'quit' : (0, self.clear_autocomp),
1981
+ '* pressed' : (0, self.clear_autocomp, fork),
1903
1982
  'tab pressed' : (0, clear, skip),
1904
1983
  'enter pressed' : (0, clear, skip),
1905
1984
  'escape pressed' : (0, clear, skip),
@@ -1917,7 +1996,7 @@ class Buffer(EditorInterface, EditWindow):
1917
1996
  '*delete pressed' : (2, skip),
1918
1997
  '*backspace pressed' : (2, skip),
1919
1998
  '*backspace released' : (2, self.call_word_autocomp),
1920
- '*S-backspace pressed' : (0, clear_autocomp, fork),
1999
+ '*S-backspace pressed' : (0, self.clear_autocomp, fork),
1921
2000
  '*alt pressed' : (2, ),
1922
2001
  '*ctrl pressed' : (2, ),
1923
2002
  '*shift pressed' : (2, ),
@@ -1925,8 +2004,8 @@ class Buffer(EditorInterface, EditWindow):
1925
2004
  '*f[0-9]* pressed' : (2, ),
1926
2005
  },
1927
2006
  3 : { # apropos auto completion AS-mode
1928
- 'quit' : (0, clear_autocomp),
1929
- '* pressed' : (0, clear_autocomp, fork),
2007
+ 'quit' : (0, self.clear_autocomp),
2008
+ '* pressed' : (0, self.clear_autocomp, fork),
1930
2009
  'tab pressed' : (0, clear, skip),
1931
2010
  'enter pressed' : (0, clear, skip),
1932
2011
  'escape pressed' : (0, clear, skip),
@@ -1944,7 +2023,7 @@ class Buffer(EditorInterface, EditWindow):
1944
2023
  '*delete pressed' : (3, skip),
1945
2024
  '*backspace pressed' : (3, skip),
1946
2025
  '*backspace released' : (3, self.call_apropos_autocomp),
1947
- '*S-backspace pressed' : (0, clear_autocomp, fork),
2026
+ '*S-backspace pressed' : (0, self.clear_autocomp, fork),
1948
2027
  '*alt pressed' : (3, ),
1949
2028
  '*ctrl pressed' : (3, ),
1950
2029
  '*shift pressed' : (3, ),
@@ -2017,6 +2096,9 @@ class Buffer(EditorInterface, EditWindow):
2017
2096
  evt.Skip()
2018
2097
 
2019
2098
  def OnEnterDot(self, evt):
2099
+ if not self.CanEdit():
2100
+ self.handler('quit', evt)
2101
+ return
2020
2102
  p = self.cpos
2021
2103
  lst = self.get_style(p-1)
2022
2104
  rst = self.get_style(p)
@@ -2116,6 +2198,7 @@ class Buffer(EditorInterface, EditWindow):
2116
2198
  sender=self, command=None, more=False)
2117
2199
 
2118
2200
  def eval_line(self):
2201
+ """Evaluate the selected word or line and show calltips."""
2119
2202
  if self.CallTipActive():
2120
2203
  self.CallTipCancel()
2121
2204
 
@@ -2140,6 +2223,7 @@ class Buffer(EditorInterface, EditWindow):
2140
2223
  self.message("No words")
2141
2224
 
2142
2225
  def exec_region(self):
2226
+ """Execute a region of code."""
2143
2227
  try:
2144
2228
  code = compile(self.Text, self.filename, "exec")
2145
2229
  exec(code, self.globals, self.locals)
@@ -2156,7 +2240,7 @@ class Buffer(EditorInterface, EditWindow):
2156
2240
  lx = lines[-1] - 1
2157
2241
  self.red_arrow = lx
2158
2242
  self.goto_line(lx)
2159
- self.EnsureVisible(lx) # expand if folded
2243
+ self.EnsureVisible(lx) # expand if folded
2160
2244
  self.EnsureCaretVisible()
2161
2245
  self.AnnotationSetStyle(lx, stc.STC_STYLE_ANNOTATION)
2162
2246
  self.AnnotationSetText(lx, msg)
@@ -2329,7 +2413,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
2329
2413
 
2330
2414
  @property
2331
2415
  def buffer(self):
2332
- """Returns the currently selected page or None."""
2416
+ """Return the currently selected page or None."""
2333
2417
  return self.CurrentPage
2334
2418
 
2335
2419
  def find_buffer(self, fn):
@@ -2484,7 +2568,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
2484
2568
  return all([self.find_file(fn) for fn in dlg.Paths])
2485
2569
  return None
2486
2570
  retval = self.load_file(filename)
2487
- if retval == False: # noqa: not None
2571
+ if retval == False: # noqa # to check if not None
2488
2572
  buf = self.create_buffer(filename)
2489
2573
  self.swap_buffer(buf)
2490
2574
  self.post_message("New file.")
@@ -2807,11 +2891,6 @@ class Nautilus(EditorInterface, Shell):
2807
2891
  self.ReplaceSelection('')
2808
2892
  self.message("")
2809
2893
 
2810
- def clear_autocomp(evt):
2811
- if self.AutoCompActive():
2812
- self.AutoCompCancel()
2813
- self.message("")
2814
-
2815
2894
  def fork(evt):
2816
2895
  self.handler.fork(self.handler.current_event, evt)
2817
2896
 
@@ -2867,10 +2946,10 @@ class Nautilus(EditorInterface, Shell):
2867
2946
  'M-j pressed' : (0, _F(self.exec_region)),
2868
2947
  'C-h pressed' : (0, self.call_helpTip),
2869
2948
  'M-h pressed' : (0, self.call_helpDoc),
2870
- '. pressed' : (2, self.OnEnterDot),
2871
2949
  'tab pressed' : (1, self.call_history_comp),
2872
2950
  'M-p pressed' : (1, self.call_history_comp),
2873
2951
  'M-n pressed' : (1, self.call_history_comp),
2952
+ '. pressed' : (2, self.OnEnterDot),
2874
2953
  'C-. pressed' : (2, self.call_word_autocomp),
2875
2954
  'C-/ pressed' : (3, self.call_apropos_autocomp),
2876
2955
  'C-, pressed' : (4, self.call_text_autocomp),
@@ -2906,8 +2985,8 @@ class Nautilus(EditorInterface, Shell):
2906
2985
  '*f[0-9]* pressed' : (1, ),
2907
2986
  },
2908
2987
  2 : { # word auto completion AS-mode
2909
- 'quit' : (0, clear_autocomp),
2910
- '* pressed' : (0, clear_autocomp, fork),
2988
+ 'quit' : (0, self.clear_autocomp),
2989
+ '* pressed' : (0, self.clear_autocomp, fork),
2911
2990
  'tab pressed' : (0, clear, skip),
2912
2991
  'enter pressed' : (0, clear, skip),
2913
2992
  'escape pressed' : (0, clear, skip),
@@ -2925,7 +3004,7 @@ class Nautilus(EditorInterface, Shell):
2925
3004
  '*delete pressed' : (2, skip),
2926
3005
  '*backspace pressed' : (2, self.OnBackspace),
2927
3006
  '*backspace released' : (2, self.call_word_autocomp),
2928
- '*S-backspace pressed' : (0, clear_autocomp, fork),
3007
+ '*S-backspace pressed' : (0, self.clear_autocomp, fork),
2929
3008
  'C-j pressed' : (2, _F(self.eval_line)),
2930
3009
  '*alt pressed' : (2, ),
2931
3010
  '*ctrl pressed' : (2, ),
@@ -2934,8 +3013,8 @@ class Nautilus(EditorInterface, Shell):
2934
3013
  '*f[0-9]* pressed' : (2, ),
2935
3014
  },
2936
3015
  3 : { # apropos auto completion AS-mode
2937
- 'quit' : (0, clear_autocomp),
2938
- '* pressed' : (0, clear_autocomp, fork),
3016
+ 'quit' : (0, self.clear_autocomp),
3017
+ '* pressed' : (0, self.clear_autocomp, fork),
2939
3018
  'tab pressed' : (0, clear, skip),
2940
3019
  'enter pressed' : (0, clear, skip),
2941
3020
  'escape pressed' : (0, clear, skip),
@@ -2953,7 +3032,7 @@ class Nautilus(EditorInterface, Shell):
2953
3032
  '*delete pressed' : (3, skip),
2954
3033
  '*backspace pressed' : (3, self.OnBackspace),
2955
3034
  '*backspace released' : (3, self.call_apropos_autocomp),
2956
- '*S-backspace pressed' : (0, clear_autocomp, fork),
3035
+ '*S-backspace pressed' : (0, self.clear_autocomp, fork),
2957
3036
  'C-j pressed' : (3, _F(self.eval_line)),
2958
3037
  '*alt pressed' : (3, ),
2959
3038
  '*ctrl pressed' : (3, ),
@@ -2962,8 +3041,8 @@ class Nautilus(EditorInterface, Shell):
2962
3041
  '*f[0-9]* pressed' : (3, ),
2963
3042
  },
2964
3043
  4 : { # text auto completion AS-mode
2965
- 'quit' : (0, clear_autocomp),
2966
- '* pressed' : (0, clear_autocomp, fork),
3044
+ 'quit' : (0, self.clear_autocomp),
3045
+ '* pressed' : (0, self.clear_autocomp, fork),
2967
3046
  'tab pressed' : (0, clear, skip),
2968
3047
  'enter pressed' : (0, clear, skip),
2969
3048
  'escape pressed' : (0, clear, skip),
@@ -2981,7 +3060,7 @@ class Nautilus(EditorInterface, Shell):
2981
3060
  '*delete pressed' : (4, skip),
2982
3061
  '*backspace pressed' : (4, self.OnBackspace),
2983
3062
  '*backspace released' : (4, self.call_text_autocomp),
2984
- '*S-backspace pressed' : (0, clear_autocomp, fork),
3063
+ '*S-backspace pressed' : (0, self.clear_autocomp, fork),
2985
3064
  'C-j pressed' : (4, _F(self.eval_line)),
2986
3065
  '*alt pressed' : (4, ),
2987
3066
  '*ctrl pressed' : (4, ),
@@ -2990,8 +3069,8 @@ class Nautilus(EditorInterface, Shell):
2990
3069
  '*f[0-9]* pressed' : (4, ),
2991
3070
  },
2992
3071
  5 : { # module auto completion AS-mode
2993
- 'quit' : (0, clear_autocomp),
2994
- '* pressed' : (0, clear_autocomp, fork),
3072
+ 'quit' : (0, self.clear_autocomp),
3073
+ '* pressed' : (0, self.clear_autocomp, fork),
2995
3074
  'tab pressed' : (0, clear, skip),
2996
3075
  'enter pressed' : (0, clear, skip),
2997
3076
  'escape pressed' : (0, clear, skip),
@@ -3006,11 +3085,12 @@ class Nautilus(EditorInterface, Shell):
3006
3085
  'S-[a-z\\] pressed' : (5, skip),
3007
3086
  'S-[a-z\\] released' : (5, self.call_module_autocomp),
3008
3087
  '\\ released' : (5, self.call_module_autocomp),
3088
+ 'C-m pressed' : (5, _F(self.call_module_autocomp, force=1)),
3009
3089
  'M-m pressed' : (5, _F(self.call_module_autocomp, force=1)),
3010
3090
  '*delete pressed' : (5, skip),
3011
3091
  '*backspace pressed' : (5, self.OnBackspace),
3012
3092
  '*backspace released' : (5, self.call_module_autocomp),
3013
- '*S-backspace pressed' : (0, clear_autocomp, fork),
3093
+ '*S-backspace pressed' : (0, self.clear_autocomp, fork),
3014
3094
  '*alt pressed' : (5, ),
3015
3095
  '*ctrl pressed' : (5, ),
3016
3096
  '*shift pressed' : (5, ),
@@ -3077,39 +3157,41 @@ class Nautilus(EditorInterface, Shell):
3077
3157
  Backspace-guard from autocomp eating over a prompt whitespace.
3078
3158
  """
3079
3159
  if self.cpos == self.bolc:
3080
- self.handler('quit', evt) # don't eat backward prompt
3160
+ self.handler('quit', evt) # Don't eat backward prompt
3081
3161
  return
3082
3162
  evt.Skip()
3083
3163
 
3084
3164
  @editable
3085
- def backward_kill_word(self): # (override)
3165
+ def backward_kill_word(self): # (override)
3086
3166
  if not self.SelectedText:
3167
+ if self.cpos <= self.bolc:
3168
+ return
3087
3169
  text, lp = self.CurLine
3088
3170
  if text[:lp] == sys.ps2:
3089
- self.cpos -= lp # Select ps2:prompt
3090
- self.WordLeftExtend() # Select cr/lf
3171
+ self.cpos -= lp # Select ps2:prompt
3172
+ self.WordLeftExtend() # Select cr/lf chunks
3091
3173
  else:
3092
- q = max(self.bol, self.bolc) # for debugger mode: bol <= bolc
3093
3174
  self.WordLeftExtend()
3175
+ q = max(self.bol, self.bolc) # for debugger mode: bol <= bolc
3094
3176
  if self.cpos < q:
3095
- self.cpos = q # Don't skip back prompt
3177
+ self.cpos = q # Don't skip back ps2:prompt
3096
3178
  self.ReplaceSelection('')
3097
3179
 
3098
3180
  @editable
3099
- def backward_kill_line(self): # (override)
3181
+ def backward_kill_line(self): # (override)
3100
3182
  if not self.SelectedText:
3183
+ if self.cpos <= self.bolc:
3184
+ return
3101
3185
  text, lp = self.CurLine
3102
3186
  if text[:lp] == sys.ps2:
3103
- self.cpos -= lp # Select ps2:prompt
3104
- self.WordLeftExtend() # Select cr/lf
3187
+ self.cpos -= lp # Select ps2:prompt
3188
+ self.WordLeftExtend() # Select cr/lf chunks
3105
3189
  else:
3106
3190
  q = max(self.bol, self.bolc) # for debugger mode: bol <= bolc
3107
- if self.cpos <= self.bolc:
3108
- return
3109
- elif self.cpos > q:
3191
+ if self.cpos > q:
3110
3192
  self.cpos = q
3111
3193
  else:
3112
- self.WordLeftExtend() # Select cr/lf
3194
+ self.WordLeftExtend() # Select cr/lf chunks
3113
3195
  self.ReplaceSelection('')
3114
3196
 
3115
3197
  def OnEnter(self, evt):
@@ -3626,7 +3708,7 @@ class Nautilus(EditorInterface, Shell):
3626
3708
  ## --------------------------------
3627
3709
 
3628
3710
  def eval_line(self):
3629
- """Evaluate the selected word or line."""
3711
+ """Evaluate the selected word or line and show calltips."""
3630
3712
  if self.CallTipActive():
3631
3713
  self.CallTipCancel()
3632
3714
 
@@ -3654,7 +3736,7 @@ class Nautilus(EditorInterface, Shell):
3654
3736
  self.message("No words")
3655
3737
 
3656
3738
  def exec_region(self):
3657
- """Execute the the selected region."""
3739
+ """Execute a region of code."""
3658
3740
  if self.CallTipActive():
3659
3741
  self.CallTipCancel()
3660
3742