PrEditor 1.4.0__py3-none-any.whl → 1.5.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 PrEditor might be problematic. Click here for more details.

preditor/debug.py CHANGED
@@ -32,9 +32,9 @@ class FileLogger:
32
32
  return msg.format(today=datetime.datetime.today(), version=sys.version)
33
33
 
34
34
  def write(self, msg):
35
- f = open(self._logfile, 'a')
36
- f.write(msg)
37
- f.close()
35
+ with open(self._logfile, 'a', encoding="utf-8") as f:
36
+ f.write(msg)
37
+
38
38
  if self._print:
39
39
  self._stdhandle.write(msg)
40
40
 
preditor/gui/console.py CHANGED
@@ -53,6 +53,16 @@ class ConsolePrEdit(QTextEdit):
53
53
  # If populated, also write to this interface
54
54
  self.outputPipe = None
55
55
 
56
+ # For workboxes, use this regex pattern, so we can extract workboxName
57
+ # and lineNum
58
+ pattern = r'File "<Workbox(?:Selection)?>:(?P<workboxName>.*)", '
59
+ pattern += r'line (?P<lineNum>\d{1,6}), in'
60
+ self.workbox_pattern = re.compile(pattern)
61
+
62
+ # Define a pattern to capture info from tracebacks
63
+ pattern = r'File "(?P<filename>.*)", line (?P<lineNum>\d{1,10}), in'
64
+ self.traceback_pattern = re.compile(pattern)
65
+
56
66
  self._consolePrompt = '>>> '
57
67
  # Note: Changing _outputPrompt may require updating resource\lang\python.xml
58
68
  # If still using a #
@@ -90,7 +100,7 @@ class ConsolePrEdit(QTextEdit):
90
100
  # to the console and free up the memory consumed by previous writes as we
91
101
  # assume this is likely to be the only callback added to the manager.
92
102
  self.stream_manager.add_callback(
93
- self.write, replay=True, disable_writes=True, clear=True
103
+ self.pre_write, replay=True, disable_writes=True, clear=True
94
104
  )
95
105
  # Store the current outputs
96
106
  self.stdout = sys.stdout
@@ -122,6 +132,11 @@ class ConsolePrEdit(QTextEdit):
122
132
  if not self.cursorWidth():
123
133
  self.setCursorWidth(1)
124
134
 
135
+ # The act of changing from no scroll bar to a scroll bar can add up to 1
136
+ # second of time to the process of outputting text, so, just always have
137
+ # it on.
138
+ self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
139
+
125
140
  def doubleSingleShotSetScrollValue(self, origPercent):
