mwxlib 0.83.6__py3-none-any.whl → 0.83.8__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/framework.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Author: Kazuya O'moto <komoto@jeol.co.jp>
6
6
  """
7
- __version__ = "0.83.6"
7
+ __version__ = "0.83.8"
8
8
  __author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
9
9
 
10
10
  from functools import wraps, partial
@@ -1183,7 +1183,7 @@ class ShellFrame(MiniFrame):
1183
1183
 
1184
1184
  if flush:
1185
1185
  for book in self.get_all_pages(type(self.Log)):
1186
- book.remove_all_buffers()
1186
+ book.delete_all_buffers()
1187
1187
 
1188
1188
  self.SESSION_FILE = os.path.abspath(rc)
1189
1189
  try:
mwx/nutshell.py CHANGED
@@ -34,6 +34,19 @@ from .utilus import find_modules, deprecated
34
34
  from .framework import CtrlInterface, AuiNotebook, Menu
35
35
 
36
36
 
37
+ ## URL pattern (flag = re.M | re.A)
38
+ url_re = r"https?://[\w/:%#\$&\?()~.=+-]+"
39
+
40
+ ## Python syntax pattern
41
+ py_indent_re = r"if|else|elif|for|while|with|def|class|try|except|finally"
42
+ py_outdent_re = r"else:|elif\s+.*:|except(\s+.*)?:|finally:"
43
+ py_closing_re = r"break|pass|return|raise|continue"
44
+
45
+ ## Python interp traceback pattern
46
+ py_error_re = r"^\s+File \"(.*?)\", line ([0-9]+)"
47
+ py_frame_re = r"^\s+file \'(.*?)\', line ([0-9]+)"
48
+
49
+
37
50
  def skip(v):
38
51
  v.Skip()
39
52
 
@@ -278,6 +291,11 @@ class EditorInterface(CtrlInterface):
278
291
  ## Custom indicator [2] for match_paren
279
292
  self.IndicatorSetStyle(2, stc.STC_INDIC_DOTS)
280
293
  self.IndicatorSetForeground(2, "light gray")
294
+ try:
295
+ self.IndicatorSetHoverStyle(2, stc.STC_INDIC_PLAIN)
296
+ self.IndicatorSetHoverForeground(2, "light gray")
297
+ except AttributeError:
298
+ pass
281
299
 
282
300
  ## Custom annotation
283
301
  self.AnnotationSetVisible(stc.STC_ANNOTATION_BOXED)
@@ -585,10 +603,6 @@ class EditorInterface(CtrlInterface):
585
603
  ## --------------------------------
586
604
  ## Python syntax and indentation
587
605
  ## --------------------------------
588
- py_indent_re = r"if|else|elif|for|while|with|def|class|try|except|finally"
589
- py_outdent_re = r"else:|elif\s+.*:|except(\s+.*)?:|finally:"
590
- py_closing_re = r"break|pass|return|raise|continue"
591
-
592
606
  def on_indent_line(self, evt):
593
607
  if self.SelectedText:
594
608
  evt.Skip()
@@ -629,7 +643,7 @@ class EditorInterface(CtrlInterface):
629
643
  indent = self.py_calc_indentation(text) # check previous line
630
644
  text = self.GetLine(self.cline)
631
645
  lstr, _indent = self.py_strip_indents(text) # check current line
632
- if re.match(self.py_outdent_re, lstr):
646
+ if re.match(py_outdent_re, lstr):
633
647
  indent -= 4
634
648
  return indent
635
649
 
@@ -646,9 +660,9 @@ class EditorInterface(CtrlInterface):
646
660
  text = text.rstrip()
647
661
  if text.endswith('\\'):
648
662
  return indent + 2
649
- if text.endswith(':') and re.match(self.py_indent_re, lstr):
663
+ if text.endswith(':') and re.match(py_indent_re, lstr):
650
664
  return indent + 4
651
- if re.match(self.py_closing_re, lstr):
665
+ if re.match(py_closing_re, lstr):
652
666
  return indent - 4
653
667
  return indent
654
668
 
@@ -852,11 +866,6 @@ class EditorInterface(CtrlInterface):
852
866
  if item:
853
867
  self.IndicatorSetForeground(0, item.get('fore') or "red")
854
868
  self.IndicatorSetForeground(1, item.get('back') or "yellow")
855
- try:
856
- self.IndicatorSetHoverStyle(1, stc.STC_INDIC_ROUNDBOX)
857
- self.IndicatorSetHoverForeground(1, "blue")
858
- except AttributeError:
859
- pass
860
869
 
861
870
  ## Apply the rest of the style
862
871
  for key, value in spec.items():
@@ -1019,9 +1028,9 @@ class EditorInterface(CtrlInterface):
1019
1028
  p -= 1
1020
1029
  return p, q, st
1021
1030
 
1022
- def grep_forward(self, pattern):
1031
+ def grep_forward(self, pattern, flags=re.M):
1023
1032
  text = self.GetTextRange(self.eol, self.TextLength)
1024
- errs = re.finditer(pattern, text, re.M)
1033
+ errs = re.finditer(pattern, text, flags)
1025
1034
  for err in errs:
1026
1035
  p, q = err.span()
1027
1036
  self.goto_char(q + self.eol)
@@ -1030,9 +1039,9 @@ class EditorInterface(CtrlInterface):
1030
1039
  self.EnsureVisible(self.cline)
1031
1040
  yield err
1032
1041
 
1033
- def grep_barckward(self, pattern):
1042
+ def grep_barckward(self, pattern, flags=re.M):
1034
1043
  text = self.GetTextRange(0, self.cpos)
1035
- errs = re.finditer(pattern, text, re.M)
1044
+ errs = re.finditer(pattern, text, flags)
1036
1045
  for err in reversed(list(errs)):
1037
1046
  p, q = err.span()
1038
1047
  self.goto_char(p)
@@ -1041,6 +1050,10 @@ class EditorInterface(CtrlInterface):
1041
1050
  self.EnsureVisible(self.cline)
1042
1051
  yield err
1043
1052
 
1053
+ def grep(self, pattern, flags=re.M):
1054
+ text = self.GetTextRange(0, self.TextLength)
1055
+ yield from re.finditer(pattern, text, flags)
1056
+
1044
1057
  def search_text(self, text):
1045
1058
  """Yields raw-positions where `text` is found."""
1046
1059
  word = text.encode()
@@ -1441,7 +1454,7 @@ class Buffer(EditWindow, EditorInterface):
1441
1454
  f = self.filename
1442
1455
  if f and os.path.isfile(f):
1443
1456
  return os.path.getmtime(f) - self.__mtime
1444
- elif f and re.match(r"https?://[\w/:%#\$&\?()~.=+-]+", f):
1457
+ elif f and re.match(url_re, f):
1445
1458
  return -1
1446
1459
 
1447
1460
  @property
@@ -1493,6 +1506,8 @@ class Buffer(EditWindow, EditorInterface):
1493
1506
 
1494
1507
  self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdate) # skip to brace matching
1495
1508
 
1509
+ self.Bind(stc.EVT_STC_INDICATOR_CLICK, self.OnIndicatorClick)
1510
+
1496
1511
  self.Bind(stc.EVT_STC_SAVEPOINTLEFT, self.OnSavePointLeft)
1497
1512
  self.Bind(stc.EVT_STC_SAVEPOINTREACHED, self.OnSavePointReached)
1498
1513
 
@@ -1512,12 +1527,12 @@ class Buffer(EditWindow, EditorInterface):
1512
1527
 
1513
1528
  self.handler.update({ # DNA<Buffer>
1514
1529
  None : {
1515
- 'stc_updated' : [ None, ],
1516
- 'buffer_saved' : [ None, self.on_activated, dispatch ],
1517
- 'buffer_loaded' : [ None, self.on_activated, dispatch ],
1530
+ 'buffer_saved' : [ None, dispatch ],
1531
+ 'buffer_loaded' : [ None, dispatch ],
1532
+ 'buffer_modified' : [ None, self.on_modified, dispatch ],
1518
1533
  'buffer_activated' : [ None, self.on_activated, dispatch ],
1519
1534
  'buffer_inactivated' : [ None, self.on_inactivated, dispatch ],
1520
- 'py_region_executed' : [ None, self.on_activated ],
1535
+ 'buffer_region_executed' : [ None, ],
1521
1536
  },
1522
1537
  -1 : { # original action of the EditWindow
1523
1538
  '* pressed' : (0, skip, self.on_exit_escmap),
@@ -1548,9 +1563,30 @@ class Buffer(EditWindow, EditorInterface):
1548
1563
  def OnUpdate(self, evt): #<wx._stc.StyledTextEvent>
1549
1564
  if evt.Updated & (stc.STC_UPDATE_SELECTION | stc.STC_UPDATE_CONTENT):
1550
1565
  self.trace_position()
1551
- self.handler('stc_updated', evt)
1566
+ if evt.Updated & stc.STC_UPDATE_CONTENT:
1567
+ self.handler('buffer_modified', self)
1552
1568
  evt.Skip()
1553
1569
 
1570
+ def OnIndicatorClick(self, evt):
1571
+ if self.SelectedText:
1572
+ evt.Skip()
1573
+ return
1574
+ pos = evt.Position
1575
+ if self.IndicatorValueAt(2, pos):
1576
+ p = self.IndicatorStart(2, pos)
1577
+ q = self.IndicatorEnd(2, pos)
1578
+ text = self.GetTextRange(p, q).strip()
1579
+ ## Note: Do postcall a confirmation dialog.
1580
+ wx.CallAfter(self.parent.load_url, text)
1581
+
1582
+ def on_modified(self, buf):
1583
+ """Called when the buffer is modified."""
1584
+ self.SetIndicatorCurrent(2)
1585
+ self.IndicatorClearRange(0, self.TextLength)
1586
+ for m in self.grep(url_re):
1587
+ p, q = m.span()
1588
+ self.IndicatorFillRange(p, q-p)
1589
+
1554
1590
  def OnSavePointLeft(self, evt):
1555
1591
  if self.mtdelta is not None:
1556
1592
  self.parent.handler('buffer_caption_reset', self)
@@ -1670,7 +1706,7 @@ class Buffer(EditWindow, EditorInterface):
1670
1706
  sender=self, command=None, more=False)
1671
1707
  except Exception as e:
1672
1708
  msg = traceback.format_exc()
1673
- err = re.findall(r"^\s+File \"(.*?)\", line ([0-9]+)", msg, re.M)
1709
+ err = re.findall(py_error_re, msg, re.M)
1674
1710
  lines = [int(l) for f,l in err if f == filename]
1675
1711
  if lines:
1676
1712
  lx = lines[-1] - 1
@@ -1686,7 +1722,7 @@ class Buffer(EditWindow, EditorInterface):
1686
1722
  self.code = code
1687
1723
  del self.pointer # Reset pointer (debugger hook point).
1688
1724
  del self.red_arrow
1689
- self.handler('py_region_executed', self)
1725
+ self.handler('buffer_region_executed', self)
1690
1726
  self.message("Evaluated {!r} successfully".format(filename))
1691
1727
  self.AnnotationClearAll()
1692
1728
 
@@ -1743,7 +1779,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
1743
1779
  def destroy(v):
1744
1780
  obj = v.EventObject
1745
1781
  if isinstance(obj, Buffer):
1746
- self.handler('buffer_removed', obj)
1782
+ self.handler('buffer_deleted', obj)
1747
1783
  v.Skip()
1748
1784
  self.Bind(wx.EVT_WINDOW_DESTROY, destroy)
1749
1785
 
@@ -1759,7 +1795,8 @@ class EditorBook(AuiNotebook, CtrlInterface):
1759
1795
  'buffer_new' : [ None, dispatch, ],
1760
1796
  'buffer_saved' : [ None, dispatch, self.set_caption ],
1761
1797
  'buffer_loaded' : [ None, dispatch, self.set_caption ],
1762
- 'buffer_removed' : [ None, dispatch, ],
1798
+ 'buffer_deleted' : [ None, dispatch, ],
1799
+ 'buffer_modified' : [ None, dispatch, ],
1763
1800
  'buffer_activated' : [ None, dispatch, self.on_activated ],
1764
1801
  'buffer_inactivated' : [ None, dispatch, self.on_inactivated ],
1765
1802
  'buffer_caption_reset' : [ None, dispatch, self.set_caption ],
@@ -1772,8 +1809,6 @@ class EditorBook(AuiNotebook, CtrlInterface):
1772
1809
  '* released' : (0, skip),
1773
1810
  'M-up pressed' : (0, _F(self.previous_buffer)),
1774
1811
  'M-down pressed' : (0, _F(self.next_buffer)),
1775
- 'M-left pressed' : (0, dispatch),
1776
- 'M-right pressed' : (0, dispatch),
1777
1812
  },
1778
1813
  })
1779
1814
 
@@ -1901,7 +1936,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
1901
1936
  buf.SetFocus()
1902
1937
  return buf
1903
1938
 
1904
- def remove_buffer(self, buf=None):
1939
+ def delete_buffer(self, buf=None):
1905
1940
  """Pop the current buffer from the buffer list."""
1906
1941
  if not buf:
1907
1942
  buf = self.buffer
@@ -1911,7 +1946,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
1911
1946
  if not self.buffer: # no buffers
1912
1947
  self.new_buffer()
1913
1948
 
1914
- def remove_all_buffers(self):
1949
+ def delete_all_buffers(self):
1915
1950
  """Initialize list of buffers."""
1916
1951
  self.DeleteAllPages()
1917
1952
  self.new_buffer()
@@ -1989,7 +2024,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
1989
2024
  return False
1990
2025
  except Exception as e:
1991
2026
  self.post_message("Failed to load {!r}: {}".format(buf.name, e))
1992
- self.remove_buffer(buf)
2027
+ self.delete_buffer(buf)
1993
2028
  if org:
1994
2029
  self.swap_page(org)
1995
2030
  return False
@@ -2087,7 +2122,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
2087
2122
  style=wx.YES_NO|wx.ICON_INFORMATION) != wx.YES:
2088
2123
  self.post_message("The close has been canceled.")
2089
2124
  return None
2090
- wx.CallAfter(self.remove_buffer, buf)
2125
+ wx.CallAfter(self.delete_buffer, buf)
2091
2126
 
2092
2127
  def kill_all_buffers(self):
2093
2128
  for buf in self.all_buffers:
@@ -2100,7 +2135,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
2100
2135
  style=wx.YES_NO|wx.ICON_INFORMATION) != wx.YES:
2101
2136
  self.post_message("The close has been canceled.")
2102
2137
  return None
2103
- wx.CallAfter(self.remove_all_buffers)
2138
+ wx.CallAfter(self.delete_all_buffers)
2104
2139
 
2105
2140
 
2106
2141
  class Interpreter(interpreter.Interpreter):
@@ -2396,9 +2431,9 @@ class Nautilus(Shell, EditorInterface):
2396
2431
 
2397
2432
  self.handler.update({ # DNA<Nautilus>
2398
2433
  None : {
2399
- 'stc_updated' : [ None, ],
2400
2434
  'interp_error' : [ None, self.on_interp_error ],
2401
2435
  'shell_deleted' : [ None, dispatch, self.on_deleted ],
2436
+ 'shell_modified' : [ None, dispatch, ],
2402
2437
  'shell_activated' : [ None, dispatch, self.on_activated ],
2403
2438
  'shell_inactivated' : [ None, dispatch, self.on_inactivated ],
2404
2439
  '*button* pressed' : [ None, dispatch, skip ],
@@ -2628,7 +2663,8 @@ class Nautilus(Shell, EditorInterface):
2628
2663
  tip = tip.splitlines()[0]
2629
2664
  self.message(tip) # clear if no tip
2630
2665
  self.__text = text
2631
- self.handler('stc_updated', evt)
2666
+ if evt.Updated & stc.STC_UPDATE_CONTENT:
2667
+ self.handler('shell_modified', self)
2632
2668
  evt.Skip()
2633
2669
 
2634
2670
  def OnCallTipClick(self, evt):
@@ -2908,7 +2944,7 @@ class Nautilus(Shell, EditorInterface):
2908
2944
  Argument `text` is raw output:str with no magic cast.
2909
2945
  """
