mwxlib 1.5.0__py3-none-any.whl → 1.5.10__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
@@ -27,7 +27,7 @@ from wx.py.shell import Shell
27
27
  from wx.py.editwindow import EditWindow
28
28
 
29
29
  from .utilus import funcall as _F
30
- from .utilus import ignore, typename
30
+ from .utilus import typename
31
31
  from .utilus import split_words, split_parts, split_tokens, find_modules
32
32
  from .framework import CtrlInterface, AuiNotebook, Menu
33
33
 
@@ -54,6 +54,7 @@ py_break_re = r'at ([^*?"<>|\r\n]+?):([0-9]+)'
54
54
  stc.STC_STYLE_CARETLINE = 40
55
55
  stc.STC_STYLE_ANNOTATION = 41
56
56
 
57
+
57
58
  class Stylus:
58
59
  py_log_mode = {
59
60
  stc.STC_STYLE_DEFAULT : "fore:#7f7f7f,back:#ffffb8,size:9,face:MS Gothic",
@@ -338,7 +339,7 @@ class AutoCompInterfaceMixin:
338
339
  ## ls = [x for x in self.fragmwords if x.startswith(hint)] # case-sensitive match
339
340
  q = hint.lower()
340
341
  ls = [x for x in self.fragmwords if x.lower().startswith(q)] # case-insensitive match
341
- words = sorted(ls, key=lambda s:s.upper())
342
+ words = sorted(ls, key=lambda s: s.upper())
342
343
 
343
344
  self._gen_autocomp(0, hint, words)
344
345
  self.message("[text] {} candidates matched"
@@ -396,7 +397,7 @@ class AutoCompInterfaceMixin:
396
397
 
397
398
  P = re.compile(hint)
398
399
  p = re.compile(hint, re.I)
399
- words = sorted([x for x in modules if p.match(x)], key=lambda s:s.upper())
400
+ words = sorted([x for x in modules if p.match(x)], key=lambda s: s.upper())
400
401
 
401
402
  j = next((k for k, w in enumerate(words) if P.match(w)),
402
403
  next((k for k, w in enumerate(words) if p.match(w)), -1))
@@ -428,7 +429,7 @@ class AutoCompInterfaceMixin:
428
429
  obj = self.eval(text)
429
430
  P = re.compile(hint)
430
431
  p = re.compile(hint, re.I)
431
- words = sorted([x for x in dir(obj) if p.match(x)], key=lambda s:s.upper())
432
+ words = sorted([x for x in dir(obj) if p.match(x)], key=lambda s: s.upper())
432
433
 
433
434
  j = next((k for k, w in enumerate(words) if P.match(w)),
434
435
  next((k for k, w in enumerate(words) if p.match(w)), -1))
@@ -460,7 +461,7 @@ class AutoCompInterfaceMixin:
460
461
  obj = self.eval(text)
461
462
  P = re.compile(hint)
462
463
  p = re.compile(hint, re.I)
463
- words = sorted([x for x in dir(obj) if p.search(x)], key=lambda s:s.upper())
464
+ words = sorted([x for x in dir(obj) if p.search(x)], key=lambda s: s.upper())
464
465
 
465
466
  j = next((k for k, w in enumerate(words) if P.match(w)),
466
467
  next((k for k, w in enumerate(words) if p.match(w)), -1))
@@ -513,15 +514,15 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
513
514
  'C-e pressed' : (0, _F(self.end_of_line)),
514
515
  'M-a pressed' : (0, _F(self.back_to_indentation)),
515
516
  'M-e pressed' : (0, _F(self.end_of_line)),
516
- 'M-g pressed' : (0, ask(self.goto_line, "Line to goto:", lambda x:int(x)-1),
517
+ 'M-g pressed' : (0, ask(self.goto_line, "Line to goto:", lambda x: int(x)-1),
517
518
  _F(self.recenter)),
518
519
  'M-f pressed' : (10, _F(self.filter_text), self.on_itext_enter),
519
520
  'C-k pressed' : (0, _F(self.kill_line)),
520
521
  'C-S-c pressed' : (0, _F(self.Copy)),
521
522
  'C-S-v pressed' : (0, _F(self.Paste)),
522
523
  'C-l pressed' : (0, _F(self.recenter)),
523
- 'C-S-l pressed' : (0, _F(self.recenter)), # overrides delete-line
524
- 'C-S-f pressed' : (0, _F(self.set_mark)), # overrides mark
524
+ ## 'C-S-l pressed' : (0, _F(self.recenter)), # overrides delete-line
525
+ ## 'C-S-f pressed' : (0, _F(self.set_mark)), # overrides mark
525
526
  'C-space pressed' : (0, _F(self.set_mark)),
526
527
  'C-S-space pressed' : (0, _F(self.set_pointer)),
527
528
  'C-backspace pressed' : (0, _F(self.backward_kill_word)),
@@ -778,23 +779,23 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
778
779
 
779
780
  white_arrow = property(
780
781
  lambda self: self.get_marker(1),
781
- lambda self,v: self.set_marker(v, 1), # [arrow_set]
782
- lambda self: self.del_marker(1)) # [arrow_unset]
782
+ lambda self, v: self.set_marker(v, 1), # [arrow_set]
783
+ lambda self: self.del_marker(1)) # [arrow_unset]
783
784
 
784
785
  red_arrow = property(
785
786
  lambda self: self.get_marker(2),
786
- lambda self,v: self.set_marker(v, 2), # [red-arrow_set]
787
- lambda self: self.del_marker(2)) # [red-arrow_unset]
787
+ lambda self, v: self.set_marker(v, 2), # [red-arrow_set]
788
+ lambda self: self.del_marker(2)) # [red-arrow_unset]
788
789
 
789
790
  pointer = property(
790
791
  lambda self: self.get_marker(3),
791
- lambda self,v: self.set_marker(v, 3), # [pointer_set]
792
- lambda self: self.del_marker(3)) # [pointer_unset]
792
+ lambda self, v: self.set_marker(v, 3), # [pointer_set]
793
+ lambda self: self.del_marker(3)) # [pointer_unset]
793
794
 