126
141
  """This double QTimer.singleShot monkey business seems to be the only way
127
142
  to get scroll.maximum() to update properly so that we calc newValue
@@ -239,7 +254,7 @@ class ConsolePrEdit(QTextEdit):
239
254
  # info is a comma separated string, in the form: "filename, workboxIdx, lineNum"
240
255
  info = self.anchor.split(', ')
241
256
  modulePath = info[0]
242
- workboxIndex = info[1]
257
+ workboxName = info[1]
243
258
  lineNum = info[2]
244
259
 
245
260
  # fetch info from LoggerWindow
@@ -250,23 +265,27 @@ class ConsolePrEdit(QTextEdit):
250
265
  cmdTempl = window.textEditorCmdTempl
251
266
 
252
267
  # Bail if not setup properly
253
- msg = "Cannot use traceback hyperlink. "
254
- if not exePath:
255
- msg += "No text editor path defined."
256
- print(msg)
257
- return
258
- if not os.path.exists(exePath):
259
- msg += "Text editor executable does not exist: {}".format(exePath)
260
- print(msg)
261
- return
262
- if not cmdTempl:
263
- msg += "No text editor Command Prompt command template defined."
264
- print(msg)
265
- return
266
- if modulePath and not os.path.exists(modulePath):
267
- msg += "Specified module path does not exist: {}".format(modulePath)
268
- print(msg)
269
- return
268
+ if workboxName is None:
269
+ msg = (
270
+ "Cannot use traceback hyperlink (Correct the path with Options "
271
+ "> Set Preferred Text Editor Path).\n"
272
+ )
273
+ if not exePath:
274
+ msg += "No text editor path defined."
275
+ print(msg)
276
+ return
277
+ if not os.path.exists(exePath):
278
+ msg += "Text editor executable does not exist: {}".format(exePath)
279
+ print(msg)
280
+ return
281
+ if not cmdTempl:
282
+ msg += "No text editor Command Prompt command template defined."
283
+ print(msg)
284
+ return
285
+ if modulePath and not os.path.exists(modulePath):
286
+ msg += "Specified module path does not exist: {}".format(modulePath)
287
+ print(msg)
288
+ return
270
289
 
271
290
  if modulePath:
272
291
  # Check if cmdTempl filepaths aren't wrapped in double=quotes to handle
@@ -296,12 +315,9 @@ class ConsolePrEdit(QTextEdit):
296
315
  msg = "The provided text editor command template is not valid:\n {}"
297
316
  msg = msg.format(cmdTempl)
298
317
  print(msg)
299
- elif workboxIndex is not None:
300
- group, editor = workboxIndex.split(',')
318
+ elif workboxName is not None:
319
+ workbox = window.workbox_for_name(workboxName, visible=True)
301
320
  lineNum = int(lineNum)
302
- workbox = window.uiWorkboxTAB.set_current_groups_from_index(
303
- int(group), int(editor)
304
- )
305
321
  workbox.__goto_line__(lineNum)
306
322
  workbox.setFocus()
307
323
 
@@ -373,7 +389,34 @@ class ConsolePrEdit(QTextEdit):
373
389
  """returns the completer instance that is associated with this editor"""
374
390
  return self._completer
375
391
 
376
- def executeString(self, commandText, filename='<ConsolePrEdit>', extraPrint=True):
392
+ def getWorkboxLine(self, name, lineNum):
393
+ """Python 3 does not include in tracebacks the code line if it comes from
394
+ stdin, which is the case for PrEditor workboxes, so we fake it. This method
395
+ will return the line of code at lineNum, from the workbox with the provided
396
+ name.
397
+
398
+ Args:
399
+ name (str): The name of the workbox from which to get a line of code
400
+ lineNum (int): The number of the line to return
401
+
402
+ Returns:
403
+ txt (str): The line of text found
404
+ """
405
+ workbox = self.window().workbox_for_name(name)
406
+ if not workbox:
407
+ return None
408
+ if lineNum > workbox.lines():
409
+ return None
410
+ txt = workbox.text(lineNum).strip() + "\n"
411
+ return txt
412
+
413
+ def executeString(
414
+ self, commandText, consoleLine=None, filename='<ConsolePrEdit>', extraPrint=True
415
+ ):
416
+ # These vars helps with faking code lines in tracebacks for stdin input, which
417
+ # workboxes are, and py3 doesn't include in the traceback
418
+ self.consoleLine = consoleLine or ""
419
+
377
420
  if self.clearExecutionTime is not None:
378
421
  self.clearExecutionTime()
379
422
  cursor = self.textCursor()
@@ -428,6 +471,10 @@ class ConsolePrEdit(QTextEdit):
428
471
 
429
472
  def executeCommand(self):
430
473
  """executes the current line of code"""
474
+
475
+ # Not using workbox, so clear this
476
+ self.consoleLine = ""
477
+
431
478
  # grab the command from the line
432
479
  block = self.textCursor().block().text()
433
480
  p = '{prompt}(.*)'.format(prompt=re.escape(self.prompt()))
@@ -450,7 +497,9 @@ class ConsolePrEdit(QTextEdit):
450
497
  self._prevCommands = self._prevCommands[-1 * self._prevCommandsMax :]
451
498
 
452
499
  # evaluate the command
453
- cmdresult, wasEval = self.executeString(commandText)
500
+ cmdresult, wasEval = self.executeString(
501
+ commandText, consoleLine=commandText
502
+ )
454
503
 
455
504
  # print the resulting commands
456
505
  if cmdresult is not None:
@@ -787,28 +836,65 @@ class ConsolePrEdit(QTextEdit):
787
836
  """Determine if txt is a File-info line from a traceback, and if so, return info
788
837
  dict.
