pyqt-code-editor 0.0.1__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.
- pyqt_code_editor/__init__.py +5 -0
- pyqt_code_editor/_settings.py +232 -0
- pyqt_code_editor/app.py +438 -0
- pyqt_code_editor/code_editors/__init__.py +1 -0
- pyqt_code_editor/code_editors/code_editors.py +33 -0
- pyqt_code_editor/code_editors/languages/__init__.py +0 -0
- pyqt_code_editor/code_editors/languages/generic.py +11 -0
- pyqt_code_editor/code_editors/languages/markdown.py +11 -0
- pyqt_code_editor/code_editors/languages/python.py +13 -0
- pyqt_code_editor/code_editors/languages/text.py +9 -0
- pyqt_code_editor/components/__init__.py +0 -0
- pyqt_code_editor/components/editor_panel.py +399 -0
- pyqt_code_editor/components/find_in_files.py +199 -0
- pyqt_code_editor/components/jupyter_console.py +487 -0
- pyqt_code_editor/components/project_explorer.py +515 -0
- pyqt_code_editor/components/settings_panel.py +162 -0
- pyqt_code_editor/components/sigmund.py +75 -0
- pyqt_code_editor/components/workspace_explorer.py +162 -0
- pyqt_code_editor/mixins/__init__.py +15 -0
- pyqt_code_editor/mixins/auto_pair.py +201 -0
- pyqt_code_editor/mixins/base.py +142 -0
- pyqt_code_editor/mixins/check.py +94 -0
- pyqt_code_editor/mixins/comment.py +91 -0
- pyqt_code_editor/mixins/complete.py +482 -0
- pyqt_code_editor/mixins/execute.py +182 -0
- pyqt_code_editor/mixins/file_link.py +166 -0
- pyqt_code_editor/mixins/line_number.py +206 -0
- pyqt_code_editor/mixins/python_auto_indent.py +239 -0
- pyqt_code_editor/mixins/search_replace.py +396 -0
- pyqt_code_editor/mixins/shortcuts.py +228 -0
- pyqt_code_editor/mixins/smart_backspace_delete.py +120 -0
- pyqt_code_editor/mixins/symbols.py +45 -0
- pyqt_code_editor/mixins/theme.py +99 -0
- pyqt_code_editor/mixins/widgets/__init__.py +0 -0
- pyqt_code_editor/mixins/zoom.py +51 -0
- pyqt_code_editor/python_utils.py +936 -0
- pyqt_code_editor/signal_router.py +116 -0
- pyqt_code_editor/syntax_highlighters/__init__.py +0 -0
- pyqt_code_editor/syntax_highlighters/languages/__init__.py +0 -0
- pyqt_code_editor/syntax_highlighters/languages/generic.py +86 -0
- pyqt_code_editor/syntax_highlighters/languages/python.py +62 -0
- pyqt_code_editor/syntax_highlighters/syntax_highlighter.py +26 -0
- pyqt_code_editor/themes.py +36 -0
- pyqt_code_editor/utils.py +96 -0
- pyqt_code_editor/watchdog.py +141 -0
- pyqt_code_editor/widgets/__init__.py +6 -0
- pyqt_code_editor/widgets/calltip_widget.py +44 -0
- pyqt_code_editor/widgets/completion_popup.py +89 -0
- pyqt_code_editor/widgets/dock.py +15 -0
- pyqt_code_editor/widgets/quick_open_dialog.py +196 -0
- pyqt_code_editor/widgets/quick_open_file_dialog.py +32 -0
- pyqt_code_editor/widgets/quick_symbol_dialog.py +13 -0
- pyqt_code_editor/widgets/search_replace_frame.py +128 -0
- pyqt_code_editor/widgets/tab_splitter.py +22 -0
- pyqt_code_editor/widgets/tabbed_editor.py +351 -0
- pyqt_code_editor/worker/__init__.py +0 -0
- pyqt_code_editor/worker/languages/__init__.py +0 -0
- pyqt_code_editor/worker/languages/generic.py +15 -0
- pyqt_code_editor/worker/languages/python.py +17 -0
- pyqt_code_editor/worker/manager.py +113 -0
- pyqt_code_editor/worker/process.py +128 -0
- pyqt_code_editor/worker/providers/__init__.py +1 -0
- pyqt_code_editor/worker/providers/codestral.py +56 -0
- pyqt_code_editor/worker/providers/jedi.py +115 -0
- pyqt_code_editor/worker/providers/ruff.py +45 -0
- pyqt_code_editor/worker/providers/sigmund.py +29 -0
- pyqt_code_editor/worker/providers/symbol.py +78 -0
- pyqt_code_editor/worker/settings.py +1 -0
- pyqt_code_editor-0.0.1.dist-info/METADATA +69 -0
- pyqt_code_editor-0.0.1.dist-info/RECORD +73 -0
- pyqt_code_editor-0.0.1.dist-info/WHEEL +4 -0
- pyqt_code_editor-0.0.1.dist-info/entry_points.txt +4 -0
- pyqt_code_editor-0.0.1.dist-info/licenses/COPYING +674 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import logging
|
|
3
|
+
import jedi
|
|
4
|
+
from .. import settings
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _signature_to_html(signature) -> str:
|
|
10
|
+
"""Convert jedi.Script.get_signatures() output to nicely formatted HTML."""
|
|
11
|
+
param_strs = []
|
|
12
|
+
for param in signature.params:
|
|
13
|
+
param_strs.append(param.to_string())
|
|
14
|
+
# Build the signature line
|
|
15
|
+
sig_line = ",<br /> ".join(param_strs)
|
|
16
|
+
return_hint = ""
|
|
17
|
+
# If there's a known return annotation, append it
|
|
18
|
+
if hasattr(signature, "annotation_string") and signature.annotation_string:
|
|
19
|
+
return_hint = f"-> {signature.annotation_string}"
|
|
20
|
+
return f"({sig_line}){return_hint}"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _prepare_jedi_script(code: str, cursor_position: int, path: str | None):
|
|
24
|
+
"""
|
|
25
|
+
Prepare a Jedi Script object and calculate line_no/column_no from the
|
|
26
|
+
given code and cursor_position. Returns (script, line_no, column_no).
|
|
27
|
+
"""
|
|
28
|
+
# Convert the flat cursor_position into line & column (1-based indexing for Jedi)
|
|
29
|
+
line_no = code[:cursor_position].count('\n') + 1
|
|
30
|
+
last_newline_idx = code.rfind('\n', 0, cursor_position)
|
|
31
|
+
if last_newline_idx < 0:
|
|
32
|
+
column_no = cursor_position
|
|
33
|
+
else:
|
|
34
|
+
column_no = cursor_position - (last_newline_idx + 1)
|
|
35
|
+
|
|
36
|
+
logger.info("Creating Jedi Script for path=%r at line=%d, column=%d",
|
|
37
|
+
path, line_no, column_no)
|
|
38
|
+
|
|
39
|
+
script = jedi.Script(code, path=path)
|
|
40
|
+
return script, line_no, column_no
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def jedi_complete(code: str, cursor_position: int, path: str | None) -> list[str]:
|
|
44
|
+
"""
|
|
45
|
+
Perform Python-specific completion using Jedi. Returns a list of possible completions
|
|
46
|
+
for the text at the given cursor position, or None if no completion is found.
|
|
47
|
+
"""
|
|
48
|
+
if cursor_position == 0 or not code:
|
|
49
|
+
return []
|
|
50
|
+
# Basic sanity check for whether we want to attempt completion.
|
|
51
|
+
char_before = code[cursor_position - 1]
|
|
52
|
+
# Typically, you'd allow '.', '_' or alphanumeric as a signal for completion
|
|
53
|
+
if not re.match(r"[A-Za-z0-9_.]", char_before):
|
|
54
|
+
return []
|
|
55
|
+
# If the first preceding # comes before the first preceding newline, then we're inside a code comment
|
|
56
|
+
code_up_to_cursor = code[:cursor_position]
|
|
57
|
+
if code_up_to_cursor.rfind('#') > code_up_to_cursor.rfind('\n'):
|
|
58
|
+
return []
|
|
59
|
+
# Go Jedi!
|
|
60
|
+
script, line_no, column_no = _prepare_jedi_script(code, cursor_position, path)
|
|
61
|
+
completions = script.complete(line=line_no, column=column_no)
|
|
62
|
+
if not completions:
|
|
63
|
+
return []
|
|
64
|
+
result = [
|
|
65
|
+
{'completion' : c.complete, 'name': c.name}
|
|
66
|
+
for c in completions[:settings.max_completions] if c.complete
|
|
67
|
+
]
|
|
68
|
+
return result or []
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def jedi_signatures(code: str, cursor_position: int, path: str | None,
|
|
72
|
+
multiline: bool = False, max_width: int = 40,
|
|
73
|
+
max_lines: int = 10):
|
|
74
|
+
"""
|
|
75
|
+
Retrieve function signatures (calltips) from Jedi given the current cursor position.
|
|
76
|
+
Returns a list of strings describing each signature, or None if none.
|
|
77
|
+
|
|
78
|
+
Enhancements:
|
|
79
|
+
1) If the docstring contains a duplicate of sig_str at the beginning, it's removed.
|
|
80
|
+
2) The docstring is wrapped to max_width columns and truncated to max_lines lines.
|
|
81
|
+
"""
|
|
82
|
+
if cursor_position == 0 or not code:
|
|
83
|
+
logger.info("No code or cursor_position=0; cannot fetch calltip.")
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
logger.info("Starting Jedi calltip request (multiline=%r).", multiline)
|
|
87
|
+
script, line_no, column_no = _prepare_jedi_script(code, cursor_position, path)
|
|
88
|
+
|
|
89
|
+
signatures = script.get_signatures(line=line_no, column=column_no)
|
|
90
|
+
if not signatures:
|
|
91
|
+
logger.info("No signatures returned by Jedi.")
|
|
92
|
+
return None
|
|
93
|
+
|
|
94
|
+
results = []
|
|
95
|
+
for sig in signatures:
|
|
96
|
+
results.append(_signature_to_html(sig))
|
|
97
|
+
|
|
98
|
+
logger.info("Got %d signature(s) from Jedi.", len(results))
|
|
99
|
+
return results or None
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def jedi_symbols(code: str) -> list[dict]:
|
|
103
|
+
"""Retrieve symbols from Jedi given the current code."""
|
|
104
|
+
script = jedi.Script(code)
|
|
105
|
+
symbols = script.get_names(all_scopes=True)
|
|
106
|
+
results = []
|
|
107
|
+
for symbol in symbols:
|
|
108
|
+
if symbol.type not in ('function', 'class'):
|
|
109
|
+
continue
|
|
110
|
+
results.append({
|
|
111
|
+
'name': symbol.name,
|
|
112
|
+
'type': symbol.type,
|
|
113
|
+
'line': symbol.line
|
|
114
|
+
})
|
|
115
|
+
return results
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import tempfile
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import logging
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def ruff_check(code: str) -> list[dict]:
|
|
10
|
+
"""
|
|
11
|
+
Lints Python source code using Ruff.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
code (str): The Python source code to lint.
|
|
15
|
+
"""
|
|
16
|
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".py", mode="w") as tmp_file:
|
|
17
|
+
tmp_file.write(code)
|
|
18
|
+
tmp_file_path = tmp_file.name
|
|
19
|
+
print(tmp_file.name)
|
|
20
|
+
cmd = ["ruff", "check", tmp_file_path, "--output-format", "json"]
|
|
21
|
+
try:
|
|
22
|
+
process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
|
23
|
+
stderr=subprocess.PIPE, text=True)
|
|
24
|
+
stdout, stderr = process.communicate()
|
|
25
|
+
except Exception as e:
|
|
26
|
+
logger.error(f'failed to invoke ruff: {e}')
|
|
27
|
+
return {}
|
|
28
|
+
finally:
|
|
29
|
+
if os.path.exists(tmp_file_path):
|
|
30
|
+
os.unlink(tmp_file_path)
|
|
31
|
+
try:
|
|
32
|
+
result = json.loads(stdout)
|
|
33
|
+
except Exception as e:
|
|
34
|
+
logger.error(f'failed to parse ruff output: {e}')
|
|
35
|
+
return {}
|
|
36
|
+
formatted_result = {}
|
|
37
|
+
for message in result:
|
|
38
|
+
row = message['location']['row']
|
|
39
|
+
if row not in formatted_result:
|
|
40
|
+
formatted_result[row] = []
|
|
41
|
+
formatted_result[row].append({
|
|
42
|
+
'code': message['code'],
|
|
43
|
+
'message': message['message'],
|
|
44
|
+
})
|
|
45
|
+
return formatted_result
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import json
|
|
4
|
+
import requests
|
|
5
|
+
from .. import settings
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def sigmund_complete(code: str, cursor_pos: int, path: str | None,
|
|
9
|
+
multiline: False) -> list[str]:
|
|
10
|
+
if token is None:
|
|
11
|
+
return []
|
|
12
|
+
if len(code) < 10:
|
|
13
|
+
return []
|
|
14
|
+
ret_val = []
|
|
15
|
+
start = max(0, cursor_pos - settings.sigmund_max_context)
|
|
16
|
+
end = cursor_pos + settings.sigmund_max_context
|
|
17
|
+
prompt = code[start: cursor_pos]
|
|
18
|
+
suffix = code[cursor_pos: end]
|
|
19
|
+
data = {'prompt': prompt, 'token': token, 'suffix': suffix,
|
|
20
|
+
'multiline': multiline}
|
|
21
|
+
try:
|
|
22
|
+
response = requests.post(settings.sigmund_fim_endpoint, json=data,
|
|
23
|
+
timeout=settings.sigmund_timeout)
|
|
24
|
+
response.raise_for_status()
|
|
25
|
+
resp_json = response.json()
|
|
26
|
+
completion = resp_json.get('completion', '')
|
|
27
|
+
return [completion]
|
|
28
|
+
except Exception as e:
|
|
29
|
+
return []
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
def symbol_complete(code: str, cursor_pos: int, path: str | None) -> list[str]:
|
|
4
|
+
"""
|
|
5
|
+
A helper function for code completion that is based on all the symbols
|
|
6
|
+
that are detected in the code in a language-agnostic way. The code is split
|
|
7
|
+
into separate words so that punctuation and separators are ignored. Then
|
|
8
|
+
the best fitting completion is returned. If no completion is available
|
|
9
|
+
(e.g., because the character before the cursor is punctuation, comma, or
|
|
10
|
+
whitespace), return None.
|
|
11
|
+
|
|
12
|
+
Logic to handle contradictory test #4 and #5:
|
|
13
|
+
1) If the partial_word itself appears in the code, we prioritize a match
|
|
14
|
+
with the largest leftover length.
|
|
15
|
+
2) Otherwise, if there is a symbol that differs from partial_word by exactly
|
|
16
|
+
1 character, pick that first; otherwise pick the one with the largest
|
|
17
|
+
leftover length. Ties are broken lexicographically.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
if cursor_pos == 0:
|
|
21
|
+
return [] # No space to complete if at start of code
|
|
22
|
+
|
|
23
|
+
# Check the character immediately before the cursor
|
|
24
|
+
char_before = code[cursor_pos - 1]
|
|
25
|
+
# If the character is not alphanumeric or underscore, no completion
|
|
26
|
+
if not re.match(r"[A-Za-z0-9_]", char_before):
|
|
27
|
+
return []
|
|
28
|
+
|
|
29
|
+
# Find the partial word by reading backwards from cursor_pos
|
|
30
|
+
start_index = cursor_pos - 1
|
|
31
|
+
while start_index >= 0 and re.match(r"[A-Za-z0-9_]", code[start_index]):
|
|
32
|
+
start_index -= 1
|
|
33
|
+
partial_word = code[start_index + 1:cursor_pos]
|
|
34
|
+
if not partial_word:
|
|
35
|
+
return []
|
|
36
|
+
|
|
37
|
+
# Remove the user-typed partial_word from the code where it appears near the cursor
|
|
38
|
+
code_without_partial = code[:start_index + 1] + code[cursor_pos:]
|
|
39
|
+
|
|
40
|
+
# Gather all words (symbols) from the updated code
|
|
41
|
+
all_symbols = re.findall(r"[A-Za-z0-9_]+", code_without_partial)
|
|
42
|
+
unique_symbols = set(all_symbols) # deduplicate
|
|
43
|
+
|
|
44
|
+
# Filter only those symbols that:
|
|
45
|
+
# 1) start with partial_word
|
|
46
|
+
# 2) are strictly longer than partial_word
|
|
47
|
+
matches = [sym for sym in unique_symbols
|
|
48
|
+
if sym.startswith(partial_word) and len(sym) > len(partial_word)]
|
|
49
|
+
if not matches:
|
|
50
|
+
return []
|
|
51
|
+
|
|
52
|
+
# Build leftover_map { leftover_length -> list_of_symbols }
|
|
53
|
+
leftover_map = {}
|
|
54
|
+
for sym in matches:
|
|
55
|
+
leftover_len = len(sym) - len(partial_word)
|
|
56
|
+
leftover_map.setdefault(leftover_len, []).append(sym)
|
|
57
|
+
|
|
58
|
+
# Check if partial_word is itself a symbol (i.e. it appears elsewhere in the code)
|
|
59
|
+
partial_word_is_symbol = partial_word in unique_symbols
|
|
60
|
+
|
|
61
|
+
if partial_word_is_symbol:
|
|
62
|
+
# Pick from the group with the maximum leftover
|
|
63
|
+
max_leftover_len = max(leftover_map)
|
|
64
|
+
candidates = leftover_map[max_leftover_len]
|
|
65
|
+
else:
|
|
66
|
+
# If there's a leftover=1 group available, pick that
|
|
67
|
+
if 1 in leftover_map:
|
|
68
|
+
candidates = leftover_map[1]
|
|
69
|
+
else:
|
|
70
|
+
# Otherwise pick from the group with the maximum leftover
|
|
71
|
+
max_leftover_len = max(leftover_map)
|
|
72
|
+
candidates = leftover_map[max_leftover_len]
|
|
73
|
+
|
|
74
|
+
# Among candidates, pick the lexicographically first
|
|
75
|
+
best_match = min(candidates)
|
|
76
|
+
# The remainder is the substring that goes beyond the partial_word
|
|
77
|
+
remainder = best_match[len(partial_word):]
|
|
78
|
+
return [{'completion' : remainder, 'name': best_match}]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# This is an empty module that will be filled with settings
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyqt_code_editor
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Fully featured code-editor widgets for PyQt
|
|
5
|
+
Keywords: code editor,pyqt,ide
|
|
6
|
+
Author-email: Sebastiaan Mathôt <s.mathot@cogsci.nl>
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: COPYING
|
|
10
|
+
Requires-Dist: chardet
|
|
11
|
+
Requires-Dist: jedi
|
|
12
|
+
Requires-Dist: mistralai
|
|
13
|
+
Requires-Dist: pathspec
|
|
14
|
+
Requires-Dist: pygments
|
|
15
|
+
Requires-Dist: qtawesome
|
|
16
|
+
Requires-Dist: qtpy
|
|
17
|
+
Requires-Dist: ruff
|
|
18
|
+
Requires-Dist: opensesame-extension-sigmund
|
|
19
|
+
Requires-Dist: pyqt6
|
|
20
|
+
Requires-Dist: qtconsole
|
|
21
|
+
Project-URL: Source, https://github.com/open-cogsci/pyqt_code_editor
|
|
22
|
+
|
|
23
|
+
# PyQt Code Editor
|
|
24
|
+
|
|
25
|
+
__This code is under development and not ready for general use__
|
|
26
|
+
|
|
27
|
+
Fully featured code-editor widgets for PyQt
|
|
28
|
+
|
|
29
|
+
Copyright 2025 Sebastiaan Mathôt
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## About
|
|
33
|
+
|
|
34
|
+
This is a set of code-editor widgets for PyQt. They are inspired by PyQode, and contain much of the same functionality, but in a cleaner and more modern codebase. All functionality can be used as standalone PyQt widgets. A full Python IDE is also available. This IDE is called Sigmund Analyst, and is primarily intended for data analysis in combination with [SigmundAI](https://sigmundai.eu).
|
|
35
|
+
|
|
36
|
+
Features:
|
|
37
|
+
|
|
38
|
+
- Code-editor widgets with syntax highlighting, code completion, AI integration, and more
|
|
39
|
+
- Project explorer (folder view)
|
|
40
|
+
- Editor panel with splittable tabs
|
|
41
|
+
- Jupyter console
|
|
42
|
+
- Workspace explorer (linked to Jupyter console)
|
|
43
|
+
- Settings panel
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
First, install all dependencies using:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
pip install .
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Next, start one of the example scripts:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
python examples/example_ide.py
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
On some systems, a segmentation fault occurs with the version of PyQt from PyPi. In that case, install PyQt from some other source, such as Anaconda.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
`PyQt Code Editor` is licensed under the [GNU General Public License
|
|
68
|
+
v3](http://www.gnu.org/licenses/gpl-3.0.en.html).
|
|
69
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
pyqt_code_editor/__init__.py,sha256=xolRrp46-3ATeGfcKWvc5bW3HfZNUbgSS19uRyL4DSY,106
|
|
2
|
+
pyqt_code_editor/_settings.py,sha256=u_ZjcTGS7UKcDQ0LqyvaWMu8I5_B7irxZN9QQ-Y4Asc,10250
|
|
3
|
+
pyqt_code_editor/app.py,sha256=YlWG2bfA5ZOSHYSKljDEMH6k_0zQzlf3KsNjO1EpIhQ,18772
|
|
4
|
+
pyqt_code_editor/python_utils.py,sha256=9xyk7YICT3GLB-hh_A2PDGxDf7Hg-sm9YeClEkFxzoU,26335
|
|
5
|
+
pyqt_code_editor/signal_router.py,sha256=7oJqEd75-CMFCFrByz42Xt1lCRwGgIj1h_FJ3euH4q8,4628
|
|
6
|
+
pyqt_code_editor/themes.py,sha256=jzgMzgxksF-7goILzXJm06ztgdoXwjccjEur5TRQVbQ,989
|
|
7
|
+
pyqt_code_editor/utils.py,sha256=2FReKyGlGbcsWflhY7fcTpoSGLScSqWGd6LJMXfhyZI,3665
|
|
8
|
+
pyqt_code_editor/watchdog.py,sha256=1Cbdbx6KZbWF6bBbM3vpjynXmnxQycvzsMGzeyfdS88,4450
|
|
9
|
+
pyqt_code_editor/code_editors/__init__.py,sha256=jY99MI7_nV8vZ4UzEuU8dvxy_c87sKpK_rzHERgxfyU,40
|
|
10
|
+
pyqt_code_editor/code_editors/code_editors.py,sha256=te6wYu-FciYVNL7WuDNjcsZ2ET8i2MWo8mluACZRvdI,1205
|
|
11
|
+
pyqt_code_editor/code_editors/languages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
pyqt_code_editor/code_editors/languages/generic.py,sha256=yT03IRSw00e-mnqljmJdVCSPwkThNiJmhMywST8fgqc,393
|
|
13
|
+
pyqt_code_editor/code_editors/languages/markdown.py,sha256=h9pnLFY6zr5uCLrBDs45t14PF1tVl6R1x3Lru2s3uiI,393
|
|
14
|
+
pyqt_code_editor/code_editors/languages/python.py,sha256=J16Rkn5OPzX2H0S2HzRip-inQhdTQVAYxreVUXxBrSY,554
|
|
15
|
+
pyqt_code_editor/code_editors/languages/text.py,sha256=lfdDJ15NXZka9AxrjQqfwbqVajL0-dDFo6CbDkNW6qY,340
|
|
16
|
+
pyqt_code_editor/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
pyqt_code_editor/components/editor_panel.py,sha256=xFDRFogW1EhM_ObRtW-zPN-rPzdoNjKKroZRa3xzrIc,17829
|
|
18
|
+
pyqt_code_editor/components/find_in_files.py,sha256=yqTlYJcZRbVe6_UVsjcjNE3_Xayn3jGLo4xOLvlGEw0,7498
|
|
19
|
+
pyqt_code_editor/components/jupyter_console.py,sha256=qWG99oZc2otlkElAislhK8HnWbfdTe36vpSWYPeF24w,20250
|
|
20
|
+
pyqt_code_editor/components/project_explorer.py,sha256=3JmgxQfL3O_SHwwUJ7lUgdEaPyjYp2owfK_6a4zK4DU,21552
|
|
21
|
+
pyqt_code_editor/components/settings_panel.py,sha256=DC5HNYtXvUsr1ZDw3bWCOivW5vVjHp8Y5SMeHuxvYN8,6399
|
|
22
|
+
pyqt_code_editor/components/sigmund.py,sha256=cPxVpuPYhzqDVsjQQTSngR2R75su_bKXu_Nz_9IZHeI,2562
|
|
23
|
+
pyqt_code_editor/components/workspace_explorer.py,sha256=-dXkMVHbSmjj75XB0AYwdAy9j4v_4gvuyXWHxyJs1fg,6420
|
|
24
|
+
pyqt_code_editor/mixins/__init__.py,sha256=6ZXNiJCVv0I-41_ZbO8OaywONCAoPk6BhdIHfsBgt2k,511
|
|
25
|
+
pyqt_code_editor/mixins/auto_pair.py,sha256=eKC-fZCJ5WXzvS4mZV69gW73jrVa7VIS_cvoFeEnR7E,8283
|
|
26
|
+
pyqt_code_editor/mixins/base.py,sha256=BL3cyA1zRGj07nBfq6rCq03_RWU285AcFIyHm8xcnOk,5313
|
|
27
|
+
pyqt_code_editor/mixins/check.py,sha256=gf1cNS1P67b4z1Qe3zX39XZuk-YzVfaBcS37T1xqT3Y,3793
|
|
28
|
+
pyqt_code_editor/mixins/comment.py,sha256=8_J7YwWmd5c03cbDCnPxjH5RLvy0wvabIJBywRYD5zQ,3854
|
|
29
|
+
pyqt_code_editor/mixins/complete.py,sha256=xFM7wNE8Z4z06LqpIMmZebk0pjfhK6cjMsqklQA7tkc,20583
|
|
30
|
+
pyqt_code_editor/mixins/execute.py,sha256=U1ULJHxXGGDH-chMgR42b_5zEseea34GKmGFkD4GmjY,7339
|
|
31
|
+
pyqt_code_editor/mixins/file_link.py,sha256=TPFG811TbYmX5SLJOCZZVf4zJKmPiTJ8MgUdvLOBrkg,6620
|
|
32
|
+
pyqt_code_editor/mixins/line_number.py,sha256=APmQTkJi5H1z1HZkTGf084Hc9m5t8sljyzr-7fTJZU4,8128
|
|
33
|
+
pyqt_code_editor/mixins/python_auto_indent.py,sha256=QKdJ0F4g0blqL_DAPQR1sIJYM7qZCRHwK5LMCfl3B8c,9684
|
|
34
|
+
pyqt_code_editor/mixins/search_replace.py,sha256=KtdyGUHr3ozWrZWOWL88jG_2G9t9GEkful-O1D2PtS4,15033
|
|
35
|
+
pyqt_code_editor/mixins/shortcuts.py,sha256=7JchKANfZulUpR_iSOQKlPT0Ns0e0ykj259lEmZbX70,9370
|
|
36
|
+
pyqt_code_editor/mixins/smart_backspace_delete.py,sha256=xtwWu9BCrtU-eEmynbG6Jk0-bIE-l-jw3cdwYyWBuZ4,5814
|
|
37
|
+
pyqt_code_editor/mixins/symbols.py,sha256=r0_g5lSfXCumbBAguPuKW1_er5g1LkIXe8xKZ8jZuxo,1739
|
|
38
|
+
pyqt_code_editor/mixins/theme.py,sha256=C2PVWqqaAPv4YoAn0y2ObPclXofF1SWmsUG2eGw2z94,3783
|
|
39
|
+
pyqt_code_editor/mixins/zoom.py,sha256=Swr_cuGmgWogp0uJVDtnwAmlip8fAKZNDm3qm5hB4UY,1537
|
|
40
|
+
pyqt_code_editor/mixins/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
|
+
pyqt_code_editor/syntax_highlighters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
|
+
pyqt_code_editor/syntax_highlighters/syntax_highlighter.py,sha256=vCK1DQEhpCb5ORTqzzp5Xv6uUNaw5xJMvEr0XQH3hxU,951
|
|
43
|
+
pyqt_code_editor/syntax_highlighters/languages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
|
+
pyqt_code_editor/syntax_highlighters/languages/generic.py,sha256=CQZYL7aDLPXcrUhQEpFpJhhpGBJJHylI6bK5OOSo2gY,3257
|
|
45
|
+
pyqt_code_editor/syntax_highlighters/languages/python.py,sha256=BY7BzM_9iY7Ev4HkYObbtOxG4Tx9fri3fOzEvqelDfw,2603
|
|
46
|
+
pyqt_code_editor/widgets/__init__.py,sha256=XeN7FD2XG-2hhwvjGhEzVTVlaeCd_hVx4jT9ydc7d5I,254
|
|
47
|
+
pyqt_code_editor/widgets/calltip_widget.py,sha256=c6Eq4w_PJrcGEB1xCsb6ZMuSHY2a8vToik1z0MS6jeY,1698
|
|
48
|
+
pyqt_code_editor/widgets/completion_popup.py,sha256=d7oS7EJOU7lFbpxdbO8x6WWUA-Q80GIXQbNuGYqGoec,3462
|
|
49
|
+
pyqt_code_editor/widgets/dock.py,sha256=9Kdpd7anNOD5yLeYEDR328bBlFScH0BQY6oecqkxluI,326
|
|
50
|
+
pyqt_code_editor/widgets/quick_open_dialog.py,sha256=_OPNOGCI9mtflTocSpk08QtCmrTOzvDxMXLTWvKwjPA,7417
|
|
51
|
+
pyqt_code_editor/widgets/quick_open_file_dialog.py,sha256=4Baz_D9C3XaAJ6xJJR1gBV1ABlZAHPPMFKH5mTihKx8,1165
|
|
52
|
+
pyqt_code_editor/widgets/quick_symbol_dialog.py,sha256=JHgmkh3RnP2fYV3iFuXbY8cCHIWmjpNR2azyIeNq5D4,418
|
|
53
|
+
pyqt_code_editor/widgets/search_replace_frame.py,sha256=WVN4wsZ3TK9XahPDEdYK9wWc3Z8GnxcfZI1Sil7zHnM,4517
|
|
54
|
+
pyqt_code_editor/widgets/tab_splitter.py,sha256=sUN6xwotvQETKJqMHa1IMswY05-xA6wSd7auIVyqnRg,704
|
|
55
|
+
pyqt_code_editor/widgets/tabbed_editor.py,sha256=C5Oyv7j6YBqQhyjqocP0MwrerwwnSgZFsQT4Ows32_M,14021
|
|
56
|
+
pyqt_code_editor/worker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
57
|
+
pyqt_code_editor/worker/manager.py,sha256=BjLIFG3yX7EC0dxyhWdg1qoy1S_6ZjBQeXEWTRLewHI,4054
|
|
58
|
+
pyqt_code_editor/worker/process.py,sha256=Gida0xdT3NtNLyJ-DU_k7rLyKEH4SzUZHnCl_8XfqqU,5157
|
|
59
|
+
pyqt_code_editor/worker/settings.py,sha256=rbBZbLwJalviJp7jegm_cXqYOtc19-iOjPZp2CJs24k,60
|
|
60
|
+
pyqt_code_editor/worker/languages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
|
+
pyqt_code_editor/worker/languages/generic.py,sha256=b9v_Ul1s6zq5FlDIjx6_bpd8Pw1GA_Gc-HGzaC-85tg,437
|
|
62
|
+
pyqt_code_editor/worker/languages/python.py,sha256=4qfi2Xh1PMqFEOJedfE0PfDCI2DC9GvOqkGPK81PLcw,479
|
|
63
|
+
pyqt_code_editor/worker/providers/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
64
|
+
pyqt_code_editor/worker/providers/codestral.py,sha256=pCVrS1hOdzFV6dC-rJ210mDolsMis0-4-5UDQN8_Crk,1521
|
|
65
|
+
pyqt_code_editor/worker/providers/jedi.py,sha256=My2I2I_-a8_el8x88ej1Kw8HP0Rpdb38AgUJKpfDP5s,4301
|
|
66
|
+
pyqt_code_editor/worker/providers/ruff.py,sha256=syZRyM8-n683Lc7kTf1Gq1Ns4UfPZ6sXBvHmKHTwLsA,1383
|
|
67
|
+
pyqt_code_editor/worker/providers/sigmund.py,sha256=Ewsd4126lK2QIjDW9KqMrnYE6ht0vCl8UOZ3kSp0h6E,928
|
|
68
|
+
pyqt_code_editor/worker/providers/symbol.py,sha256=iMObfsgZl6rI-WeCu9PE5uZGY6OSuST-4jcT9e0l7co,3305
|
|
69
|
+
pyqt_code_editor-0.0.1.dist-info/entry_points.txt,sha256=9D7XocBHMrmdKZXgFDKMpYju89bQm9u0jDB5QWABXYs,116
|
|
70
|
+
pyqt_code_editor-0.0.1.dist-info/licenses/COPYING,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
|
71
|
+
pyqt_code_editor-0.0.1.dist-info/WHEEL,sha256=_2ozNFCLWc93bK4WKHCO-eDUENDlo-dgc9cU3qokYO4,82
|
|
72
|
+
pyqt_code_editor-0.0.1.dist-info/METADATA,sha256=aQSLCzhfy8RmkKY_6N0CNjyguLVC9Fdl95UfCTuS6Xs,1915
|
|
73
|
+
pyqt_code_editor-0.0.1.dist-info/RECORD,,
|