2910
2946
  ln = self.cmdline_region[0]
2911
- err = re.findall(r"^\s+File \"(.*?)\", line ([0-9]+)", text, re.M)
2947
+ err = re.findall(py_error_re, text, re.M)
2912
2948
  self.add_marker(ln, 1 if not err else 2) # 1:white-arrow 2:red-arrow
2913
2949
  return (not err)
2914
2950
 
@@ -3149,7 +3185,7 @@ class Nautilus(Shell, EditorInterface):
3149
3185
  lstr = line.lstrip()
3150
3186
  if (lstr and lstr == line # no indent
3151
3187
  and not lstr.startswith('#') # no comment
3152
- and not re.match(self.py_outdent_re, lstr)): # no outdent pattern
3188
+ and not re.match(py_outdent_re, lstr)): # no outdent pattern
3153
3189
  if cmd:
3154
3190
  commands.append(cmd) # Add stacked commands to the list
3155
3191
  cmd = line
@@ -3161,7 +3197,7 @@ class Nautilus(Shell, EditorInterface):
3161
3197
  if len(commands) > 1:
3162
3198
  suffix = sys.ps2
3163
3199
  for j, cmd in enumerate(commands):
3164
- if re.match(self.py_indent_re, cmd):
3200
+ if re.match(py_indent_re, cmd):
3165
3201
  ## multi-line code-block ends with [\r\n... ]