789
838
  """
790
- lineMarker = '", line '
839
+
791
840
  ret = None
841
+ if not txt.lstrip().startswith("File "):
842
+ return ret
843
+
844
+ match = self.traceback_pattern.search(txt)
845
+ if match:
846
+ filename = match.groupdict().get('filename')
847
+ lineNum = match.groupdict().get('lineNum')
848
+ fileStart = txt.find(filename)
849
+ fileEnd = fileStart + len(filename)
792
850
 
793
- filenameEnd = txt.find(lineMarker)
794
- if txt[:8] == ' File "' and filenameEnd >= 0:
795
- filename = txt[8:filenameEnd]
796
- lineNumStart = filenameEnd + len(lineMarker)
797
- lineNumEnd = txt.find(',', lineNumStart)
798
- if lineNumEnd == -1:
799
- lineNumEnd = len(txt)
800
- lineNum = txt[lineNumStart:lineNumEnd]
801
851
  ret = {
802
852
  'filename': filename,
803
- 'fileStart': 8,
804
- 'fileEnd': filenameEnd,
853
+ 'fileStart': fileStart,
854
+ 'fileEnd': fileEnd,
805
855
  'lineNum': lineNum,
806
856
  }
807
-
808
857
  return ret
809
858
 
859
+ @staticmethod
860
+ def getIndentForCodeTracebackLine(msg):
861
+ """Determine the indentation to recreate traceback lines
862
+
863
+ Args:
864
+ msg (str): The traceback line
865
+
866
+ Returns:
867
+ indent (str): A string of zero or more spaces used for indentation
868
+ """
869
+ indent = ""
870
+ match = re.match(r"^ *", msg)
871
+ if match:
872
+ indent = match.group() * 2
873
+ return indent
874
+
875
+ def pre_write(self, msg, error=False):
876
+ """In order to make a stack-trace provide clickable hyperlinks, it must be sent
877
+ to self.write line-by-line, like a actual exception traceback is. So, we check
878
+ if msg has the stack marker str, if so, send it line by line, otherwise, just
879
+ pass msg on to self.write.
880
+ """
881
+ stack_marker = "Stack (most recent call last)"
882
+ index = msg.find(stack_marker)
883
+ has_stack_marker = index > -1
884
+
885
+ if has_stack_marker:
886
+ lines = msg.split("\n")
887
+ for line in lines:
888
+ line = "{}\n".format(line)
889
+ self.write(line, error=error)
890
+ else:
891
+ self.write(msg, error=error)
892
+
810
893
  def write(self, msg, error=False):
811
894
  """write the message to the logger"""
895
+ if not msg:
896
+ return
897
+
812
898
  # Convert the stream_manager's stream to the boolean value this function expects
813
899
  error = error == stream.STDERR
814
900
  # Check that we haven't been garbage collected before trying to write.
@@ -859,25 +945,50 @@ class ConsolePrEdit(QTextEdit):
859
945
  # display normal output. Exclude ConsolePrEdits
860
946
  info = info if info else self.parseErrorHyperLinkInfo(msg)
861
947
  filename = info.get("filename", "") if info else ""
948
+
949
+ # Determine if this is a workbox line of code, or code run directly
950
+ # in the console
951
+ isWorkbox = '<WorkboxSelection>' in filename or '<Workbox>' in filename
862
952
  isConsolePrEdit = '<ConsolePrEdit>' in filename
863
953
 
954
+ # Starting in Python 3, tracebacks don't include the code executed
955
+ # for stdin, so workbox code won't appear. This attempts to include
956
+ # it.
957
+ if isWorkbox:
958
+ match = self.workbox_pattern.search(msg)
959
+ workboxName = match.groupdict().get("workboxName")
960
+ lineNum = int(match.groupdict().get("lineNum")) - 1
961
+
962
+ workboxLine = self.getWorkboxLine(workboxName, lineNum)
963
+ if workboxLine:
964
+ indent = self.getIndentForCodeTracebackLine(msg)
965
+ msg = "{}{}{}".format(msg, indent, workboxLine)
966
+
967
+ elif isConsolePrEdit:
968
+ consoleLine = self.consoleLine
969
+ indent = self.getIndentForCodeTracebackLine(msg)
970
+ msg = "{}{}{}\n".format(msg, indent, consoleLine)
971
+
864
972
  # To make it easier to see relevant lines of a traceback, optionally insert
865
973
  # a newline separating internal PrEditor code from the code run by user.
866
974
  if self.addSepNewline:
867
975
  if sepPreditorTrace:
868
- msg += "\n"
976
+ msg = "\n" + msg
869
977
  self.addSepNewline = False
870
978
 
871
979
  preditorCalls = ("cmdresult = e", "exec(compiled,")
872
980
  if msg.strip().startswith(preditorCalls):
873
981
  self.addSepNewline = True
874
982
 
983
+ # Error tracebacks and logging.stack_info supply msg's differently,
984
+ # so modify it here, so we get consistent results.
985
+ msg = msg.replace("\n\n", "\n")
986
+
875
987
  if info and doHyperlink and not isConsolePrEdit:
876
988
  fileStart = info.get("fileStart")
877
989
  fileEnd = info.get("fileEnd")
878
990
  lineNum = info.get("lineNum")
879
991
 
880
- isWorkbox = '<WorkboxSelection>' in filename or '<Workbox>' in filename
881
992
  if isWorkbox:
882
993
  split = filename.split(':')
883
994
  workboxIdx = split[-1]
@@ -1033,7 +1033,7 @@ class LoggerWindow(Window):
1033
1033
  # Create timer to autohide status messages
1034
1034
  self.statusTimer = QTimer()
1035
1035
  self.statusTimer.setSingleShot(True)
1036
- self.statusTimer.setInterval(2000)
1036
+ self.statusTimer.setInterval(5000)
1037
1037
  self.statusTimer.timeout.connect(self.clearStatusText)
1038
1038
 
1039
1039
  def clearStatusText(self):
@@ -118,7 +118,7 @@ class WorkboxMixin(object):
118
118
  raise NotImplementedError("Mixin method not overridden.")
119
119
 
120
120
  def __exec_selected__(self, truncate=True):
121
- txt, line = self.__selected_text__()
121
+ txt, lineNum = self.__selected_text__()
122
122
 
123
123
  # Remove any leading white space shared across all lines
124
124
  txt = textwrap.dedent(txt)
@@ -129,7 +129,7 @@ class WorkboxMixin(object):
129
129
  # Make workbox line numbers match the workbox line numbers, by adding
130
130
  # the appropriate number of newlines to mimic it's original position in
131
131
  # the workbox.
132
- txt = '\n' * line + txt
132
+ txt = '\n' * lineNum + txt
133
133
 
134
134
  # execute the code
135
135
  title = self.__workbox_trace_title__(selection=True)
@@ -207,7 +207,10 @@ class WorkboxWidget(WorkboxMixin, DocumentEditor):
207
207
 
208
208
  @classmethod
209
209
  def __write_file__(cls, filename, txt, encoding=None):
210
- # Save unix newlines for simplicity
210
+ # Save unix newlines for simplicity. This should only be called for
211
+ # files which are not linked, so we don't inadvertently change a file's
212
+ # line-endings. For linked files, call saveAs, which bypasses this
213
+ # method writes without converting to unix line endings.
211
214
  txt = cls.__unix_end_lines__(txt)
212
215
  super(WorkboxWidget, cls).__write_file__(filename, txt, encoding=encoding)
213
216
 
@@ -72,9 +72,6 @@ class DocumentEditor(QsciScintilla):
72
72
  fontsChanged = Signal(
73
73
  QFont, QFont
74
74
  ) # emits the font size change (font size, margin font size)
75
- documentSaved = Signal(
76
- QsciScintilla, object
77
- ) # (DocumentEditor, filename) emitted when ever the document is saved.
78
75
 
79
76
  def __init__(self, parent, filename='', lineno=0, delayable_engine='default'):
80
77
  super(DocumentEditor, self).__init__(parent)
@@ -145,7 +142,7 @@ class DocumentEditor(QsciScintilla):
145
142
  self.customContextMenuRequested.connect(self.showMenu)
146
143
  self.selectionChanged.connect(self.updateSelectionInfo)
147
144
  window = self.window()
148
- if hasattr(window, 'openFileMonitor'):
145
+ if hasattr(window, 'styleSheetChanged'):
149
146
  window.styleSheetChanged.connect(self.updateColorScheme)
150
147
 
151
148
  # Create shortcuts
@@ -1179,8 +1176,6 @@ class DocumentEditor(QsciScintilla):
1179
1176
  try:
1180
1177
  txt = self.text()
1181
1178
  WorkboxMixin.__write_file__(filename, txt, encoding=self._encoding)
1182
- with open(filename, "w", encoding=self._encoding) as f:
1183
- f.write(self.text())
1184
1179
  except PermissionError as error:
1185
1180
  logger.debug('An error occurred while saving')
1186
1181
  QMessageBox.question(
@@ -1191,9 +1186,6 @@ class DocumentEditor(QsciScintilla):
1191
1186
  )
1192
1187
  return False
1193
1188
 
1194
- # notify that the document was saved
1195
- self.documentSaved.emit(self, filename)
1196
-
1197
1189
  # update the file
1198
1190
  if setFilename:
1199
1191
  self.updateFilename(filename)
@@ -6,11 +6,61 @@ import sys
6
6
  from . import STDERR, STDOUT
7
7
 
8
8
 
9
- class Director(io.TextIOBase):
9
+ class _DirectorBuffer(io.RawIOBase):
10
+ """Binary buffer that forwards text writes to the manager.
11
+
12
+ This makes the stream more compatible including if enabled when running tox.
13
+
14
+ Args:
15
+ manager (Manager): The manager that writes are stored in.
16
+ state: The state passed to the manager. This is often ``preditor.stream.STDOUT``
17
+ or ``preditor.stream.STDERR``.
18
+ old_stream: A second stream that will be written to every time this stream
19
+ is written to. This allows this object to replace sys.stdout and still
20
+ send that output to the original stdout, which is useful for not breaking
21
+ DCC's script editors. Pass False to disable this feature. If you pass None
22
+ and state is set to ``preditor.stream.STDOUT`` or ``preditor.stream.STDERR``
23
+ this will automatically be set to the current sys.stdout or sys.stderr.
24
+ name (str, optional): Stored on self.name.
25
+ """
26
+
27
+ def __init__(self, manager, state, old_stream=None, name='nul'):
28
+ super().__init__()
29
+ self.manager = manager
30
+ self.state = state
31
+ self.old_stream = old_stream
32
+ self.name = name
33
+
34
+ def flush(self):
35
+ if self.old_stream:
36
+ self.old_stream.flush()
37
+ super().flush()
38
+
39
+ def writable(self):
40
+ return True
41
+
42
+ def write(self, b):
43
+ if isinstance(b, memoryview):
44
+ b = b.tobytes()
45
+
46
+ # Decode incoming bytes (TextIOWrapper encodes before sending here)
47
+ msg = b.decode("utf-8", errors="replace")
48
+ self.manager.write(msg, self.state)
49
+
50
+ if self.old_stream:
51
+ self.old_stream.write(msg)
52
+
53
+ return len(b)
54
+
55
+
56
+ class Director(io.TextIOWrapper):
10
57
  """A file like object that stores the text written to it in a manager.
