PrEditor 2.1.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.
- preditor/__init__.py +315 -0
- preditor/__main__.py +13 -0
- preditor/about_module.py +165 -0
- preditor/cli.py +192 -0
- preditor/config.py +318 -0
- preditor/constants.py +13 -0
- preditor/contexts.py +210 -0
- preditor/cores/__init__.py +0 -0
- preditor/cores/core.py +20 -0
- preditor/dccs/.hab.json +10 -0
- preditor/dccs/maya/PrEditor_maya.mod +1 -0
- preditor/dccs/maya/README.md +22 -0
- preditor/dccs/maya/plug-ins/PrEditor_maya.py +141 -0
- preditor/dccs/studiomax/PackageContents.xml +32 -0
- preditor/dccs/studiomax/PrEditor-PrEditor_Show.mcr +8 -0
- preditor/dccs/studiomax/README.md +17 -0
- preditor/dccs/studiomax/preditor.ms +16 -0
- preditor/dccs/studiomax/preditor_menu.mnx +7 -0
- preditor/debug.py +149 -0
- preditor/delayable_engine/__init__.py +302 -0
- preditor/delayable_engine/delayables.py +85 -0
- preditor/enum.py +728 -0
- preditor/excepthooks.py +165 -0
- preditor/gui/__init__.py +56 -0
- preditor/gui/app.py +163 -0
- preditor/gui/codehighlighter.py +289 -0
- preditor/gui/completer.py +237 -0
- preditor/gui/console.py +605 -0
- preditor/gui/console_base.py +911 -0
- preditor/gui/dialog.py +181 -0
- preditor/gui/drag_tab_bar.py +625 -0
- preditor/gui/editor_chooser.py +57 -0
- preditor/gui/errordialog.py +69 -0
- preditor/gui/find_files.py +137 -0
- preditor/gui/fuzzy_search/__init__.py +0 -0
- preditor/gui/fuzzy_search/fuzzy_search.py +97 -0
- preditor/gui/group_tab_widget/__init__.py +0 -0
- preditor/gui/group_tab_widget/group_tab_widget.py +528 -0
- preditor/gui/group_tab_widget/grouped_tab_menu.py +35 -0
- preditor/gui/group_tab_widget/grouped_tab_models.py +107 -0
- preditor/gui/group_tab_widget/grouped_tab_widget.py +223 -0
- preditor/gui/group_tab_widget/one_tab_widget.py +96 -0
- preditor/gui/level_buttons.py +358 -0
- preditor/gui/logger_window_handler.py +77 -0
- preditor/gui/logger_window_plugin.py +35 -0
- preditor/gui/loggerwindow.py +2405 -0
- preditor/gui/newtabwidget.py +69 -0
- preditor/gui/output_console.py +11 -0
- preditor/gui/qtdesigner/__init__.py +21 -0
- preditor/gui/qtdesigner/_log_plugin.py +29 -0
- preditor/gui/qtdesigner/console_base_plugin.py +48 -0
- preditor/gui/qtdesigner/console_predit_plugin.py +48 -0
- preditor/gui/set_text_editor_path_dialog.py +61 -0
- preditor/gui/status_label.py +99 -0
- preditor/gui/suggest_path_quotes_dialog.py +50 -0
- preditor/gui/ui/editor_chooser.ui +93 -0
- preditor/gui/ui/errordialog.ui +74 -0
- preditor/gui/ui/find_files.ui +140 -0
- preditor/gui/ui/loggerwindow.ui +1909 -0
- preditor/gui/ui/set_text_editor_path_dialog.ui +189 -0
- preditor/gui/ui/suggest_path_quotes_dialog.ui +225 -0
- preditor/gui/window.py +161 -0
- preditor/gui/workbox_mixin.py +1139 -0
- preditor/gui/workbox_text_edit.py +136 -0
- preditor/gui/workboxwidget.py +315 -0
- preditor/logging_config.py +55 -0
- preditor/osystem.py +401 -0
- preditor/plugins.py +118 -0
- preditor/prefs.py +381 -0
- preditor/resource/environment_variables.html +26 -0
- preditor/resource/error_mail.html +85 -0
- preditor/resource/error_mail_inline.html +41 -0
- preditor/resource/img/README.md +17 -0
- preditor/resource/img/arrow_forward.png +0 -0
- preditor/resource/img/check-bold.png +0 -0
- preditor/resource/img/chevron-down.png +0 -0
- preditor/resource/img/chevron-up.png +0 -0
- preditor/resource/img/close-thick.png +0 -0
- preditor/resource/img/comment-edit.png +0 -0
- preditor/resource/img/content-copy.png +0 -0
- preditor/resource/img/content-cut.png +0 -0
- preditor/resource/img/content-duplicate.png +0 -0
- preditor/resource/img/content-paste.png +0 -0
- preditor/resource/img/content-save.png +0 -0
- preditor/resource/img/debug_disabled.png +0 -0
- preditor/resource/img/eye-check.png +0 -0
- preditor/resource/img/file-plus.png +0 -0
- preditor/resource/img/file-remove.png +0 -0
- preditor/resource/img/format-align-left.png +0 -0
- preditor/resource/img/format-letter-case-lower.png +0 -0
- preditor/resource/img/format-letter-case-upper.png +0 -0
- preditor/resource/img/format-letter-case.svg +1 -0
- preditor/resource/img/information.png +0 -0
- preditor/resource/img/logging_critical.png +0 -0
- preditor/resource/img/logging_custom.png +0 -0
- preditor/resource/img/logging_debug.png +0 -0
- preditor/resource/img/logging_error.png +0 -0
- preditor/resource/img/logging_info.png +0 -0
- preditor/resource/img/logging_not_set.png +0 -0
- preditor/resource/img/logging_warning.png +0 -0
- preditor/resource/img/marker.png +0 -0
- preditor/resource/img/play.png +0 -0
- preditor/resource/img/playlist-play.png +0 -0
- preditor/resource/img/plus-minus-variant.png +0 -0
- preditor/resource/img/preditor.ico +0 -0
- preditor/resource/img/preditor.png +0 -0
- preditor/resource/img/preditor.psd +0 -0
- preditor/resource/img/preditor.svg +44 -0
- preditor/resource/img/regex.svg +1 -0
- preditor/resource/img/restart.svg +1 -0
- preditor/resource/img/skip-forward-outline.png +0 -0
- preditor/resource/img/skip-next-outline.png +0 -0
- preditor/resource/img/skip-next.png +0 -0
- preditor/resource/img/skip-previous.png +0 -0
- preditor/resource/img/subdirectory-arrow-right.png +0 -0
- preditor/resource/img/text-search-variant.png +0 -0
- preditor/resource/img/warning-big.png +0 -0
- preditor/resource/lang/python.json +30 -0
- preditor/resource/pref_updates/pref_updates.json +17 -0
- preditor/resource/settings.ini +25 -0
- preditor/resource/stylesheet/Bright.css +76 -0
- preditor/resource/stylesheet/Dark.css +210 -0
- preditor/scintilla/__init__.py +40 -0
- preditor/scintilla/delayables/__init__.py +11 -0
- preditor/scintilla/delayables/smart_highlight.py +97 -0
- preditor/scintilla/delayables/spell_check.py +174 -0
- preditor/scintilla/documenteditor.py +1924 -0
- preditor/scintilla/finddialog.py +68 -0
- preditor/scintilla/lang/__init__.py +80 -0
- preditor/scintilla/lang/config/bash.ini +15 -0
- preditor/scintilla/lang/config/batch.ini +14 -0
- preditor/scintilla/lang/config/cpp.ini +19 -0
- preditor/scintilla/lang/config/css.ini +19 -0
- preditor/scintilla/lang/config/eyeonscript.ini +17 -0
- preditor/scintilla/lang/config/html.ini +21 -0
- preditor/scintilla/lang/config/javascript.ini +24 -0
- preditor/scintilla/lang/config/lua.ini +16 -0
- preditor/scintilla/lang/config/maxscript.ini +20 -0
- preditor/scintilla/lang/config/mel.ini +18 -0
- preditor/scintilla/lang/config/mu.ini +22 -0
- preditor/scintilla/lang/config/nsi.ini +19 -0
- preditor/scintilla/lang/config/perl.ini +19 -0
- preditor/scintilla/lang/config/puppet.ini +19 -0
- preditor/scintilla/lang/config/python.ini +28 -0
- preditor/scintilla/lang/config/ruby.ini +19 -0
- preditor/scintilla/lang/config/sql.ini +7 -0
- preditor/scintilla/lang/config/xml.ini +21 -0
- preditor/scintilla/lang/config/yaml.ini +18 -0
- preditor/scintilla/lang/language.py +240 -0
- preditor/scintilla/lexers/__init__.py +0 -0
- preditor/scintilla/lexers/cpplexer.py +22 -0
- preditor/scintilla/lexers/javascriptlexer.py +27 -0
- preditor/scintilla/lexers/maxscriptlexer.py +235 -0
- preditor/scintilla/lexers/mellexer.py +369 -0
- preditor/scintilla/lexers/mulexer.py +33 -0
- preditor/scintilla/lexers/pythonlexer.py +42 -0
- preditor/scintilla/ui/finddialog.ui +160 -0
- preditor/settings.py +71 -0
- preditor/stream/__init__.py +72 -0
- preditor/stream/console_handler.py +169 -0
- preditor/stream/director.py +144 -0
- preditor/stream/manager.py +97 -0
- preditor/streamhandler_helper.py +46 -0
- preditor/utils/__init__.py +191 -0
- preditor/utils/call_stack.py +86 -0
- preditor/utils/cute.py +106 -0
- preditor/utils/stylesheets.py +54 -0
- preditor/utils/text_search.py +338 -0
- preditor/version.py +34 -0
- preditor/weakref.py +363 -0
- preditor-2.1.0.dist-info/METADATA +308 -0
- preditor-2.1.0.dist-info/RECORD +179 -0
- preditor-2.1.0.dist-info/WHEEL +5 -0
- preditor-2.1.0.dist-info/entry_points.txt +19 -0
- preditor-2.1.0.dist-info/licenses/LICENSE +165 -0
- preditor-2.1.0.dist-info/top_level.txt +3 -0
- tests/encodings/test_ecoding.py +33 -0
- tests/find_files/test_find_files.py +74 -0
- tests/ide/test_delayable_engine.py +171 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
from __future__ import absolute_import
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
import re
|
|
5
|
+
import sys
|
|
6
|
+
from enum import Enum
|
|
7
|
+
|
|
8
|
+
import Qt as Qt_py
|
|
9
|
+
from Qt.QtCore import QRegExp, QSortFilterProxyModel, QStringListModel, Qt
|
|
10
|
+
from Qt.QtGui import QCursor, QTextCursor
|
|
11
|
+
from Qt.QtWidgets import QCompleter, QToolTip
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CompleterMode(Enum):
|
|
15
|
+
"""
|
|
16
|
+
Enum which defines the available Completer Modes
|
|
17
|
+
|
|
18
|
+
STARTS_WITH - (Default) Matches completions which start with the typed input
|
|
19
|
+
regex = "^SampleInput.*"
|
|
20
|
+
OUTER_FUZZY - Matches completions which contain, but don't necessarily
|
|
21
|
+
start with, the typed input
|
|
22
|
+
regex = ".*SampleInput.*"
|
|
23
|
+
FULL_FUZZY - Matches completions which contain the characters of the typed input,
|
|
24
|
+
in order, regardless of other characters intermixed
|
|
25
|
+
regex = ".*S.*a.*m.*p.*l.*e.*I.*n.*p.*u.*t.*"
|
|
26
|
+
|
|
27
|
+
Matches respect case-sensitivity, which is set separately
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
STARTS_WITH = 0
|
|
31
|
+
OUTER_FUZZY = 1
|
|
32
|
+
FULL_FUZZY = 2
|
|
33
|
+
|
|
34
|
+
def displayName(self):
|
|
35
|
+
return self.name.replace('_', ' ').title()
|
|
36
|
+
|
|
37
|
+
def toolTip(self):
|
|
38
|
+
toolTipMap = {
|
|
39
|
+
'STARTS_WITH': "'all' matches 'allowtabs', does not match 'findallnames'",
|
|
40
|
+
'OUTER_FUZZY': "'all' matches 'getallobjs', does not match 'anylonglist'",
|
|
41
|
+
'FULL_FUZZY': "'all' matches 'getallobjs', also matches 'anylonglist'",
|
|
42
|
+
}
|
|
43
|
+
return toolTipMap.get(self.name, "")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class PythonCompleter(QCompleter):
|
|
47
|
+
def __init__(self, widget):
|
|
48
|
+
super(PythonCompleter, self).__init__(widget)
|
|
49
|
+
|
|
50
|
+
# use the python model for information
|
|
51
|
+
|
|
52
|
+
self._enabled = True
|
|
53
|
+
|
|
54
|
+
# update this completer
|
|
55
|
+
self.setWidget(widget)
|
|
56
|
+
|
|
57
|
+
self.setCaseSensitive()
|
|
58
|
+
self.setCompleterMode()
|
|
59
|
+
self.buildCompleter()
|
|
60
|
+
|
|
61
|
+
self.wasCompleting = False
|
|
62
|
+
self.wasCompletingCounter = 0
|
|
63
|
+
self.wasCompletingCounterMax = 1
|
|
64
|
+
|
|
65
|
+
def setCaseSensitive(self, caseSensitive=True):
|
|
66
|
+
"""Set case sensitivity for completions"""
|
|
67
|
+
self._sensitivity = (
|
|
68
|
+
Qt.CaseSensitivity.CaseSensitive
|
|
69
|
+
if caseSensitive
|
|
70
|
+
else Qt.CaseSensitivity.CaseInsensitive
|
|
71
|
+
)
|
|
72
|
+
self.buildCompleter()
|
|
73
|
+
|
|
74
|
+
def caseSensitive(self):
|
|
75
|
+
"""Return current case sensitivity state for completions"""
|
|
76
|
+
caseSensitive = self._sensitivity == Qt.CaseSensitivity.CaseSensitive
|
|
77
|
+
return caseSensitive
|
|
78
|
+
|
|
79
|
+
def setCompleterMode(self, completerMode=CompleterMode.STARTS_WITH):
|
|
80
|
+
"""Set completer mode"""
|
|
81
|
+
self._completerMode = completerMode
|
|
82
|
+
|
|
83
|
+
def completerMode(self):
|
|
84
|
+
"""Return current completer mode"""
|
|
85
|
+
return self._completerMode
|
|
86
|
+
|
|
87
|
+
def buildCompleter(self):
|
|
88
|
+
"""
|
|
89
|
+
Build the completer to allow for wildcards and set
|
|
90
|
+
case sensitivity to use
|
|
91
|
+
"""
|
|
92
|
+
model = QStringListModel()
|
|
93
|
+
self.filterModel = QSortFilterProxyModel(self.parent())
|
|
94
|
+
self.filterModel.setSourceModel(model)
|
|
95
|
+
self.filterModel.setFilterCaseSensitivity(self._sensitivity)
|
|
96
|
+
self.setModel(self.filterModel)
|
|
97
|
+
self.setCompletionMode(QCompleter.CompletionMode.UnfilteredPopupCompletion)
|
|
98
|
+
|
|
99
|
+
def currentObject(self, scope=None, docMode=False):
|
|
100
|
+
if self._enabled:
|
|
101
|
+
word = self.textUnderCursor()
|
|
102
|
+
|
|
103
|
+
# determine if we are in docMode or not
|
|
104
|
+
if word.endswith('(') and not docMode:
|
|
105
|
+
return (None, '')
|
|
106
|
+
|
|
107
|
+
word = word.rstrip('(')
|
|
108
|
+
split = word.split('.')
|
|
109
|
+
|
|
110
|
+
# make sure there is more than 1 item for this symbol
|
|
111
|
+
if len(split) > 1 or docMode:
|
|
112
|
+
if not docMode:
|
|
113
|
+
symbol = '.'.join(split[:-1])
|
|
114
|
+
prefix = split[-1]
|
|
115
|
+
else:
|
|
116
|
+
symbol = word
|
|
117
|
+
prefix = ''
|
|
118
|
+
|
|
119
|
+
# try to evaluate the object to pull out the keys
|
|
120
|
+
object = None
|
|
121
|
+
try:
|
|
122
|
+
object = eval(symbol, scope)
|
|
123
|
+
except Exception:
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
if object is None:
|
|
127
|
+
if symbol in sys.modules:
|
|
128
|
+
object = sys.modules[symbol]
|
|
129
|
+
|
|
130
|
+
return (object, prefix)
|
|
131
|
+
return (None, '')
|
|
132
|
+
|
|
133
|
+
def enabled(self):
|
|
134
|
+
return self._enabled
|
|
135
|
+
|
|
136
|
+
def hideDocumentation(self):
|
|
137
|
+
QToolTip.hideText()
|
|
138
|
+
|
|
139
|
+
def refreshList(self, scope=None):
|
|
140
|
+
"""refreshes the string list based on the cursor word"""
|
|
141
|
+
object, prefix = self.currentObject(scope)
|
|
142
|
+
|
|
143
|
+
# Only show hidden method/variable names if the hidden character '_' is typed
|
|
144
|
+
# in.
|
|
145
|
+
try:
|
|
146
|
+
if prefix.startswith('_'):
|
|
147
|
+
keys = [key for key in dir(object) if key.startswith('_')]
|
|
148
|
+
else:
|
|
149
|
+
keys = [key for key in dir(object) if not key.startswith('_')]
|
|
150
|
+
except AttributeError:
|
|
151
|
+
keys = []
|
|
152
|
+
keys.sort()
|
|
153
|
+
self.model().sourceModel().setStringList(keys)
|
|
154
|
+
|
|
155
|
+
regExStr = ""
|
|
156
|
+
if self._completerMode == CompleterMode.STARTS_WITH:
|
|
157
|
+
regExStr = "^{}.*".format(prefix)
|
|
158
|
+
if self._completerMode == CompleterMode.OUTER_FUZZY:
|
|
159
|
+
regExStr = ".*{}.*".format(prefix)
|
|
160
|
+
if self._completerMode == CompleterMode.FULL_FUZZY:
|
|
161
|
+
regExStr = ".*".join(prefix)
|
|
162
|
+
|
|
163
|
+
if Qt_py.IsPyQt6 or Qt_py.IsPySide6:
|
|
164
|
+
regexp = QRegExp(regExStr)
|
|
165
|
+
if self._sensitivity:
|
|
166
|
+
regexp.setPatternOptions(QRegExp.PatternOption.CaseInsensitiveOption)
|
|
167
|
+
self.filterModel.setFilterRegularExpression(regexp)
|
|
168
|
+
else:
|
|
169
|
+
regexp = QRegExp(regExStr, self._sensitivity)
|
|
170
|
+
self.filterModel.setFilterRegExp(regexp)
|
|
171
|
+
|
|
172
|
+
def clear(self):
|
|
173
|
+
self.popup().hide()
|
|
174
|
+
self.hideDocumentation()
|
|
175
|
+
|
|
176
|
+
self.wasCompletingCounter = 0
|
|
177
|
+
self.wasCompleting = False
|
|
178
|
+
|
|
179
|
+
def showDocumentation(self, pos=None, scope=None):
|
|
180
|
+
# hide the existing popup widget
|
|
181
|
+
self.popup().hide()
|
|
182
|
+
|
|
183
|
+
# create the default position
|
|
184
|
+
if pos is None:
|
|
185
|
+
pos = QCursor.pos()
|
|
186
|
+
|
|
187
|
+
# collect the object
|
|
188
|
+
object, prefix = self.currentObject(scope, docMode=True)
|
|
189
|
+
|
|
190
|
+
# not all objects allow `if object`, so catch any errors
|
|
191
|
+
# Specifically, numpy arrays fail with ValueError here
|
|
192
|
+
try:
|
|
193
|
+
if object:
|
|
194
|
+
docs = inspect.getdoc(object)
|
|
195
|
+
if docs:
|
|
196
|
+
QToolTip.showText(pos, docs)
|
|
197
|
+
except Exception:
|
|
198
|
+
pass
|
|
199
|
+
|
|
200
|
+
def setEnabled(self, state):
|
|
201
|
+
self._enabled = state
|
|
202
|
+
|
|
203
|
+
def textUnderCursor(self, useParens=False):
|
|
204
|
+
"""pulls out the text underneath the cursor of this items widget"""
|
|
205
|
+
|
|
206
|
+
cursor = self.widget().textCursor()
|
|
207
|
+
cursor.select(QTextCursor.SelectionType.WordUnderCursor)
|
|
208
|
+
|
|
209
|
+
# grab the selected word
|
|
210
|
+
word = cursor.selectedText()
|
|
211
|
+
block = cursor.block().text()
|
|
212
|
+
|
|
213
|
+
# lookup previous words using '.'
|
|
214
|
+
pos = cursor.position() - cursor.block().position() - len(word) - 1
|
|
215
|
+
|
|
216
|
+
while -1 < pos:
|
|
217
|
+
char = block[pos]
|
|
218
|
+
if not re.match(r"^[a-zA-Z0-9_\.\(\)'\"]$", char):
|
|
219
|
+
break
|
|
220
|
+
word = char + word
|
|
221
|
+
pos -= 1
|
|
222
|
+
|
|
223
|
+
# If the word starts with a opening parentheses, remove it if there is not a
|
|
224
|
+
# matching closing one.
|
|
225
|
+
if word and word[0] == '(':
|
|
226
|
+
count = 0
|
|
227
|
+
# use a simple instance count to check if the opening parentheses is closed
|
|
228
|
+
for char in word:
|
|
229
|
+
if char == '(':
|
|
230
|
+
count += 1
|
|
231
|
+
elif char == ')':
|
|
232
|
+
count -= 1
|
|
233
|
+
if count:
|
|
234
|
+
# the opening parentheses is not closed, remove it
|
|
235
|
+
word = word[1:]
|
|
236
|
+
|
|
237
|
+
return str(word)
|