3166
3202
  if not cmd.endswith(os.linesep):
3167
3203
  cmd = cmd.rstrip('\r\n') + os.linesep
@@ -3191,7 +3227,7 @@ class Nautilus(Shell, EditorInterface):
3191
3227
  lstr = line.lstrip()
3192
3228
  if (lstr and lstr == line # no indent
3193
3229
  and not lstr.startswith('#') # no comment
3194
- and not re.match(self.py_outdent_re, lstr)): # no outdent pattern
3230
+ and not re.match(py_outdent_re, lstr)): # no outdent pattern
3195
3231
  if cmd:
3196
3232
  commands.append(cmd) # Add the previous command to the list
3197
3233
  cmd = line
@@ -3297,7 +3333,7 @@ class Nautilus(Shell, EditorInterface):
3297
3333
  self.exec(code)
3298
3334
  except Exception as e:
3299
3335
  msg = traceback.format_exc()
3300
- err = re.findall(r"^\s+File \"(.*?)\", line ([0-9]+)", msg, re.M)
3336
+ err = re.findall(py_error_re, msg, re.M)
3301
3337
  lines = [int(l) for f,l in err if f == filename]
3302
3338
  if lines:
3303
3339
  region = self.get_region(self.cline)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mwxlib
3
- Version: 0.83.6
3
+ Version: 0.83.8
4
4
  Summary: A wrapper of matplotlib and wxPython (phoenix)
