PrEditor 1.1.0__py3-none-any.whl → 1.2.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.

Files changed (56) hide show
  1. preditor/__init__.py +4 -1
  2. preditor/about_module.py +6 -2
  3. preditor/dccs/.hab.json +10 -0
  4. preditor/dccs/maya/PrEditor_maya.mod +0 -1
  5. preditor/dccs/maya/README.md +22 -0
  6. preditor/dccs/maya/plug-ins/PrEditor_maya.py +32 -1
  7. preditor/dccs/studiomax/PackageContents.xml +32 -0
  8. preditor/dccs/studiomax/PrEditor-PrEditor_Show.mcr +8 -0
  9. preditor/dccs/studiomax/README.md +17 -0
  10. preditor/dccs/studiomax/preditor.ms +16 -0
  11. preditor/dccs/studiomax/preditor_menu.mnx +7 -0
  12. preditor/debug.py +7 -3
  13. preditor/excepthooks.py +1 -1
  14. preditor/gui/app.py +2 -2
  15. preditor/gui/codehighlighter.py +10 -24
  16. preditor/gui/completer.py +17 -6
  17. preditor/gui/console.py +77 -47
  18. preditor/gui/dialog.py +10 -7
  19. preditor/gui/drag_tab_bar.py +7 -7
  20. preditor/gui/errordialog.py +2 -2
  21. preditor/gui/find_files.py +7 -5
  22. preditor/gui/fuzzy_search/fuzzy_search.py +8 -4
  23. preditor/gui/group_tab_widget/__init__.py +4 -4
  24. preditor/gui/group_tab_widget/grouped_tab_models.py +4 -4
  25. preditor/gui/group_tab_widget/grouped_tab_widget.py +6 -4
  26. preditor/gui/level_buttons.py +16 -1
  27. preditor/gui/loggerwindow.py +32 -20
  28. preditor/gui/set_text_editor_path_dialog.py +3 -1
  29. preditor/gui/window.py +4 -4
  30. preditor/gui/workbox_mixin.py +40 -11
  31. preditor/gui/workbox_text_edit.py +5 -3
  32. preditor/gui/workboxwidget.py +16 -12
  33. preditor/logging_config.py +5 -2
  34. preditor/scintilla/__init__.py +19 -1
  35. preditor/scintilla/delayables/smart_highlight.py +7 -4
  36. preditor/scintilla/delayables/spell_check.py +5 -4
  37. preditor/scintilla/documenteditor.py +165 -116
  38. preditor/scintilla/finddialog.py +3 -3
  39. preditor/scintilla/lang/language.py +1 -1
  40. preditor/scintilla/lexers/cpplexer.py +3 -2
  41. preditor/scintilla/lexers/javascriptlexer.py +6 -4
  42. preditor/scintilla/lexers/maxscriptlexer.py +8 -7
  43. preditor/scintilla/lexers/mellexer.py +3 -2
  44. preditor/scintilla/lexers/mulexer.py +3 -2
  45. preditor/scintilla/lexers/pythonlexer.py +7 -6
  46. preditor/utils/cute.py +9 -8
  47. preditor/version.py +16 -3
  48. {preditor-1.1.0.dist-info → preditor-1.2.0.dist-info}/METADATA +69 -32
  49. {preditor-1.1.0.dist-info → preditor-1.2.0.dist-info}/RECORD +55 -46
  50. preditor-1.2.0.dist-info/top_level.txt +3 -0
  51. tests/find_files/test_find_files.py +74 -0
  52. tests/ide/test_delayable_engine.py +171 -0
  53. preditor-1.1.0.dist-info/top_level.txt +0 -1
  54. {preditor-1.1.0.dist-info → preditor-1.2.0.dist-info}/WHEEL +0 -0
  55. {preditor-1.1.0.dist-info → preditor-1.2.0.dist-info}/entry_points.txt +0 -0
  56. {preditor-1.1.0.dist-info → preditor-1.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,11 +1,13 @@
1
1
  from __future__ import absolute_import
2
2
 
3
- from PyQt5.Qsci import QsciLexerJavaScript
4
3
  from Qt.QtGui import QColor
5
4
 
5
+ from .. import Qsci
6
6
 
7
- class JavaScriptLexer(QsciLexerJavaScript):
8
- # Items in this list will be highlighted using the color for self.KeywordSet2
7
+
8
+ class JavaScriptLexer(Qsci.QsciLexerJavaScript):
9
+ # Items in this list will be highlighted using the color for
10
+ # `Qsci.QsciLexerJavaScript.KeywordSet2`
9
11
  highlightedKeywords = ''
10
12
 
11
13
  def defaultFont(self, index):
@@ -13,7 +15,7 @@ class JavaScriptLexer(QsciLexerJavaScript):
13
15
  return self.font(0)
14
16
 
15
17
  def defaultPaper(self, style):
16
- if style == self.KeywordSet2:
18
+ if style == Qsci.QsciLexerJavaScript.KeywordSet2:
17
19
  # Set the highlight color for this lexer
18
20
  return QColor(155, 255, 155)
19
21
  return super(JavaScriptLexer, self).defaultPaper(style)
@@ -4,7 +4,8 @@ import re
4
4
  from builtins import str as text
5
5
 
6
6
  from future.utils import iteritems
7
- from PyQt5.Qsci import QsciLexerCustom, QsciScintilla
7
+
8
+ from .. import Qsci, QsciScintilla
8
9
 
9
10
  MS_KEYWORDS = """
10
11
  if then else not and or key collect
@@ -17,12 +18,12 @@ filein open close flush include print
17
18
  """
18
19
 
19
20
 
20
- class MaxscriptLexer(QsciLexerCustom):
21
+ class MaxscriptLexer(Qsci.QsciLexerCustom):
21
22
  # Items in this list will be highligheded using the color for self.SmartHighlight
22
23
  highlightedKeywords = ''
23
24
 
24
25
  def __init__(self, parent=None):
25
- QsciLexerCustom.__init__(self, parent)
26
+ super(MaxscriptLexer, self).__init__(parent)
26
27
  self._styles = {
27
28
  0: 'Default',
28
29
  1: 'Comment',
@@ -48,15 +49,15 @@ class MaxscriptLexer(QsciLexerCustom):
48
49
  return QColor(40, 160, 40)
49
50
 
50
51
  elif style in (self.Keyword, self.Operator):
51
- return QColor(Qt.blue)
52
+ return QColor(Qt.GlobalColor.blue)
52
53
 
53
54
  elif style == self.Number:
54
- return QColor(Qt.red)
55
+ return QColor(Qt.GlobalColor.red)
55
56
 
56
57
  elif style == self.String:
57
58
  return QColor(180, 140, 30)
58
59
 
59
- return QsciLexerCustom.defaultColor(self, style)
60
+ return super(MaxscriptLexer, self).defaultColor(style)
60
61
 
61
62
  def defaultPaper(self, style):
62
63
  if style == self.SmartHighlight:
@@ -77,7 +78,7 @@ class MaxscriptLexer(QsciLexerCustom):
77
78
  return MS_KEYWORDS
78
79
  if style == self.SmartHighlight:
79
80
  return self.highlightedKeywords
80
- return QsciLexerCustom.keywords(self, style)
81
+ return super(MaxscriptLexer, self).keywords(style)
81
82
 
82
83
  def processChunk(self, chunk, lastState, keywords):
83
84
  # process the length of the chunk
@@ -2,9 +2,10 @@ from __future__ import absolute_import
2
2
 
3
3
  import re
4
4
 
5
- from PyQt5.Qsci import QsciLexerCPP
6
5
  from Qt.QtGui import QColor
7
6
 
7
+ from .. import Qsci
8
+
8
9
  MEL_SYNTAX = """and array as case catch continue do else exit float for from global if
9
10
  in int local not of off on or proc random return select string then throw to try vector
10
11
  when where while with true false
@@ -310,7 +311,7 @@ xgmWrapXGen xgmr xpmPicker
310
311
  """
311
312
 
312
313
 
313
- class MelLexer(QsciLexerCPP):
314
+ class MelLexer(Qsci.QsciLexerCPP):
314
315
  # Items in this list will be highlighted using the color for self.GlobalClass
315
316
  _highlightedKeywords = ''
316
317
  # Mel uses $varName for variables, so we have to allow them in words
@@ -1,14 +1,15 @@
1
1
  from __future__ import absolute_import
2
2
 
3
- from PyQt5.Qsci import QsciLexerCPP
4
3
  from Qt.QtGui import QColor
5
4
 
5
+ from .. import Qsci
6
+
6
7
  MU_KEYWORDS = """
7
8
  method string Color use require module for_each let global function nil void
8
9
  """
9
10
 
10
11
 
11
- class MuLexer(QsciLexerCPP):
12
+ class MuLexer(Qsci.QsciLexerCPP):
12
13
  # Items in this list will be highlighted using the color for self.KeywordSet2
13
14
  highlightedKeywords = ''
14
15
 
@@ -1,22 +1,23 @@
1
1
  from __future__ import absolute_import
2
2
 
3
- from PyQt5.Qsci import QsciLexerPython
4
3
  from Qt.QtGui import QColor
5
4
 
5
+ from .. import Qsci
6
6
 
7
- class PythonLexer(QsciLexerPython):
8
- # Items in this list will be highlighted using the color for
9
- # self.HighlightedIdentifier
7
+
8
+ class PythonLexer(Qsci.QsciLexerPython):
9
+ # Items in this list will be highlighted using the color
10
+ # for Qsci.QsciLexerPython.HighlightedIdentifier.
10
11
  highlightedKeywords = ''
11
12
 
12
13
  def __init__(self, *args):
13
14
  super(PythonLexer, self).__init__(*args)
14
15
 
15
16
  # set the indentation warning
16
- self.setIndentationWarning(self.Inconsistent)
17
+ self.setIndentationWarning(Qsci.QsciLexerPython.IndentationWarning.Inconsistent)
17
18
 
18
19
  def defaultPaper(self, style):
19
- if style == self.HighlightedIdentifier:
20
+ if style == Qsci.QsciLexerPython.HighlightedIdentifier:
20
21
  # Set the highlight color for this lexer
21
22
  return QColor(155, 255, 155)
22
23
  return super(PythonLexer, self).defaultPaper(style)
preditor/utils/cute.py CHANGED
@@ -7,19 +7,20 @@ from Qt.QtWidgets import QApplication
7
7
  def ensureWindowIsVisible(widget):
8
8
  """
9
9
  Checks the widget's geometry against all of the system's screens. If it does
10
- not intersect it will reposition it to the top left corner of the highest
11
- numbered desktop. Returns a boolean indicating if it had to move the
12
- widget.
10
+ not intersect, it will reposition it to the top left corner of the highest
11
+ numbered screen. Returns a boolean indicating if it had to move the widget.
13
12
  """
14
- desktop = QApplication.desktop()
13
+ screens = QApplication.screens()
15
14
  geo = widget.geometry()
16
- for screen in range(desktop.screenCount()):
17
- monGeo = desktop.screenGeometry(screen)
18
- if monGeo.intersects(geo):
15
+
16
+ for screen in screens:
17
+ if screen.geometry().intersects(geo):
19
18
  break
20
19
  else:
20
+ monGeo = screens[-1].geometry() # Use the last screen available
21
21
  geo.moveTo(monGeo.x() + 7, monGeo.y() + 30)
22
- # setting the geometry may trigger a second check if setGeometry is overridden
22
+
23
+ # Setting the geometry may trigger a second check if setGeometry is overridden
23
24
  disable = hasattr(widget, 'checkScreenGeo') and widget.checkScreenGeo
24
25
  if disable:
25
26
  widget.checkScreenGeo = False
preditor/version.py CHANGED
@@ -1,7 +1,14 @@
1
1
  # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
3
 
4
- __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
5
12
 
6
13
  TYPE_CHECKING = False
7
14
  if TYPE_CHECKING:
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
9
16
  from typing import Union
10
17
 
11
18
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
12
20
  else:
13
21
  VERSION_TUPLE = object
22
+ COMMIT_ID = object
14
23
 
15
24
  version: str
16
25
  __version__: str
17
26
  __version_tuple__: VERSION_TUPLE
18
27
  version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
19
30
 
20
- __version__ = version = '1.1.0'
21
- __version_tuple__ = version_tuple = (1, 1, 0)
31
+ __version__ = version = '1.2.0'
32
+ __version_tuple__ = version_tuple = (1, 2, 0)
33
+
34
+ __commit_id__ = commit_id = 'g5a9de95c6'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PrEditor
3
- Version: 1.1.0
3
+ Version: 1.2.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
@@ -10,7 +10,6 @@ Project-URL: Tracker, https://github.com/blurstudio/PrEditor/issues
10
10
  Platform: any
11
11
  Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
14
13
  Classifier: Operating System :: OS Independent
15
14
  Classifier: Programming Language :: Python
16
15
  Classifier: Programming Language :: Python :: 3
@@ -19,11 +18,12 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
19
18
  Requires-Python: >=3.7
20
19
  Description-Content-Type: text/markdown
21
20
  License-File: LICENSE
22
- Requires-Dist: Qt.py
21
+ Requires-Dist: chardet
23
22
  Requires-Dist: configparser>=4.0.2
24
23
  Requires-Dist: future>=0.18.2
25
- Requires-Dist: signalslot>=0.1.2
26
24
  Requires-Dist: importlib-metadata>=4.8.3
25
+ Requires-Dist: Qt.py>=1.4.4
26
+ Requires-Dist: signalslot>=0.1.2
27
27
  Provides-Extra: cli
28
28
  Requires-Dist: click>=7.1.2; extra == "cli"
29
29
  Requires-Dist: click-default-group; extra == "cli"
@@ -38,6 +38,10 @@ Requires-Dist: Flake8-pyproject; extra == "dev"
38
38
  Requires-Dist: pep8-naming; extra == "dev"
39
39
  Requires-Dist: pytest; extra == "dev"
40
40
  Requires-Dist: tox; extra == "dev"
41
+ Provides-Extra: qsci5
42
+ Requires-Dist: QScintilla; extra == "qsci5"
43
+ Provides-Extra: qsci6
44
+ Requires-Dist: PyQt6-QScintilla; extra == "qsci6"
41
45
  Provides-Extra: shortcut
42
46
  Requires-Dist: casement>=0.1.0; platform_system == "Windows" and extra == "shortcut"
43
47
  Dynamic: license-file
@@ -141,13 +145,13 @@ a better `parent_callback`.
141
145
  ## Installing Qt
142
146
 
143
147
  PrEditor is built on Qt, but uses [Qt.py](https://github.com/mottosso/Qt.py) so
144
- you can choose to use PySide2 or PyQt5. We have elected to not directly depend
145
- on either of these packages as if you want to use PrEditor inside of a an existing
146
- application like Maya or Houdini, they already come with PySide2 installed. If
147
- you are using it externally, add them to your pip install command.
148
+ you can choose to use PySide6, PySide2, PyQt6 or PyQt5. We have elected to not
149
+ directly depend on either of these packages so that you can use PrEditor inside
150
+ of existing applications like Maya or Houdini that already come with PySide
151
+ installed. If you are using it externally add them to your pip install command.
148
152
 
149
- - PySide2: `pip install preditor PySide2`
150
- - PyQt5: `pip install preditor PyQt5`
153
+ - PySide6: `pip install preditor PySide6`
154
+ - PyQt6: `pip install preditor PyQt6`
151
155
 
152
156
  ## Cli
153
157
 
@@ -169,35 +173,68 @@ this is only useful for windows.
169
173
  ## QScintilla workbox
170
174
 
171
175
  The more mature QScintilla workbox requires a few extra dependencies that must
172
- be passed manually. It hasn't been added to `extras_require` because we plan to
173
- split it into its own pip module due to it requiring PyQt5 which is a little hard
174
- to get working inside of DCC's that ship with PySide2 by default. Here is the
175
- python 3 pip install command.
176
+ be passed manually. We have added it as pip `optional-dependencies`. QScintilla
177
+ only works with PyQt5/6 and it is a little hard to get PyQt working inside of
178
+ DCC's that ship with PySide2/6 by default. Here is the python 3 pip install command.
176
179
 
177
- - `pip install preditor PyQt5, QScintilla>=2.11.4 aspell-python-py3`
180
+ - PyQt6: `pip install preditor[qsci6] PyQt6, aspell-python-py3`
181
+ - PyQt5: `pip install preditor[qsci5] PyQt5, aspell-python-py3`
178
182
 
179
183
  The aspell-python-py3 requirement is optional to enable spell check.
180
184
 
185
+ You may need to set the `QT_PREFERRED_BINDING` or `QT_PREFERRED_BINDING_JSON`
186
+ [environment variable](https://github.com/mottosso/Qt.py?tab=readme-ov-file#override-preferred-choice) to ensure that PrEditor can use PyQt5/PyQt6.
181
187
 
182
188
  # DCC Integration
183
189
 
184
- ## Maya
185
-
186
- PrEditor is pre-setup to use as a Maya module. To use it, create a virtualenv
187
- with the same python as maya, or install it using mayapy.
188
-
189
- ```
190
- virtualenv venv_preditor
191
- venv_preditor\Scripts\activate
192
- pip install PrEditor
193
- set MAYA_MODULE_PATH=c:\path\to\venv_preditor\Lib\site-packages\preditor\dccs
194
- ```
195
- Note: Due to how maya .mod files works if you are using development installs you
196
- can't use pip editable installs. This is due to the relative path used
197
- `PYTHONPATH +:= ../..` in `PrEditor_maya.mod`. You can modify that to use a hard
198
- coded file path for testing, or add a second .mod file to add the virtualenv's
199
- `site-packages` file path as a hard coded file path.
200
-
190
+ Here are several example integrations for DCC's included in PrEditor. These
191
+ require some setup to manage installing all pip requirements. These will require
192
+ you to follow the [Setup](#setup) instructions below.
193
+
194
+ - [Maya](/preditor/dccs/maya/README.md)
195
+ - [3ds Max](/preditor/dccs/studiomax/README.md)
196
+
197
+ If you are using hab, you can simply add the path to the [preditor](/preditor) folder to your site's `distro_paths`. [See .hab.json](/preditor/dccs/.hab.json)
198
+
199
+ ## Setup
200
+
201
+ PrEditor has many python pip requirements. The easiest way to get access to all
202
+ of them inside an DCC is to create a virtualenv and pip install the requirements.
203
+ You can possibly use the python included with DCC(mayapy), but this guide covers
204
+ using a system install of python.
205
+
206
+ 1. Identify the minor version of python that the dcc is using. Running `sys.version_info[:2]` in the DCC returns the major and minor version of python.
207
+ 2. Download and install the required version of python. Note, you likely only need to match the major and minor version of python(3.11 not 3.11.12). It's recommended that you don't use the windows store to install python as it has had issues when used to create virtualenvs.
208
+ 3. Create a virtualenv using that version of python. On windows you can use `py.exe -3.11` or call the correct python.exe file. Change `-3.11` to match the major and minor version returned by step 1. Note that you should create separate venvs for a given python minor version and potentially for minor versions of Qt if you are using PyQt.
209
+ ```batch
210
+ cd c:\path\to\venv\parent
211
+ py -3.11 -m virtualenv preditor_311
212
+ ```
213
+ 4. Use the newly created pip exe to install PrEditor and its dependencies.
214
+ * This example shows using PySide and the simple TextEdit workbox in a minimal configuration.
215
+ ```batch
216
+ c:\path\to\venv\parent\preditor_311\Scripts\pip install PrEditor
217
+ ```
218
+ * This example shows using QScintilla in PyQt6 for a better editing experience. Note that you need to match the PyQt version used by the DCC, This may require matching the exact version of PyQt.
219
+ ```batch
220
+ c:\path\to\venv\parent\preditor_311\Scripts\pip install PrEditor[qsci6] PyQt6==6.5.3
221
+ ```
222
+
223
+ ### Editable install
224
+
225
+ You should skip this section unless you want to develop PrEditor's code from an git repo using python's editable pip install.
226
+
227
+ Due to how editable installs work you will need to set an environment variable
228
+ specifying the site-packages directory of the virtualenv you created in the
229
+ previous step. On windows this should be the `lib\site-packages` folder inside
230
+ of the venv you just created. Store this in the `PREDITOR_SITE`, this can be done
231
+ permanently or temporarily(via `set "PREDITOR_SITE=c:\path\to\venv\parent\preditor_311\lib\site-packages"`).
232
+
233
+ This is required because you are going to use the path to your git repo's preditor
234
+ folder in the module/plugin loading methods for the the DCC you are using, but
235
+ there is no way to automatically find the virtualenv that your random git repo
236
+ is installed in. In fact, you may have have your git repo installed into multiple
237
+ virtualenvs at once.
201
238
 
202
239
  # Plugins
203
240
 
@@ -1,54 +1,61 @@
1
- preditor/__init__.py,sha256=OJO0Gsh74_OA6lS_q3tgIh2zLS8lr7fzTk0kyCqnz2k,12163
1
+ preditor/__init__.py,sha256=5_8lpwEYbDRsfvTQ3otpseNVCHlJRAR10e2N9rQhAIo,12209
2
2
  preditor/__main__.py,sha256=boRVSmxX6eF8EkzbePtCZbzdcaPseqVae4RPPLp3U1A,449
3
- preditor/about_module.py,sha256=rz1B3vL93AfJsAk_dnqSsDXcBYZJUf4lAdwUYAfwMwU,5085
3
+ 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=lXSdjWjThAuie8WC-B6wZHppDxsBeftJs-LaAMr5l48,4535
7
+ preditor/debug.py,sha256=uhgJdCV7UI25lYP0E6jXaDl_hjHTOhDQ9_qWJmOv3tk,4613
8
8
  preditor/enum.py,sha256=snG5V259dH9SI1kwBqZeZdhat36F1iAmIjYErosnDUg,23489
9
- preditor/excepthooks.py,sha256=DUolMjQxOIqX9czYQfQ4WqSjMIH5VP9ZcaFoI0LRky4,5126
10
- preditor/logging_config.py,sha256=aCqBhnHhcTigpR7neVEPbx4Vc_3ADpiqaBQ7uOd4qRQ,1462
9
+ preditor/excepthooks.py,sha256=UZ2PsxUo8hA_PBabAXsQkiwKgTLgY_3lueFymIb0V50,5127
10
+ preditor/logging_config.py,sha256=bGRCaSq6ugPG2L5keTpw5CNiQwi9PFDxDMDhx_VLHsg,1583
11
11
  preditor/osystem.py,sha256=vRr-WaIzYEO38tJeyHMOlAyrvGaWGBuiyaPx0X9JfZ4,13682
12
12
  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=UNO7UaKPam6Zugzw6NMt_RQBnRzrv9GVeKUjWt-tl6I,511
16
+ preditor/version.py,sha256=zHRWUFacu0mfM24GYuT-vIcPzFr12VT8INArUatU4D0,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
20
- preditor/dccs/maya/PrEditor_maya.mod,sha256=XTZsiqpSj7AjiB0SOZJct06mk1cLivV7sWIZmg1HoFo,46
21
- preditor/dccs/maya/plug-ins/PrEditor_maya.py,sha256=_ybVuvJ3PGTn35VVQXZmjINifYjqPOV3MHBC1WQKvls,3955
20
+ preditor/dccs/.hab.json,sha256=9_x-QXUhqrDJDPXXJF4hS3KZh9S27m6egeS5xYbJrtI,236
21
+ preditor/dccs/maya/PrEditor_maya.mod,sha256=uY9moRGjwKDYt6RdKxw_8oCHSQwZ0cmYRSAknUs7eKo,25
22
+ preditor/dccs/maya/README.md,sha256=b-W0MmhII_y4_NSIPlbjBbPNxciGVAwW4plsLNiDhtc,1155
23
+ preditor/dccs/maya/plug-ins/PrEditor_maya.py,sha256=NI0ysu84GZ8dRMQpesEvSHY2YGra0jiP7N5qxR0ih0A,5102
24
+ preditor/dccs/studiomax/PackageContents.xml,sha256=063SW-C9bje7_ZlJgQnT6ehoV7-42eHaSbZaIsMArQk,1647
25
+ preditor/dccs/studiomax/PrEditor-PrEditor_Show.mcr,sha256=Cju39XiwGHP5AtfgVqxkts9GjFVlZmTK_VUDUO_jegE,164
26
+ preditor/dccs/studiomax/README.md,sha256=grDwWRsCVut8ncEKNHIGFwVGeSJRYDs6oukd-SYM1qc,814
27
+ preditor/dccs/studiomax/preditor.ms,sha256=GeX2taJgSsqJBB8_cCdVMV6-G75xjCWyh1G_8atVR6Y,558
28
+ preditor/dccs/studiomax/preditor_menu.mnx,sha256=AjUOFC9vz4f3qxYYMGo0-wmlYzCo5D6N5hP5Fv0RHc8,684
22
29
  preditor/delayable_engine/__init__.py,sha256=imy_fMPiBQUKkN4CvPcSy_mYvWEpphaTMYZbMPPgjZw,11214
23
30
  preditor/delayable_engine/delayables.py,sha256=GWxv4iTcqFeo7703SMrtotKx4cfq1ujJMNdpmtawPqc,2708
24
31
  preditor/gui/__init__.py,sha256=DeOH5K4_M0YLNx1i7NRvwCgwjyjkre4vVwlr5OEMx9Q,3423
25
- preditor/gui/app.py,sha256=13-K8RKrBhFrnr8IhyWx0phv3U1denqBogYEDZ_1zos,5837
26
- preditor/gui/codehighlighter.py,sha256=3JxXZpZqN3KVZbQgSmO-JldSlf4zFQ0PojWwucTsy5U,7171
27
- preditor/gui/completer.py,sha256=T6fl_4xGVjVtGNuR6ajD1ngjEhrKR6tZ9zPJDYoKn8E,7379
28
- preditor/gui/console.py,sha256=cifASpAbSbVvszLoReY9PMUdFj1qc9PHMJbSGaaHNnU,34830
29
- preditor/gui/dialog.py,sha256=l16G4mHmEhE2ximk-gl7KJJQrJLWUqFwi2ex65e7U7k,6413
30
- preditor/gui/drag_tab_bar.py,sha256=5J-BSKQzS6_WuYxxGqmnUJr6AriTAvwfVK7Q3p7knrM,7933
32
+ preditor/gui/app.py,sha256=EhVsVMr5C5WSKNDlxGawzg-3lbTJxDMLi2fPomECacM,5869
33
+ preditor/gui/codehighlighter.py,sha256=wUOgLDhcAQf72DSS65r9_RYdv6PVJwWFXTdOPvvps_A,6790
34
+ preditor/gui/completer.py,sha256=U2FBJA_ceFq_viGqPogncH-6vhrtTcpxAF61SUnaOJ8,7813
35
+ preditor/gui/console.py,sha256=S4JZz5rkjLKhA5YYXXs6bx_C56BBlVENccnW2DnTeL0,35791
36
+ preditor/gui/dialog.py,sha256=fasmBDhN-B6uretbSQ3x1SxImsQLSKIMw4PC9B8BimI,6535
37
+ preditor/gui/drag_tab_bar.py,sha256=_TFLRyodO5e16R8DNGQjPAwrGk2SBnqtj4Bn8mxr0HI,8018
31
38
  preditor/gui/editor_chooser.py,sha256=lv1eY0UJOulX1l-P-ZQEoneYz6BNX2VkXEbg3GUu1ag,1991
32
- preditor/gui/errordialog.py,sha256=e5VGL8iwSkGreBOg3gZhjVvkrZ7fKbKQ1D91z3EKpr0,2045
33
- preditor/gui/find_files.py,sha256=8_b0oQgL6u8U2FqpR2RzMChME9eYdJq3c3bgXXDeceY,4241
34
- preditor/gui/level_buttons.py,sha256=YVvdpXItbFAGl_vYTBcYvOKNQmmEaHRY63pX30WHBbk,11728
39
+ preditor/gui/errordialog.py,sha256=cRtQ-l40kvQ9awRDqAjetwT8S4oD1iztPbEEly7GYBU,2075
40
+ preditor/gui/find_files.py,sha256=TtsjHXKWvwKrxHYZryB_NPANoFpMRlAxWJp1hA6Ny2I,4360
41
+ preditor/gui/level_buttons.py,sha256=h0pMMzp-ElwcN_qfR4EBQtXn1C666KVcnR9dMoixD3E,12597
35
42
  preditor/gui/logger_window_handler.py,sha256=43-DxzuNJq6UV6Ofc4TKRt179Sf5AxDkVDGrtq_Knok,1571
36
43
  preditor/gui/logger_window_plugin.py,sha256=x6mTuS6gmeMZtV0UIXHXIif1_B5oKVbJhuIBaW0BFVs,1210
37
- preditor/gui/loggerwindow.py,sha256=kiADRLw8yzr5qyFpHfFbC2uEFu2Zz5YHnB8Yf7p-gj0,53886
44
+ preditor/gui/loggerwindow.py,sha256=gGntieiZ2GdNY99CXNrldrv5abYzfSWYk-HdIVb3sYM,54378
38
45
  preditor/gui/newtabwidget.py,sha256=5aCWn9xAl5h1oZACqVuEsOAbzKTS2RegrLI41gROC8A,1971
39
- preditor/gui/set_text_editor_path_dialog.py,sha256=wzWAUgzGrsWbhcxeHjGlctuFVPXtYyxwnigAeUeeb5o,2247
46
+ preditor/gui/set_text_editor_path_dialog.py,sha256=bn8IeQHXPSU4PLYXQmSxKB1V8iuJaI1PA5aDJNgxXks,2292
40
47
  preditor/gui/status_label.py,sha256=SlNRmPc28S4E2OFVmErv0DmZstk4011Q_7uLp43SF0A,3320
41
48
  preditor/gui/suggest_path_quotes_dialog.py,sha256=QUJf_9hs8wOO6bFOr8_Z2xnNhSA8TfKFMOzheUqUDnY,1822
42
- preditor/gui/window.py,sha256=VS6ENhbAM991HvbLWp9Ys9DIvRgI-RcuKkr8BbPiaEE,5840
43
- preditor/gui/workbox_mixin.py,sha256=kUVHtK-flyux3PZ9GkOYnjCJMLRcZESFJXipsgNgI0U,13851
44
- preditor/gui/workbox_text_edit.py,sha256=B_xObwwobKzpMuTmwkczTGW9cOem2oF8pZDezCqwPCo,4385
45
- preditor/gui/workboxwidget.py,sha256=BDmV3tu5HaZPTpc_h8UtiAag-w7pEKUBNSkqAIz_7IU,10056
49
+ preditor/gui/window.py,sha256=6Ztjqb0Xfh8DsI7hBF4Rg-4-gWPZKTV4GRJiz3V8O6Q,5904
50
+ preditor/gui/workbox_mixin.py,sha256=uvLqbcdPOAL23kCz3Bnm1zOZ5PjXEUR9WEr-yE5iaTA,14990
51
+ preditor/gui/workbox_text_edit.py,sha256=shOeQSo3OdDnxig0xLiGZOcwwiR6fUkKLPlx2PejH40,4475
52
+ preditor/gui/workboxwidget.py,sha256=Dp81l3sFFUhmm8NZj-RTNbp4Up9fjTXb8arH0WWtjs4,10316
46
53
  preditor/gui/fuzzy_search/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
- preditor/gui/fuzzy_search/fuzzy_search.py,sha256=6npanW6aLmG_ezdHmpsKN7p2zwck_Qq6YUy9duCNN8Q,3595
48
- preditor/gui/group_tab_widget/__init__.py,sha256=PQ7yqhbkR5X_zilBJliyepVgYb26G3P6MyzBU6Jkt10,12965
54
+ preditor/gui/fuzzy_search/fuzzy_search.py,sha256=zohr6oAE99FZFlLjqKZajBrdyJIYLW96rcCOy5Bn1i0,3714
55
+ preditor/gui/group_tab_widget/__init__.py,sha256=3C2wAdD8XrXYGetjOL9lIoNhcQf5AP-QfXgMAvqRJMg,13037
49
56
  preditor/gui/group_tab_widget/grouped_tab_menu.py,sha256=lopd3mjHJIE_5xLdlZL0ghuBzsYo36vO1OZE6L6tqbI,1288
50
- preditor/gui/group_tab_widget/grouped_tab_models.py,sha256=zlmbcv3JAC5BzjKpm4CM7Hobibm1T_3GjaPoWIQbXiQ,3970
51
- preditor/gui/group_tab_widget/grouped_tab_widget.py,sha256=Z08LE8-ABakpM5Lk8cnntfjtdsmoR_T2ycgSEor7iY0,2928
57
+ preditor/gui/group_tab_widget/grouped_tab_models.py,sha256=duwEdtbvsJ1nPKFakrnY8QuCoBx4M7mOpB0_0Nrm6_Y,4027
58
+ preditor/gui/group_tab_widget/grouped_tab_widget.py,sha256=Z8SXWN3-Ukl7cwambNwX4Gb2uKBDsVM-EG9Z6W7ICts,3025
52
59
  preditor/gui/group_tab_widget/one_tab_widget.py,sha256=PdZAXjmV9oTHakh8aFYRlLnfwcoT459vQWVKgpZZx4Y,1971
53
60
  preditor/gui/ui/editor_chooser.ui,sha256=cYSVHK0A4-zst6JyDkrBZK9qcAontbhV4Mmnw5ps72E,2736
54
61
  preditor/gui/ui/errordialog.ui,sha256=i7cVc28FPxA_b4Xa58W_xmRJ_1GFb5rgtUhR_gZcf4E,1831
@@ -108,14 +115,14 @@ preditor/resource/img/warning-big.png,sha256=z5QKX3DNLo_UDRKdjwtELbXL_JLf2zOwhkM
108
115
  preditor/resource/lang/python.json,sha256=CXiQh0jcgd-OCrM-s9IF7s4o-g5WRA4vDaAyTRAxAQo,316
109
116
  preditor/resource/stylesheet/Bright.css,sha256=SfnPRBqfqEL4IF8RGt9PpLX_cSiGpfG9Q2hE1F9uTsk,2480
110
117
  preditor/resource/stylesheet/Dark.css,sha256=Sige7beBhRyfav9_mXvn-LhksxbX0_WEgpZSKhmPavc,5384
111
- preditor/scintilla/__init__.py,sha256=AoUc-fcp2D3F10FDFsp_ZzUr4zioDH0mvdubSF7sRG0,523
112
- preditor/scintilla/documenteditor.py,sha256=g9spQ-y5JBxFvwx7OHXVXQhPql4juzQFLfZNTvIwQeA,77895
113
- preditor/scintilla/finddialog.py,sha256=vcYPj74LbCy4KXdh0eJyOb8i31pJKgOZitKpgW4zhBM,2346
118
+ preditor/scintilla/__init__.py,sha256=IDndbcS8KW1TMcQTA1Vd-LzcdsNtOUfyldnjkKae0yw,956
119
+ preditor/scintilla/documenteditor.py,sha256=j9ZAAyYZwPZbI0hW5ou76aIpaFzvzukAT9l8KLY9s1o,79927
120
+ preditor/scintilla/finddialog.py,sha256=WxNVvkCfXrw_8E3-7tS1DIS9H1-ioLASDgIbniDxz3g,2376
114
121
  preditor/scintilla/delayables/__init__.py,sha256=lj9tMc3IL2QeaN858Ixt_n7clJngbKqG2sk66vIcFcQ,275
115
- preditor/scintilla/delayables/smart_highlight.py,sha256=JRwGp-pVwx75zJ5NoJ8UuBg4-jK4eQfgD4eM4ZfDbGI,3502
116
- preditor/scintilla/delayables/spell_check.py,sha256=56XQp5rB_W6PaHkV-p6kYrlBcD0WIdenn287i95lnwE,6901
122
+ preditor/scintilla/delayables/smart_highlight.py,sha256=5emI4StsQCIYizoFsib1rdw0gnUarV9TQ6CwxmzXXpU,3623
123
+ preditor/scintilla/delayables/spell_check.py,sha256=eHia6y-nOlQ-bhcfOm_EbgdREItVFNvIjkX8UIbv6ks,6936
117
124
  preditor/scintilla/lang/__init__.py,sha256=db0L84UKwXoiv_5PR3wFcywzbBo5a7SuZIz04S17nIM,1705
118
- preditor/scintilla/lang/language.py,sha256=GC8ASEcvRuo6pwTwe8usN5p_gA1UJ9RUsgmN9bOjh8I,6919
125
+ preditor/scintilla/lang/language.py,sha256=okngeGkVANP4e-GJT3NnCowlVxhs13wQZPNy87wp60I,6916
119
126
  preditor/scintilla/lang/config/bash.ini,sha256=dtvJOl5HKQo4JMpqoZ3ZcujAyk0qYa61hWYVpp6uzZw,152
120
127
  preditor/scintilla/lang/config/batch.ini,sha256=n0gQR47Zs5L9Hb1lkdJ7s2_4bqR7LwXcuCc2uOX4wpA,154
121
128
  preditor/scintilla/lang/config/cpp.ini,sha256=un8AiviOrYDrrPJYDSlBjjctWVr4OkSFjLZ5A43DYKU,263
@@ -136,23 +143,25 @@ preditor/scintilla/lang/config/sql.ini,sha256=TrRCliEmJvAlBXyKniJQdtKjfdPnBV-ywq
136
143
  preditor/scintilla/lang/config/xml.ini,sha256=xEhjIazrQhlEb19fff-mgkftK8cJW9DGcFnZwzTfbjA,469
137
144
  preditor/scintilla/lang/config/yaml.ini,sha256=rdFvgxQ7_L3kxqd5TwCAG4YFA75hBi8buVLGDZLaKwg,222
138
145
  preditor/scintilla/lexers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
- preditor/scintilla/lexers/cpplexer.py,sha256=5tVNlwVwAFZNmx8ri4WvJgkAyVvTCInNqZgfKXUKyfE,702
140
- preditor/scintilla/lexers/javascriptlexer.py,sha256=eyeT3FD_8q3hiVfyQ-uv56M0uWe76Ws-qDS32CGO6ug,853
141
- preditor/scintilla/lexers/maxscriptlexer.py,sha256=bS0-A7X09MbTJ-oAXZRDS3MdAa6kG94aEBIZIj6rjSs,8456
142
- preditor/scintilla/lexers/mellexer.py,sha256=Jp8i7UOBqQR0VQ88jZFtgwGM0KX0NxTbr3vYLeBWfkk,26506
143
- preditor/scintilla/lexers/mulexer.py,sha256=Y2FVp6ZJ9CgLIuIvItOzXMMRemuToID66dpBn1qqTwA,976
144
- preditor/scintilla/lexers/pythonlexer.py,sha256=WgL74RQGvGgsdAL-l2ioOMybqRw7M0GG-SxmzXsW4xw,1682
146
+ preditor/scintilla/lexers/cpplexer.py,sha256=xbFEFdadSrSnJJuq5hb0lwVrx_lZsUYovfCkvcyaa7M,692
147
+ preditor/scintilla/lexers/javascriptlexer.py,sha256=QSh2kGSmhEwQOLd5WjqespY5iMbE-zarZUUxRDU7myI,884
148
+ preditor/scintilla/lexers/maxscriptlexer.py,sha256=0z7I_jhDmyVHFSxXB29rO85nb37Rl2Hg77VPgknbvkw,8485
149
+ preditor/scintilla/lexers/mellexer.py,sha256=egQfRZJ49aJLUObCw-Ya7zdR8APpj4_IpOlwHxA9GJk,26496
150
+ preditor/scintilla/lexers/mulexer.py,sha256=tlyiKYBDRpmxcrH9FGi-Ogz2alHPhyqNaqVrWBvAx6I,966
151
+ preditor/scintilla/lexers/pythonlexer.py,sha256=dh_wSBhhYIIV1hUF_0cWbZCdMBMsOB6EY6x8valWo1s,1737
145
152
  preditor/scintilla/ui/finddialog.ui,sha256=CEXouVKqVCDOfMBciK-89OmsGe2Kr6XdMbSPiffp0PA,4048
146
153
  preditor/stream/__init__.py,sha256=SxILA3U3W8aNfVBd_oJ4-WXkA214cl1zGLSCelFx5QU,2682
147
154
  preditor/stream/director.py,sha256=Gklbl6jwTmB0BtyR6MZxRytdlufaz5MoiW9Le9WFTmo,2733
148
155
  preditor/stream/manager.py,sha256=NP4lf6hd5L_Ui-9Ws66gVEk6ZL8YqF7BxOzUsdrh3v0,2811
149
156
  preditor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
150
- preditor/utils/cute.py,sha256=LfF8gXMAkkQAdo4mm6J9aVkDLwWZbE6prQ0moDbtCys,1045
157
+ preditor/utils/cute.py,sha256=tLTChQ1-zMzHHaKpG85u4FbtJl_2R1E8-uckpOQbEEM,1057
151
158
  preditor/utils/stylesheets.py,sha256=EVWZNq3WnaRiyUPoYMKQo_dLEwbRyKu26b03I1JDA-s,1622
152
159
  preditor/utils/text_search.py,sha256=21kuSDTpLIPUcriB81WP1kWfzuDBuP13ZtHUtypP5jE,14218
153
- preditor-1.1.0.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
154
- preditor-1.1.0.dist-info/METADATA,sha256=maaheBBs8muvTMHa_8vUvYtGwS9uSmNvPET40yphdOU,9948
155
- preditor-1.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
156
- preditor-1.1.0.dist-info/entry_points.txt,sha256=mpe0HFD_oIEBNPTJNyUEbmMV6Ivrp4EuYyZ34C5d_PU,519
157
- preditor-1.1.0.dist-info/top_level.txt,sha256=iX1_mrUOky_BQr2oG0l_MbEUYF6idyjiWSzu9z3irIw,9
158
- preditor-1.1.0.dist-info/RECORD,,
160
+ preditor-1.2.0.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
161
+ tests/find_files/test_find_files.py,sha256=ETVe1tC666uTc_5pPhjzPCaMrMkYUB8iKGXDfW9usgI,2722
162
+ tests/ide/test_delayable_engine.py,sha256=Nv6SQXpwIdfgRbEOsEcR-7jhjZ6E0THPdwDoPvAM6y4,5948
163
+ preditor-1.2.0.dist-info/METADATA,sha256=mrSA7IThDujGF3AhzzJ0OluiwMayoDbvO9qRgfjHll0,12744
164
+ preditor-1.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
165
+ preditor-1.2.0.dist-info/entry_points.txt,sha256=mpe0HFD_oIEBNPTJNyUEbmMV6Ivrp4EuYyZ34C5d_PU,519
166
+ preditor-1.2.0.dist-info/top_level.txt,sha256=dZSBDecBQovRyqbFdvwk1AvMon636dJ14vr9ov1LSPs,20
167
+ preditor-1.2.0.dist-info/RECORD,,
@@ -0,0 +1,3 @@
1
+ dist
2
+ preditor
3
+ tests
@@ -0,0 +1,74 @@
1
+ import os
2
+
3
+ import pytest
4
+
5
+ from preditor.utils.text_search import RegexTextSearch, SimpleTextSearch
6
+
7
+
8
+ def text_for_test(filename):
9
+ dirname = os.path.dirname(__file__)
10
+ filename = os.path.join(dirname, filename)
11
+ with open(filename) as fle:
12
+ return fle.read()
13
+
14
+
15
+ @pytest.mark.parametrize(
16
+ "check_type,search_text,is_cs,context,is_re",
17
+ (
18
+ # Simple text search testing context and case
19
+ ("simple", "search term", False, 0, False),
20
+ ("simple", "search term", False, 1, False),
21
+ ("simple", "search term", False, 2, False),
22
+ ("simple", "search term", False, 3, False),
23
+ ("simple", "search term", True, 2, False),
24
+ # Regex search testing context and case
25
+ ("re_simple", "search term", False, 0, True),
26
+ ("re_simple", "search term", False, 2, True),
27
+ ("re_simple", "search term", False, 3, True),
28
+ ("re_simple", "search term", True, 2, True),
29
+ # Complex regex with a greedy search term
30
+ ("re_greedy", "search.+term", False, 0, True),
31
+ ("re_greedy", "search.+term", False, 2, True),
32
+ ("re_greedy", "search.+term", True, 2, True),
33
+ ("re_greedy_upper", "Search.+term", True, 2, True),
34
+ ),
35
+ )
36
+ def test_find_files(capsys, check_type, search_text, is_cs, context, is_re):
37
+ workbox_id = "1,2"
38
+ path = 'First Group/First Tab'
39
+ text = text_for_test("tab_text.txt")
40
+
41
+ if is_re:
42
+ TextSearch = RegexTextSearch
43
+ else:
44
+ TextSearch = SimpleTextSearch
45
+
46
+ search = TextSearch(search_text, case_sensitive=is_cs, context=context)
47
+ # Add the title to the printed output so title is tested when checking
48
+ # `captured.out` later.
49
+ print(search.title())
50
+
51
+ # Generate the search text and print it to `captured.out` so we can check
52
+ search.search_text(text, path, workbox_id)
53
+
54
+ captured = capsys.readouterr()
55
+ check_filename = "{}_{}_{}_{}.md".format(check_type, is_cs, context, is_re)
56
+ check = text_for_test(check_filename)
57
+
58
+ # To update tests, print text and save over top of the md. Then verify
59
+ # that it is actually rendered properly. You will need to add one trailing
60
+ # space after dot lines, two spaces after blank lines, and ensue the end of
61
+ # file newline is present. The default print callbacks use markdown links,
62
+ # but don't really render valid markdown. If you want to render to html,
63
+ # use regular markdown not github flavored.
64
+ # print(check_filename)
65
+ # print(captured.out)
66
+
67
+ # print('*' * 50)
68
+ # for line in check.rstrip().splitlines(keepends=True):
69
+ # print([line])
70
+ # print('*' * 50)
71
+ # for line in captured.out.splitlines(keepends=True):
72
+ # print([line])
73
+
74
+ assert captured.out == check