794
795
  red_pointer = property(
795
796
  lambda self: self.get_marker(4),
796
- lambda self,v: self.set_marker(v, 4), # [red-pointer_set]
797
- lambda self: self.del_marker(4)) # [red-pointer_unset]
797
+ lambda self, v: self.set_marker(v, 4), # [red-pointer_set]
798
+ lambda self: self.del_marker(4)) # [red-pointer_unset]
798
799
 
799
800
  @property
800
801
  def markline(self):
@@ -908,15 +909,15 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
908
909
 
909
910
  anchor = property(
910
911
  lambda self: self.GetAnchor(),
911
- lambda self,v: self.SetAnchor(v))
912
+ lambda self, v: self.SetAnchor(v))
912
913
 
913
914
  cpos = property(
914
915
  lambda self: self.GetCurrentPos(),
915
- lambda self,v: self.SetCurrentPos(v))
916
+ lambda self, v: self.SetCurrentPos(v))
916
917
 
917
918
  cline = property(
918
919
  lambda self: self.GetCurrentLine(),
919
- lambda self,v: self.SetCurrentPos(self.PositionFromLine(v)))
920
+ lambda self, v: self.SetCurrentPos(self.PositionFromLine(v)))
920
921
 
921
922
  @property
922
923
  def bol(self):
@@ -972,12 +973,12 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
972
973
  return topic
973
974
  with self.save_excursion():
974
975
  p = q = self.cpos
975
- ## if self.get_char(p-1).isidentifier():
976
- if self.GetTextRange(self.PositionBefore(p), p).isidentifier():
976
+ cp = self.GetTextRange(self.PositionBefore(p), p) # cf. self.get_char(p-1)
977
+ if cp.isidentifier() or cp.isalnum():
977
978
  self.WordLeft()