11
58
  This manager can be shared between multiple Directors to build a single
12
59
  continuous history of all writes.
13
60
 
61
+ While this uses a buffer under the hood, buffering is disabled and any calls
62
+ to write will automatically flush the buffer.
63
+
14
64
  Args:
15
65
  manager (Manager): The manager that writes are stored in.
16
66
  state: The state passed to the manager. This is often ``preditor.stream.STDOUT``
@@ -24,14 +74,11 @@ class Director(io.TextIOBase):
24
74
  """
25
75
 
26
76
  def __init__(self, manager, state, old_stream=None, *args, **kwargs):
27
- super(Director, self).__init__(*args, **kwargs)
28
- self.manager = manager
29
- self.state = state
30
-
31
77
  # Keep track of whether we wrapped a std stream
32
78
  # that way we don't .close() any streams that we don't control
33
79
  self.std_stream_wrapped = False
34
80
 
81
+ name = 'nul'
35
82
  if old_stream is False:
36
83
  old_stream = None
37
84
  elif old_stream is None:
@@ -39,15 +86,28 @@ class Director(io.TextIOBase):
39
86
  # On Windows if we're in pythonw.exe, then sys.stdout is named "nul"
40
87
  # And it uses cp1252 encoding (which breaks with unicode)
41
88
  # So if we find this nul TextIOWrapper, it's safe to just skip it
42
- if getattr(sys.stdout, 'name', '') != 'nul':
89
+ name = getattr(sys.stdout, 'name', '')
90
+ if name != 'nul':
43
91
  self.std_stream_wrapped = True
44
92
  old_stream = sys.stdout
45
93
  elif state == STDERR:
46
- if getattr(sys.stderr, 'name', '') != 'nul':
94
+ name = getattr(sys.stderr, 'name', '')
95
+ if name != 'nul':
47
96
  self.std_stream_wrapped = True
48
97
  old_stream = sys.stderr
49
98
 
50
99
  self.old_stream = old_stream
100
+ self.manager = manager
101
+ self.state = state
102
+
103
+ # Build the buffer. This provides the expected interface for tox, etc.
104
+ raw = _DirectorBuffer(manager, state, old_stream, name)
105
+ buffer = io.BufferedWriter(raw)
106
+
107
+ super().__init__(buffer, encoding="utf-8", write_through=True, *args, **kwargs)
108
+
109
+ def __repr__(self):
110
+ return f"<Director state={self.state} old_stream={self.old_stream!r}>"
51
111
 
52
112
  def close(self):
53
113
  if (
@@ -58,16 +118,27 @@ class Director(io.TextIOBase):
58
118
  ):
59
119
  self.old_stream.close()
60
120
 
61
- super(Director, self).close()
121
+ super().close()
62
122
 
63
- def flush(self):
64
- if self.old_stream:
65
- self.old_stream.flush()
123
+ def write(self, msg):
124
+ super().write(msg)
125
+ # Force a write of any buffered data
126
+ self.flush()
66
127
 
67
- super(Director, self).flush()
128
+ # These methods enable terminal features like color coding etc.
129
+ def isatty(self):
130
+ if self.old_stream is not None:
131
+ return self.old_stream.isatty()
132
+ return False
68
133
 
69
- def write(self, msg):
70
- self.manager.write(msg, self.state)
134
+ @property
135
+ def encoding(self):
136
+ if self.old_stream is not None:
137
+ return self.old_stream.encoding
138
+ return super().encoding
71
139
 
72
- if self.old_stream:
73
- self.old_stream.write(msg)
140
+ @property
141
+ def errors(self):
142
+ if self.old_stream is not None:
143
+ return self.old_stream.errors
144
+ return super().errors
preditor/version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '1.4.0'
32
- __version_tuple__ = version_tuple = (1, 4, 0)
31
+ __version__ = version = '1.5.0'
32
+ __version_tuple__ = version_tuple = (1, 5, 0)
33
33
 
34
- __commit_id__ = commit_id = 'g79cb36c80'
34
+ __commit_id__ = commit_id = 'gb7045f3af'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PrEditor
3
- Version: 1.4.0
3
+ Version: 1.5.0
4
4
  Summary: A python REPL and Editor and console based on Qt.
5
5
  Author-email: Blur Studio <opensource@blur.com>
6
6
  License: LGPL-3.0
@@ -4,7 +4,7 @@ preditor/about_module.py,sha256=_jhd2vaWArnnw2qvsZtOSQvntec9PG_PCiSFbcS1j_I,5347
4
4
  preditor/cli.py,sha256=kyVr0V43KYSMLIEWXH54CA0ByFmPcpbFF-8cli6PVow,5300
5
5
  preditor/config.py,sha256=DTDqJ8cVnbvAE8IytAREMV7HJS2b3DLH1jtFIkdTo8c,11883
6
6
  preditor/contexts.py,sha256=xxRbOFORsvlG___EuSiKuT1aiKJvnkFojFZFZE0HPNk,5147
7
- preditor/debug.py,sha256=uhgJdCV7UI25lYP0E6jXaDl_hjHTOhDQ9_qWJmOv3tk,4613
7
+ preditor/debug.py,sha256=9BkNis3l4gockQJpblxe6jnh6OyMITKzY3WKd035vGI,4625
8
8
  preditor/enum.py,sha256=snG5V259dH9SI1kwBqZeZdhat36F1iAmIjYErosnDUg,23489
9
9
  preditor/excepthooks.py,sha256=UZ2PsxUo8hA_PBabAXsQkiwKgTLgY_3lueFymIb0V50,5127
10
10
  preditor/logging_config.py,sha256=bGRCaSq6ugPG2L5keTpw5CNiQwi9PFDxDMDhx_VLHsg,1583
@@ -13,7 +13,7 @@ preditor/plugins.py,sha256=RAeyvdZxQsZY313ae5aAhahqpjuhaXJzDxPyLcR-09U,4401
13
13
  preditor/prefs.py,sha256=BPtSsdv2yuiRpIaqEml9fxlVYKHNfqQ77hp5YIQRDBg,2172
14
14
  preditor/settings.py,sha256=DV9_DbJorEnhdIvW15E7h7PswlQUsy0UlA8bXUYN0og,2206
15
15
  preditor/streamhandler_helper.py,sha256=kiU6T9WqJ3JKTTKCa7IUU8brwK7zO5UUpEzLhEfKe44,1788
16
- preditor/version.py,sha256=6vbYTZLusVDz8j8nBu2-Zv-MBvhlzKtADFBJuoWUprg,712
16
+ preditor/version.py,sha256=9Si62UWsEQhvgE6BKzBJWtlwXjMhsCJF_E0gnxJgjEU,712
17
17
  preditor/weakref.py,sha256=b--KomFAHcMWr3DEAIN2j3XxRhjDWKw0WABXyn1nxDg,12177
18
18
  preditor/cores/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  preditor/cores/core.py,sha256=mdVXlEPDh8kIdOpMDqi8P1VaqfVvyu5cXBq_toONcaM,586
@@ -32,7 +32,7 @@ preditor/gui/__init__.py,sha256=DeOH5K4_M0YLNx1i7NRvwCgwjyjkre4vVwlr5OEMx9Q,3423
32
32
  preditor/gui/app.py,sha256=EhVsVMr5C5WSKNDlxGawzg-3lbTJxDMLi2fPomECacM,5869
33
33
  preditor/gui/codehighlighter.py,sha256=wUOgLDhcAQf72DSS65r9_RYdv6PVJwWFXTdOPvvps_A,6790
34
34
  preditor/gui/completer.py,sha256=U2FBJA_ceFq_viGqPogncH-6vhrtTcpxAF61SUnaOJ8,7813
35
- preditor/gui/console.py,sha256=BEvEU7yjjn1kz1BF9T7JlqXpLCP7pI5nP6Rbdh2P-os,36476
35
+ preditor/gui/console.py,sha256=It-cXB91kwtbmkkkTwZ78fi3jt4SnHQDId5GmsyULtY,40765
36
36
  preditor/gui/dialog.py,sha256=fasmBDhN-B6uretbSQ3x1SxImsQLSKIMw4PC9B8BimI,6535
37
37
  preditor/gui/drag_tab_bar.py,sha256=EgEXdV4odNj_1_YiGP2kmpGKUaBPe75JTwudU8Xj-Gw,8113
38
38
  preditor/gui/editor_chooser.py,sha256=lv1eY0UJOulX1l-P-ZQEoneYz6BNX2VkXEbg3GUu1ag,1991
@@ -41,15 +41,15 @@ preditor/gui/find_files.py,sha256=TtsjHXKWvwKrxHYZryB_NPANoFpMRlAxWJp1hA6Ny2I,43
41
41
  preditor/gui/level_buttons.py,sha256=h0pMMzp-ElwcN_qfR4EBQtXn1C666KVcnR9dMoixD3E,12597
42
42
  preditor/gui/logger_window_handler.py,sha256=43-DxzuNJq6UV6Ofc4TKRt179Sf5AxDkVDGrtq_Knok,1571
43
43
  preditor/gui/logger_window_plugin.py,sha256=Lj9Q8L82GjzZ21ZI5W0FCHhrPHNALIunT_C9ua15l2w,1272
44
- preditor/gui/loggerwindow.py,sha256=u0FLCfS5NM8r31PJE0D-iLiq5j40hw46q8elIqnDDOM,54458
44
+ preditor/gui/loggerwindow.py,sha256=PaTTa_vTXDAjEWxwPBEtTosGppu9S38wI3zOUy7MGSI,54458
45
45
  preditor/gui/newtabwidget.py,sha256=5aCWn9xAl5h1oZACqVuEsOAbzKTS2RegrLI41gROC8A,1971
46
46
  preditor/gui/set_text_editor_path_dialog.py,sha256=bn8IeQHXPSU4PLYXQmSxKB1V8iuJaI1PA5aDJNgxXks,2292
47
47
  preditor/gui/status_label.py,sha256=SlNRmPc28S4E2OFVmErv0DmZstk4011Q_7uLp43SF0A,3320
48
48
  preditor/gui/suggest_path_quotes_dialog.py,sha256=QUJf_9hs8wOO6bFOr8_Z2xnNhSA8TfKFMOzheUqUDnY,1822
49
49
  preditor/gui/window.py,sha256=6Ztjqb0Xfh8DsI7hBF4Rg-4-gWPZKTV4GRJiz3V8O6Q,5904
50
- preditor/gui/workbox_mixin.py,sha256=s_JTCmR-_ZXcAuQ-jKsw_DQh08IAFr3SJONYE5bQRP8,18556
50
+ preditor/gui/workbox_mixin.py,sha256=_XrivnyBOjnjHE35WrDXGJbwxP0vFkC2avhypLOHd_U,18562
51
51
  preditor/gui/workbox_text_edit.py,sha256=wrJcGqIJ2-5BqEcP_qVKNlWUD8Geo8IxrIXncnDG6yw,4472
52
- preditor/gui/workboxwidget.py,sha256=7m2QzuOfoTuB2H9mODnwZ1npX0zI_1bjeQp3_Lh990s,10588
52
+ preditor/gui/workboxwidget.py,sha256=-u4DiwgJ6Oc_WjeWSny5HKu4KfJY7uQ0wUftnuH9R7Q,10840
53
53
  preditor/gui/fuzzy_search/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
54
  preditor/gui/fuzzy_search/fuzzy_search.py,sha256=zohr6oAE99FZFlLjqKZajBrdyJIYLW96rcCOy5Bn1i0,3714
55
55
  preditor/gui/group_tab_widget/__init__.py,sha256=EalGlpDcinbI6WdwmG7BK94519rUHfzxA0qez-o4m6k,13637
@@ -116,7 +116,7 @@ preditor/resource/lang/python.json,sha256=CXiQh0jcgd-OCrM-s9IF7s4o-g5WRA4vDaAyTR
116
116
  preditor/resource/stylesheet/Bright.css,sha256=SfnPRBqfqEL4IF8RGt9PpLX_cSiGpfG9Q2hE1F9uTsk,2480
117
117
  preditor/resource/stylesheet/Dark.css,sha256=Sige7beBhRyfav9_mXvn-LhksxbX0_WEgpZSKhmPavc,5384
118
118
  preditor/scintilla/__init__.py,sha256=IDndbcS8KW1TMcQTA1Vd-LzcdsNtOUfyldnjkKae0yw,956
119
- preditor/scintilla/documenteditor.py,sha256=9DyZBNPD59W1x8CGFHhxlgf9WTHi6ni7EIlyL7aMnIM,81477
119
+ preditor/scintilla/documenteditor.py,sha256=sLdVtRsq63LZEd4_Bmpn5JEAmTpBgFG_M4MZUxfz6yA,81129
120
120
  preditor/scintilla/finddialog.py,sha256=WxNVvkCfXrw_8E3-7tS1DIS9H1-ioLASDgIbniDxz3g,2376
121
121
  preditor/scintilla/delayables/__init__.py,sha256=lj9tMc3IL2QeaN858Ixt_n7clJngbKqG2sk66vIcFcQ,275
122
122
  preditor/scintilla/delayables/smart_highlight.py,sha256=5emI4StsQCIYizoFsib1rdw0gnUarV9TQ6CwxmzXXpU,3623
@@ -151,17 +151,17 @@ preditor/scintilla/lexers/mulexer.py,sha256=tlyiKYBDRpmxcrH9FGi-Ogz2alHPhyqNaqVr
151
151
  preditor/scintilla/lexers/pythonlexer.py,sha256=dh_wSBhhYIIV1hUF_0cWbZCdMBMsOB6EY6x8valWo1s,1737
152
152
  preditor/scintilla/ui/finddialog.ui,sha256=CEXouVKqVCDOfMBciK-89OmsGe2Kr6XdMbSPiffp0PA,4048
153
153
  preditor/stream/__init__.py,sha256=SxILA3U3W8aNfVBd_oJ4-WXkA214cl1zGLSCelFx5QU,2682
154
- preditor/stream/director.py,sha256=Gklbl6jwTmB0BtyR6MZxRytdlufaz5MoiW9Le9WFTmo,2733
154
+ preditor/stream/director.py,sha256=UIGhLoZPCMHlDT04CPbrm4aTzggd4A9wR2Fitu2LT08,5296
155
155
  preditor/stream/manager.py,sha256=NP4lf6hd5L_Ui-9Ws66gVEk6ZL8YqF7BxOzUsdrh3v0,2811
156
156
  preditor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
157
  preditor/utils/cute.py,sha256=tLTChQ1-zMzHHaKpG85u4FbtJl_2R1E8-uckpOQbEEM,1057
158
158
  preditor/utils/stylesheets.py,sha256=EVWZNq3WnaRiyUPoYMKQo_dLEwbRyKu26b03I1JDA-s,1622
159
159
  preditor/utils/text_search.py,sha256=21kuSDTpLIPUcriB81WP1kWfzuDBuP13ZtHUtypP5jE,14218
160
- preditor-1.4.0.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
160
+ preditor-1.5.0.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
161
161
  tests/find_files/test_find_files.py,sha256=ETVe1tC666uTc_5pPhjzPCaMrMkYUB8iKGXDfW9usgI,2722
162
162
  tests/ide/test_delayable_engine.py,sha256=Nv6SQXpwIdfgRbEOsEcR-7jhjZ6E0THPdwDoPvAM6y4,5948
163
- preditor-1.4.0.dist-info/METADATA,sha256=zA-ZtzJ0KNl6-ufO_quM7e2eyxPAF0xkaUaWRpQHoio,12744
164
- preditor-1.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
165
- preditor-1.4.0.dist-info/entry_points.txt,sha256=mpe0HFD_oIEBNPTJNyUEbmMV6Ivrp4EuYyZ34C5d_PU,519
166
- preditor-1.4.0.dist-info/top_level.txt,sha256=dZSBDecBQovRyqbFdvwk1AvMon636dJ14vr9ov1LSPs,20
167
- preditor-1.4.0.dist-info/RECORD,,
163
+ preditor-1.5.0.dist-info/METADATA,sha256=GsCQMiLBp5l5PPuC3pq34mqNgg_DFvlIA2f6fAwWQfI,12744
164
+ preditor-1.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
165
+ preditor-1.5.0.dist-info/entry_points.txt,sha256=mpe0HFD_oIEBNPTJNyUEbmMV6Ivrp4EuYyZ34C5d_PU,519
166
+ preditor-1.5.0.dist-info/top_level.txt,sha256=dZSBDecBQovRyqbFdvwk1AvMon636dJ14vr9ov1LSPs,20
167
+ preditor-1.5.0.dist-info/RECORD,,