5
5
  Home-page: https://github.com/komoto48g/mwxlib
6
6
  Author: Kazuya O'moto <komoto@jeol.co.jp>
@@ -1,13 +1,13 @@
1
1
  mwx/__init__.py,sha256=bSRdncjfSCKycMFQVnagOi9R2vUCC5snGkjea7jqPgU,2520
2
2
  mwx/controls.py,sha256=7hnSimA3bKDgTct29l6Hqpq7BCKqCeOjZJ6JQ1xjh7I,43445
3
- mwx/framework.py,sha256=RMhgj174gLaoLZFYBC74_25gD7Fp081eew5EeA7m0jk,73366
3
+ mwx/framework.py,sha256=7CbmEyVepYjv-DARsrmERJbiGXH8YNhD5WXz7iy-D28,73366
4
4
  mwx/graphman.py,sha256=Edw2pZKghWGkbR_AV9PDWQpZz6q8XstTL5Q-xDrAce4,69534
5
5
  mwx/images.py,sha256=9e8X7OpJ6Z3fF3ez17P_qk2D1NMO10-lN8TCtulAqT0,46248
6
6
  mwx/matplot2.py,sha256=W_FpY0S33crCAh7N9YTXo-jgYzj8uL9gqXkekfQo7Pk,36017
7
7
  mwx/matplot2g.py,sha256=cBuLMnQt3XSKQL9io0XJb_v8Lv0pO9hm0IMjVIERtu4,68253