978
979
  p = self.cpos
979
- ## if self.get_char(q).isidentifier():
980
- if self.GetTextRange(q, self.PositionAfter(q)).isidentifier():
980
+ cq = self.GetTextRange(q, self.PositionAfter(q)) # cf. self.get_char(q)
981
+ if cq.isidentifier() or cq.isalnum():
981
982
  self.WordRightEnd()
982
983
  q = self.cpos
983
984
  return self.GetTextRange(p, q)
@@ -1322,22 +1323,26 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1322
1323
  if not hl + offset < vl < hl + n - 1 - offset:
1323
1324
  self.ScrollToLine(vl - n//2)
1324
1325
 
1325
- def DoFindNext(self, findData, findDlg=None):
1326
+ ## --------------------------------
1327
+ ## Search functions
1328
+ ## --------------------------------
1329
+
1330
+ def DoFindNext(self, findData):
1326
1331
  """Find the search text defined in `findData`.
1327
1332
 
1328
1333
  If found, selects the matched text and scrolls to its line.
1329
1334
  Typically called from `wx.EVT_FIND` event handlers.
1330
1335
 
1331
- (override) Enables the whole word search.
1332
- Returns True if a match is found, False otherwise.
1336
+ (override) Enables whole word search.
1337
+ Returns the match position if found, -1 otherwise.
1333
1338
  """
1334
1339
  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
1340
+ if findData.Flags & wx.FR_MATCHCASE: flags |= stc.STC_FIND_MATCHCASE
1341
+ if findData.Flags & wx.FR_WHOLEWORD: flags |= stc.STC_FIND_WHOLEWORD
1337
1342
  self.SetSearchFlags(flags)
1338
1343
 
1339
1344
  backward = not (findData.Flags & wx.FR_DOWN)
1340
- findstring = findData.FindString
1345
+ findstring = findData.FindString.encode()
1341
1346
  if backward:
1342
1347
  self.TargetStart = self.anchor # backward anchor
1343
1348
  self.TargetEnd = 0
@@ -1353,20 +1358,37 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1353
1358
 
1354
1359
  ## Was it still not found?
1355
1360
  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
1361
+ ## wx.MessageBox("Unable to find the search text any more.",
1362
+ ## "Not found!", wx.OK|wx.ICON_INFORMATION)
1363
+ wx.Bell()
1364
+ pass
1365
+ else:
1366
+ self.SetSelection(loc, loc + len(findstring))
1367
+ self.EnsureVisible(self.cline) # expand if folded
1368
+ self.EnsureCaretVisible()
1369
+ return loc
1366
1370
 
1367
- ## --------------------------------
1368
- ## Search functions
1369
- ## --------------------------------
1371
+ def DoReplaceNext(self, findData):
1372
+ if self.SelectedText == findData.FindString:
1373
+ if self.CanEdit():
1374
+ self.ReplaceSelection(findData.ReplaceString)
1375
+ return self.DoFindNext(findData)
1376
+
1377
+ def DoReplaceAll(self, findData):
1378
+ with self.save_excursion():
1379
+ locs = [-1]
1380
+ count = 0
1381
+ while 1:
1382
+ loc = self.DoFindNext(findData)
1383
+ if loc in locs:
1384
+ break
1385
+ locs.append(loc)
1386
+ self.TargetStart = self.anchor
1387
+ self.TargetEnd = self.cpos
1388
+ if self.CanEdit():
1389
+ self.ReplaceTarget(findData.ReplaceString)
1390
+ count += 1
1391
+ return count
1370
1392
 
1371
1393
  def get_right_paren(self, p):
1372
1394
  if self.get_char(p) in "({[<": # left-parentheses, <
@@ -1463,7 +1485,8 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1463
1485
  if not text:
1464
1486
  self.message("No words")
1465
1487
  return
1466
- wholeword = (not self.SelectedText) # Enable or disable whole word search.
1488
+ wholeword = (not self.SelectedText # Enable or disable whole word search.
1489
+ and text.isascii()) # whole word search is for ascii only. (単語境界が不明確のため)
1467
1490
  pattern = re.escape(text)
1468
1491
  if wholeword:
1469
1492
  pattern = rf"\b{pattern}\b"
@@ -1788,7 +1811,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1788
1811
  """
1789
1812
  self.eat_white_forward()
1790
1813
  _text, lp = self.CurLine
1791
- for i in range(lp % 4 or 4):
1814
+ for _i in range(lp % 4 or 4):
1792
1815
  p = self.cpos
1793
1816
  if p == self.bol or self.get_char(p-1) != ' ':
1794
1817
  break
@@ -1940,9 +1963,9 @@ class Buffer(EditorInterface, EditWindow):
1940
1963
  None : {
1941
1964
  'buffer_saved' : [ None, dispatch ],
1942
1965
  'buffer_loaded' : [ None, dispatch ],
1943
- 'buffer_modified' : [ None, dispatch, self.on_modified ],
1944
- 'buffer_activated' : [ None, dispatch, self.on_activated ],
1945
- 'buffer_inactivated' : [ None, dispatch, self.on_inactivated ],
1966
+ 'buffer_modified' : [ None, dispatch, self.on_buffer_modified ],
1967
+ 'buffer_activated' : [ None, dispatch, self.on_buffer_activated ],
1968
+ 'buffer_inactivated' : [ None, dispatch, self.on_buffer_inactivated ],
1946
1969
  'buffer_region_executed' : [ None, dispatch ],
1947
1970
  },
1948
1971
  -1 : { # original action of the EditWindow
@@ -2067,7 +2090,7 @@ class Buffer(EditorInterface, EditWindow):
2067
2090
  ## Note: post-call for the confirmation dialog.
2068
2091
  wx.CallAfter(self.parent.load_file, url)
2069
2092
 
2070
- def on_modified(self, buf):
2093
+ def on_buffer_modified(self, buf):
2071
2094
  """Called when the buffer is modified."""
2072
2095
  self.SetIndicatorCurrent(2)
2073
2096
  self.IndicatorClearRange(0, self.TextLength)
@@ -2094,12 +2117,12 @@ class Buffer(EditorInterface, EditWindow):
2094
2117
  self.handler('quit', evt) # don't enter autocomp
2095
2118
  evt.Skip()
2096
2119
 
2097
- def on_activated(self, buf):
2120
+ def on_buffer_activated(self, buf):
2098
2121
  """Called when the buffer is activated."""
2099
2122
  self.update_caption()
2100
2123
  self.trace_position()
2101
2124
 
2102
- def on_inactivated(self, buf):
2125
+ def on_buffer_inactivated(self, buf):
2103
2126
  """Called when the buffer is inactivated."""
2104
2127
  pass
2105
2128
 
@@ -2267,9 +2290,8 @@ class EditorBook(AuiNotebook, CtrlInterface):
2267
2290
  ## So we set the tabs' height to zero to hide them.
2268
2291
  self.TabCtrlHeight = 0
2269
2292
 
2270
- self.defaultBufferStyle = dict(
2271
- ReadOnly = False,
2272
- )
2293
+ self.defaultBufferStyle = {}
2294
+
2273
2295
  self.parent = parent #: parent<ShellFrame> is not Parent<AuiNotebook>
2274
2296
  self.Name = name
2275
2297
  self.default_name = "*{}*".format(name.lower()) # e.g. '*scratch*'
@@ -2294,8 +2316,8 @@ class EditorBook(AuiNotebook, CtrlInterface):
2294
2316
  'buffer_loaded' : [ None, dispatch ],
2295
2317
  'buffer_deleted' : [ None, dispatch ],
2296
2318
  'buffer_modified' : [ None, dispatch ],
2297
- 'buffer_activated' : [ None, dispatch, self.on_activated ],
2298
- 'buffer_inactivated' : [ None, dispatch, self.on_inactivated ],
2319
+ 'buffer_activated' : [ None, dispatch, self.on_buffer_activated ],
2320
+ 'buffer_inactivated' : [ None, dispatch, self.on_buffer_inactivated ],
2299
2321
  'buffer_caption_updated' : [ None, dispatch ],
2300
2322
  },
2301
2323
  0 : { # Normal mode
@@ -2361,12 +2383,12 @@ class EditorBook(AuiNotebook, CtrlInterface):
2361
2383
  for buf in self.get_all_buffers():
2362
2384
  _setattribute(buf, self.defaultBufferStyle)
2363
2385
 
2364
- def on_activated(self, buf):
2386
+ def on_buffer_activated(self, buf):
2365
2387
  """Called when the buffer is activated."""
2366
2388
  title = "{} file: {}".format(self.Name, buf.filename)
2367
2389
  self.parent.handler('title_window', title)
2368
2390
 
2369
- def on_inactivated(self, buf):
2391
+ def on_buffer_inactivated(self, buf):
2370
2392
  """Called when the buffer is inactivated."""
2371
2393
  pass
2372
2394
 
@@ -2432,7 +2454,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
2432
2454
  """Create a new default buffer."""
2433
2455
  buf = self.default_buffer
2434
2456
  if not buf or buf.mtdelta is not None: # is saved?
2435
- buf = self.create_buffer(self.default_name, index=0)
2457
+ buf = self.create_buffer(self.default_name)
2436
2458
  self.default_buffer = buf
2437
2459
  else:
2438
2460
  buf.ClearAll()
@@ -2791,7 +2813,7 @@ class Nautilus(EditorInterface, Shell):
2791
2813
  """Reset the shell target object; Rename the parent title.
2792
2814
  """
2793
2815
  if not hasattr(obj, '__dict__'):
2794
- raise TypeError("primitive objects cannot be targets")
2816
+ raise TypeError("invalid target")
2795
2817
 
2796
2818
  self.__target = obj
2797
2819
  self.locals = obj.__dict__
@@ -2800,7 +2822,8 @@ class Nautilus(EditorInterface, Shell):
2800
2822
  try:
2801
2823
  obj.self = obj
2802
2824
  obj.this = inspect.getmodule(obj)
2803
- obj.shell = self # overwrite the facade <wx.py.shell.ShellFacade>
2825
+ obj.shell = self # Overwrite the facade <wx.py.shell.ShellFacade>.
2826
+ obj.__name__ = typename(obj) # A namespace for ghost in the shell. cf. exec_region
2804
2827
  except AttributeError:
2805
2828
  pass
2806
2829
  self.parent.handler('title_window', obj)
@@ -2889,10 +2912,10 @@ class Nautilus(EditorInterface, Shell):
2889
2912
  self.handler.update({ # DNA<Nautilus>
2890
2913
  None : {
2891
2914
  'interp_error' : [ None, self.on_interp_error ],
2892
- 'shell_deleted' : [ None, dispatch, self.on_deleted ],
2915
+ 'shell_deleted' : [ None, dispatch, self.on_shell_deleted ],
2893
2916
  'shell_modified' : [ None, dispatch ],
2894
- 'shell_activated' : [ None, dispatch, self.on_activated ],
2895
- 'shell_inactivated' : [ None, dispatch, self.on_inactivated ],
2917
+ 'shell_activated' : [ None, dispatch, self.on_shell_activated ],
2918
+ 'shell_inactivated' : [ None, dispatch, self.on_shell_inactivated ],
2896
2919
  },
2897
2920
  -1 : { # original action of the wx.py.shell
2898
2921
  '* pressed' : (0, skip, self.on_exit_escmap),
@@ -3174,7 +3197,7 @@ class Nautilus(EditorInterface, Shell):
3174
3197
  if text[:lp] == sys.ps2:
3175
3198
  self.cpos -= lp # Select ps2:prompt
3176
3199
  self.WordLeftExtend() # Select cr/lf chunks
3177
- else:
3200
+ else:
3178
3201
  q = max(self.bol, self.bolc) # for debugger mode: bol <= bolc
3179
3202
  if self.cpos > q:
3180
3203
  self.cpos = q
@@ -3236,9 +3259,9 @@ class Nautilus(EditorInterface, Shell):
3236
3259
  def on_exit_escmap(self, evt):
3237
3260
  self.CaretPeriod = self.__caret_mode
3238
3261
  self.message("ESC {}".format(evt.key))
3239
- if self.eolc < self.bolc: # check if prompt is in valid state
3262
+ if self.eolc < self.bolc: # Check if prompt is in valid state.
3240
3263
  self.goto_char(self.eolc)
3241
- self.promptPosEnd = 0
3264
+ self.promptPosEnd = 0 # Enabale write(prompt).
3242
3265
  self.prompt()
3243
3266
  self.AnnotationClearAll()
3244
3267
 
@@ -3252,7 +3275,7 @@ class Nautilus(EditorInterface, Shell):
3252
3275
  self.noteMode = False
3253
3276
  self.CaretForeground = self.__caret_mode
3254
3277
  self.goto_char(self.eolc)
3255
- self.promptPosEnd = 0
3278
+ self.promptPosEnd = 0 # Enabale write(prompt).
3256
3279
  self.prompt()
3257
3280
  self.message("")
3258
3281
 
@@ -3368,7 +3391,7 @@ class Nautilus(EditorInterface, Shell):
3368
3391
  lhs += c # store in lhs; no more processing
3369
3392
  return lhs
3370
3393
 
3371
- def on_deleted(self, shell):
3394
+ def on_shell_deleted(self, shell):
3372
3395
  """Called before shell:self is killed.
3373
3396
  Delete target shell to prevent referencing the dead shell.
3374
3397
  """
@@ -3381,21 +3404,21 @@ class Nautilus(EditorInterface, Shell):
3381
3404
  pass
3382
3405
  wx.CallAfter(_del)
3383
3406
 
3384
- def on_activated(self, shell):
3407
+ def on_shell_activated(self, shell):
3385
3408
  """Called when the shell:self is activated.
3386
- Reset localvars assigned for the shell target.
3409
+ Reset localvars assigned for the shell target. cf. target.setter.
3387
3410
  """
3388
3411
  self.trace_position()
3389
3412
  obj = self.target
3390
3413
  try:
3391
3414
  obj.self = obj
3392
3415
  obj.this = inspect.getmodule(obj)
3393
- obj.shell = self # overwrite the facade <wx.py.shell.ShellFacade>
3416
+ obj.shell = self # Overwrite the facade <wx.py.shell.ShellFacade>
3394
3417
  except AttributeError:
3395
3418
  pass
3396
3419
  self.parent.handler('title_window', obj)
3397
3420
 
3398
- def on_inactivated(self, shell):
3421
+ def on_shell_inactivated(self, shell):
3399
3422
  """Called when shell:self is inactivated.
3400
3423
  Remove target localvars assigned for the shell target.
3401
3424
  """
@@ -3542,14 +3565,26 @@ class Nautilus(EditorInterface, Shell):
3542
3565
  ## shell.__init__ よりも先に実行される
3543
3566
  pass
3544
3567
 
3568
+ def setBuiltinKeywords(self):
3569
+ """Create pseudo keywords as part of builtins.
3570
+
3571
+ (override) Don't add `close`, `exit` and `quit` to builtins.
3572
+ """
3573
+ from wx.py.path import ls, cd, pwd, sx
3574
+ builtins.cd = cd
3575
+ builtins.ls = ls
3576
+ builtins.pwd = pwd
3577
+ builtins.sx = sx
3578
+
3545
3579
  def execStartupScript(self, su):
3546
3580
  """Execute the user's PYTHONSTARTUP script if they have one.
3547
3581
 
3548
3582
  (override) Add globals when executing su:startupScript.
3549
- Fix history point.
3583
+ Don't add '_f' to globals when executing su:startupScript.
3584
+ Don't add intro text in the history.
3550
3585
  """
3551
- keys = set(self.locals.keys()) # check for locals map changes
3552
- self.promptPosEnd = self.TextLength # fix history point
3586
+ keys = set(self.locals.keys()) # to check for locals map changes.
3587
+ self.promptPosEnd = self.TextLength # Fix history point
3553
3588
  if su and os.path.isfile(su):
3554
3589
  self.push("print('Startup script executed:', {0!r})\n".format(su))
3555
3590
  self.push("with open({0!r}) as _f: exec(_f.read())\n".format(su))
@@ -3691,10 +3726,6 @@ class Nautilus(EditorInterface, Shell):
3691
3726
  self.write(cmd)
3692
3727
  self.processLine()
3693
3728
 
3694
- ## --------------------------------
3695
- ## Autocomp actions of the shell
3696
- ## --------------------------------
3697
-
3698
3729
  def eval_line(self):
3699
3730
  """Evaluate the selected word or line and show calltips."""
3700
3731
  if self.CallTipActive():
@@ -1,7 +1,6 @@
1
1
  #! python3
2
2
  """FFmpeg wrapper.
3
3
  """
4
- from functools import partial
5
4
  from subprocess import Popen, PIPE
6
5
  import numpy as np
7
6
  import os
@@ -151,9 +150,9 @@ class Plugin(Layer):
151
150
  },
152
151
  })
153
152
 
154
- self.mc.Bind(wx.media.EVT_MEDIA_PAUSE, partial(self.handler, 'pause'))
155
- self.mc.Bind(wx.media.EVT_MEDIA_PLAY, partial(self.handler, 'play'))
156
- self.mc.Bind(wx.media.EVT_MEDIA_STOP, partial(self.handler, 'stop'))
153
+ self.mc.Bind(wx.media.EVT_MEDIA_PAUSE, lambda v: self.handler('pause', v))
154
+ self.mc.Bind(wx.media.EVT_MEDIA_PLAY, lambda v: self.handler('play', v))
155
+ self.mc.Bind(wx.media.EVT_MEDIA_STOP, lambda v: self.handler('stop', v))
157
156
 
158
157
  self.mc.Bind(wx.EVT_KEY_DOWN, self.on_hotkey_down)
159
158
  self.mc.Bind(wx.EVT_KEY_UP, self.on_hotkey_up)
mwx/plugins/fft_view.py CHANGED
@@ -3,7 +3,7 @@
3
3
  """
4
4
  import wx
5
5
  import numpy as np
6
- from numpy.fft import fft2,ifft2,fftshift,ifftshift
6
+ from numpy.fft import fft2, ifft2, fftshift, ifftshift
7
7
 
8
8
  from mwx.graphman import Layer
9
9
  from mwx.controls import Param
@@ -74,7 +74,7 @@ class Plugin(Layer):
74
74
 
75
75
  if self.ftor.check:
76
76
  y, x = np.ogrid[-h/2:h/2, -w/2:w/2]
77
- mask = np.hypot(y,x) > w / self.ftor.value
77
+ mask = np.hypot(y, x) > w / self.ftor.value
78
78
  src = src.copy() # apply mask to the copy
79
79
  src[mask] = 0
80
80
 
@@ -52,7 +52,7 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
52
52
  self.__dir = True
53
53
 
54
54
  _alist = ( # assoc-list of column names
55
- ("id", 42),
55
+ ("id", 45),
56
56
  ("name", 160),
57
57
  ("shape", 90),
58
58
  ("dtype", 60),
@@ -75,6 +75,10 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
75
75
  'C-a pressed' : (0, self.OnSelectAllItems),
76
76
  'C-o pressed' : (0, self.OnLoadItems),
77
77
  'C-s pressed' : (0, self.OnSaveItems),
78
+ 'C-S-s pressed' : (0, self.OnSaveItems),
79
+ 'C-c pressed' : (0, self.OnCopyInfo),
80
+ 'C-l pressed' : (0, self.OnEditLocalUnit),
81
+ 'f2 pressed' : (0, self.OnEditAnnotation),
78
82
  'M-up pressed' : (0, self.Target.OnPageUp),
79
83
  'M-down pressed' : (0, self.Target.OnPageDown),
80
84
  },
@@ -98,7 +102,7 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
98
102
 
99
103
  self.menu = [
100
104
  (100, "Edit localunit", Icon('image'),
101
- self.OnEditUnit,
105
+ self.OnEditLocalUnit,
102
106
  lambda v: v.Enable(self.focused_item != -1)),
103
107
 
104
108
  (101, "Edit annotation", Icon('pencil'),
@@ -181,20 +185,20 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
181
185
  def OnCopyInfo(self, evt):
182
186
  selected_frames = [self.Target.all_frames[j] for j in self.selected_items]
183
187
  if selected_frames:
184
- text = ''
188
+ text = []
185
189
  for frame in selected_frames:
186
- text += pformat(frame.attributes, sort_dicts=0) # ALL attributes
187
- ## text += '{}\n{}\n'.format(frame.name, frame.annotation)
188
- Clipboard.write(text)
190
+ text += [pformat(frame.attributes, sort_dicts=0)] # ALL attributes
191
+ Clipboard.write('\n'.join(text))
189
192
  else:
190
193
  self.parent.message("No frame selected.")
191
194
 
192
- def OnEditUnit(self, evt):
195
+ def OnEditLocalUnit(self, evt):
193
196
  frame = self.Target.all_frames[self.focused_item]
194
197
  with wx.TextEntryDialog(self, frame.name,
195
198
  'Enter localunit', repr(frame.localunit)) as dlg:
196
199
  if dlg.ShowModal() == wx.ID_OK:
197
200
  frame.unit = eval(dlg.Value or 'None')
201
+ self.SetFocus()
198
202
 
199
203
  def OnEditAnnotation(self, evt):
200
204
  frame = self.Target.all_frames[self.focused_item]
@@ -202,6 +206,7 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
202
206
  'Enter an annotation', frame.annotation) as dlg:
203
207
  if dlg.ShowModal() == wx.ID_OK:
204
208
  frame.annotation = dlg.Value
209
+ self.SetFocus()
205
210
 
206
211
  def OnItemSelected(self, evt):
207
212
  frame = self.Target.all_frames[evt.Index]
mwx/testsuite.py CHANGED
@@ -17,7 +17,7 @@ Is equivalent to:
17
17
  from contextlib import contextmanager
18
18
  import wx
19
19
 
20
- __all__ = ["testApp", "testFrame", "Plugman", "testPanel"]
20
+ __all__ = ["testApp", "testFrame", "testPlugin", "testPanel"]
21
21
 
22
22
 
23
23
  @contextmanager
@@ -38,15 +38,6 @@ def testFrame(**kwargs):
38
38
  ## wx.Frame.run = staticmethod(testFrame)
39
39
 
40
40
 
41
- @contextmanager
42
- def Plugman(**kwargs):
43
- import mwx.graphman
44
- with testApp():
45
- frm = mwx.graphman.Frame(None, **kwargs)
46
- yield frm
47
- frm.Show()
48
-
49
-
50
41
  @contextmanager
51
42
  def testPanel(**kwargs):
52
43
  import mwx
@@ -56,3 +47,12 @@ def testPanel(**kwargs):
56
47
  yield panel
57
48
  panel.Sizer.Fit(frm)
58
49
  frm.Show()
50
+
51
+
52
+ @contextmanager
53
+ def testPlugin(**kwargs):
54
+ import mwx.graphman
55
+ with testApp():
56
+ frm = mwx.graphman.Frame(None, **kwargs)
57
+ yield frm
58
+ frm.Show()