8
8
  mwx/matplot2lg.py,sha256=h_aFij_7ksG2DXuYCaGmjtlcl122vZnwbMTv21Mprcg,27606
9
9
  mwx/mgplt.py,sha256=49_wpFZUEKErQmtobqrlNKDjWlAsdLft-izlqSyGPD0,6878
10
- mwx/nutshell.py,sha256=_cNKd_f5heEFcYb4PvlVNZqyLPNCNpDH8wAHFgDwmXw,137383
10
+ mwx/nutshell.py,sha256=BRrIXocO_EvgjWYbCrjnZjbCfXi-K5CLGBTQ_1u5aAI,138533
11
11
  mwx/utilus.py,sha256=H4wXPBix3zmq8wGn6YQKMO7aohSnPh_3fxUkAjDX0ZQ,37504
12
12
  mwx/wxmon.py,sha256=hEXto7dD5JunPf-iv2hhcwTIILLkNPlcl6wRt20_Wqc,11343
13
13
  mwx/wxpdb.py,sha256=M_xxXzIYhAwO1IHXVkjIC4Y2JCCCGLdgPL5R4bRtp04,19367
@@ -15,8 +15,8 @@ mwx/wxwil.py,sha256=DPXXx4OdEzvHr-_jxz9J29Ozufmb6Vr7rXVkG_LKQd0,5254
15
15
  mwx/wxwit.py,sha256=UG361QTUheO_hlSIRgkprrGUYh0IzHB8ZqOoJeeMzUs,7424
16
16
  mwx/py/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  mwx/py/filling.py,sha256=f6KMBcBv7gwrl6qmJYLTL-O0Z47bWNAdTCZtUZIo8vM,16794
18
- mwxlib-0.83.6.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
19
- mwxlib-0.83.6.dist-info/METADATA,sha256=Ld0rMHR_ESJ7ATfAKtUwDUnJ8XbtRG-E9rMjo5ZTSuY,1893
20
- mwxlib-0.83.6.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
21
- mwxlib-0.83.6.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
22
- mwxlib-0.83.6.dist-info/RECORD,,
18
+ mwxlib-0.83.8.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
19
+ mwxlib-0.83.8.dist-info/METADATA,sha256=RNWGhyeOHhPaaH9iHnWXecoVXZxlQLB5hpGmkesRs7k,1893
20
+ mwxlib-0.83.8.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
21
+ mwxlib-0.83.8.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
22
+ mwxlib-0.83.8.dist-info/RECORD,,