je-editor 0.0.202__py3-none-any.whl → 0.0.228__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.
- je_editor/__init__.py +2 -2
- je_editor/code_scan/__init__.py +0 -0
- je_editor/code_scan/ruff_thread.py +58 -0
- je_editor/code_scan/watchdog_implement.py +56 -0
- je_editor/code_scan/watchdog_thread.py +78 -0
- je_editor/git_client/__init__.py +0 -0
- je_editor/git_client/commit_graph.py +77 -0
- je_editor/git_client/git_action.py +175 -0
- je_editor/git_client/git_cli.py +66 -0
- je_editor/pyside_ui/browser/browser_download_window.py +40 -4
- je_editor/pyside_ui/browser/browser_serach_lineedit.py +24 -0
- je_editor/pyside_ui/browser/browser_view.py +55 -6
- je_editor/pyside_ui/browser/browser_widget.py +62 -19
- je_editor/pyside_ui/browser/main_browser_widget.py +85 -0
- je_editor/pyside_ui/code/auto_save/auto_save_manager.py +33 -1
- je_editor/pyside_ui/code/auto_save/auto_save_thread.py +18 -5
- je_editor/pyside_ui/code/code_format/pep8_format.py +52 -7
- je_editor/pyside_ui/code/code_process/code_exec.py +118 -64
- je_editor/pyside_ui/code/plaintext_code_edit/code_edit_plaintext.py +115 -53
- je_editor/pyside_ui/code/running_process_manager.py +18 -0
- je_editor/pyside_ui/code/shell_process/shell_exec.py +99 -60
- je_editor/pyside_ui/code/syntax/python_syntax.py +44 -9
- je_editor/pyside_ui/code/syntax/syntax_setting.py +39 -11
- je_editor/pyside_ui/code/textedit_code_result/code_record.py +33 -11
- je_editor/pyside_ui/code/variable_inspector/__init__.py +0 -0
- je_editor/pyside_ui/code/variable_inspector/inspector_gui.py +172 -0
- je_editor/pyside_ui/dialog/ai_dialog/__init__.py +0 -0
- je_editor/pyside_ui/dialog/ai_dialog/set_ai_dialog.py +71 -0
- je_editor/pyside_ui/dialog/file_dialog/create_file_dialog.py +38 -4
- je_editor/pyside_ui/dialog/file_dialog/open_file_dialog.py +32 -4
- je_editor/pyside_ui/dialog/file_dialog/save_file_dialog.py +25 -2
- je_editor/pyside_ui/dialog/search_ui/search_error_box.py +27 -2
- je_editor/pyside_ui/dialog/search_ui/search_text_box.py +28 -3
- je_editor/pyside_ui/git_ui/__init__.py +0 -0
- je_editor/pyside_ui/git_ui/code_diff_compare/__init__.py +0 -0
- je_editor/pyside_ui/git_ui/code_diff_compare/code_diff_viewer_widget.py +90 -0
- je_editor/pyside_ui/git_ui/code_diff_compare/line_number_code_viewer.py +141 -0
- je_editor/pyside_ui/git_ui/code_diff_compare/multi_file_diff_viewer.py +88 -0
- je_editor/pyside_ui/git_ui/code_diff_compare/side_by_side_diff_widget.py +284 -0
- je_editor/pyside_ui/git_ui/git_client/__init__.py +0 -0
- je_editor/pyside_ui/git_ui/git_client/commit_table.py +65 -0
- je_editor/pyside_ui/git_ui/git_client/git_branch_tree_widget.py +156 -0
- je_editor/pyside_ui/git_ui/git_client/git_client_gui.py +799 -0
- je_editor/pyside_ui/git_ui/git_client/graph_view.py +218 -0
- je_editor/pyside_ui/main_ui/ai_widget/__init__.py +0 -0
- je_editor/pyside_ui/main_ui/ai_widget/ai_config.py +34 -0
- je_editor/pyside_ui/main_ui/ai_widget/ask_thread.py +36 -0
- je_editor/pyside_ui/main_ui/ai_widget/chat_ui.py +147 -0
- je_editor/pyside_ui/main_ui/ai_widget/langchain_interface.py +84 -0
- je_editor/pyside_ui/main_ui/console_widget/__init__.py +0 -0
- je_editor/pyside_ui/main_ui/console_widget/console_gui.py +162 -0
- je_editor/pyside_ui/main_ui/console_widget/qprocess_adapter.py +84 -0
- je_editor/pyside_ui/main_ui/dock/destroy_dock.py +32 -1
- je_editor/pyside_ui/main_ui/editor/editor_widget.py +113 -23
- je_editor/pyside_ui/main_ui/editor/editor_widget_dock.py +33 -6
- je_editor/pyside_ui/main_ui/editor/process_input.py +42 -10
- je_editor/pyside_ui/main_ui/ipython_widget/rich_jupyter.py +45 -10
- je_editor/pyside_ui/main_ui/main_editor.py +189 -49
- je_editor/pyside_ui/main_ui/menu/check_style_menu/build_check_style_menu.py +50 -27
- je_editor/pyside_ui/main_ui/menu/dock_menu/build_dock_menu.py +141 -30
- je_editor/pyside_ui/main_ui/menu/file_menu/build_file_menu.py +67 -17
- je_editor/pyside_ui/main_ui/menu/help_menu/build_help_menu.py +33 -3
- je_editor/pyside_ui/main_ui/menu/language_menu/build_language_server.py +39 -0
- je_editor/pyside_ui/main_ui/menu/python_env_menu/build_venv_menu.py +102 -40
- je_editor/pyside_ui/main_ui/menu/run_menu/build_run_menu.py +53 -6
- je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_debug_menu.py +47 -3
- je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_program_menu.py +45 -5
- je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_shell_menu.py +41 -3
- je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/utils.py +21 -0
- je_editor/pyside_ui/main_ui/menu/set_menu_bar.py +37 -11
- je_editor/pyside_ui/main_ui/menu/style_menu/build_style_menu.py +42 -6
- je_editor/pyside_ui/main_ui/menu/tab_menu/build_tab_menu.py +202 -27
- je_editor/pyside_ui/main_ui/menu/text_menu/build_text_menu.py +66 -0
- je_editor/pyside_ui/main_ui/save_settings/setting_utils.py +18 -1
- je_editor/pyside_ui/main_ui/save_settings/user_color_setting_file.py +32 -2
- je_editor/pyside_ui/main_ui/save_settings/user_setting_file.py +37 -10
- je_editor/pyside_ui/main_ui/system_tray/extend_system_tray.py +39 -0
- je_editor/start_editor.py +25 -0
- je_editor/utils/encodings/python_encodings.py +100 -97
- je_editor/utils/exception/exception_tags.py +11 -11
- je_editor/utils/file/open/open_file.py +35 -19
- je_editor/utils/file/save/save_file.py +34 -13
- je_editor/utils/json/json_file.py +29 -14
- je_editor/utils/json_format/json_process.py +32 -1
- je_editor/utils/logging/loggin_instance.py +37 -7
- je_editor/utils/multi_language/english.py +102 -6
- je_editor/utils/multi_language/multi_language_wrapper.py +28 -3
- je_editor/utils/multi_language/traditional_chinese.py +101 -10
- je_editor/utils/redirect_manager/redirect_manager_class.py +49 -11
- je_editor/utils/venv_check/check_venv.py +37 -14
- {je_editor-0.0.202.dist-info → je_editor-0.0.228.dist-info}/METADATA +12 -6
- je_editor-0.0.228.dist-info/RECORD +140 -0
- {je_editor-0.0.202.dist-info → je_editor-0.0.228.dist-info}/WHEEL +1 -1
- je_editor-0.0.202.dist-info/RECORD +0 -108
- {je_editor-0.0.202.dist-info → je_editor-0.0.228.dist-info/licenses}/LICENSE +0 -0
- {je_editor-0.0.202.dist-info → je_editor-0.0.228.dist-info}/top_level.txt +0 -0
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
1
|
+
from __future__ import annotations # 支援延遲型別註解 (Python 3.7+)
|
|
2
2
|
|
|
3
|
-
import queue
|
|
4
|
-
import subprocess
|
|
5
|
-
import sys
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
from threading import Thread
|
|
8
|
-
from typing import Union
|
|
3
|
+
import queue # 佇列,用於執行緒間傳遞訊息
|
|
4
|
+
import subprocess # 建立與管理子程序 (執行外部程式)
|
|
5
|
+
import sys # 系統相關資訊 (平台、參數等)
|
|
6
|
+
from pathlib import Path # 處理檔案與路徑
|
|
7
|
+
from threading import Thread # 執行緒,用於非同步處理
|
|
8
|
+
from typing import Union # 型別提示:允許多種型別
|
|
9
9
|
|
|
10
|
-
from PySide6.QtCore import QTimer
|
|
11
|
-
from PySide6.
|
|
10
|
+
from PySide6.QtCore import QTimer # Qt 計時器,用於定時觸發事件
|
|
11
|
+
from PySide6.QtGui import QTextCharFormat # 設定文字格式 (顏色、字型等)
|
|
12
|
+
from PySide6.QtWidgets import QTextEdit # 文字編輯器元件
|
|
12
13
|
|
|
14
|
+
# 專案內部模組
|
|
13
15
|
from je_editor.pyside_ui.code.running_process_manager import run_instance_manager
|
|
14
16
|
from je_editor.pyside_ui.main_ui.editor.editor_widget import EditorWidget
|
|
15
17
|
from je_editor.pyside_ui.main_ui.save_settings.user_color_setting_file import actually_color_dict
|
|
@@ -19,45 +21,59 @@ from je_editor.utils.logging.loggin_instance import jeditor_logger
|
|
|
19
21
|
from je_editor.utils.venv_check.check_venv import check_and_choose_venv
|
|
20
22
|
|
|
21
23
|
|
|
24
|
+
# Support postponed evaluation of type annotations
|
|
25
|
+
|
|
26
|
+
|
|
22
27
|
class ExecManager(object):
|
|
28
|
+
"""
|
|
29
|
+
程式執行管理器
|
|
30
|
+
Execution manager for running code inside the editor.
|
|
31
|
+
負責:
|
|
32
|
+
- 建立子程序 (subprocess)
|
|
33
|
+
- 讀取標準輸出與錯誤輸出
|
|
34
|
+
- 將結果顯示在 QTextEdit
|
|
35
|
+
- 管理計時器與執行緒
|
|
36
|
+
"""
|
|
23
37
|
|
|
24
38
|
def __init__(
|
|
25
39
|
self,
|
|
26
|
-
main_window: Union[EditorWidget, None] = None,
|
|
27
|
-
program_language: str = "python",
|
|
28
|
-
program_encoding: str = "utf-8",
|
|
29
|
-
program_buffer: int = 1024,
|
|
40
|
+
main_window: Union[EditorWidget, None] = None, # 主視窗 (可為 None)
|
|
41
|
+
program_language: str = "python", # 預設程式語言
|
|
42
|
+
program_encoding: str = "utf-8", # 預設編碼
|
|
43
|
+
program_buffer: int = 1024, # 緩衝區大小
|
|
30
44
|
):
|
|
31
45
|
"""
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
:param program_encoding: which encoding
|
|
46
|
+
初始化執行管理器
|
|
47
|
+
Initialize ExecManager
|
|
35
48
|
"""
|
|
36
49
|
jeditor_logger.info(f"Init ExecManager "
|
|
37
50
|
f"main_window: {main_window} "
|
|
38
51
|
f"program_language: {program_language} "
|
|
39
52
|
f"program_encoding: {program_encoding} "
|
|
40
53
|
f"program_buffer: {program_buffer}")
|
|
41
|
-
|
|
42
|
-
self.
|
|
43
|
-
self.
|
|
44
|
-
self.
|
|
45
|
-
self.
|
|
46
|
-
self.
|
|
47
|
-
self.
|
|
48
|
-
self.
|
|
49
|
-
self.
|
|
50
|
-
self.
|
|
54
|
+
# 初始化屬性
|
|
55
|
+
self.read_program_error_output_from_thread = None # 錯誤輸出讀取執行緒
|
|
56
|
+
self.read_program_output_from_thread = None # 標準輸出讀取執行緒
|
|
57
|
+
self.main_window: EditorWidget = main_window # 主視窗
|
|
58
|
+
self.compiler_path = None # 編譯器/直譯器路徑
|
|
59
|
+
self.code_result: Union[QTextEdit, None] = None # 顯示程式輸出的文字框
|
|
60
|
+
self.code_result_cursor: Union[QTextEdit.textCursor, None] = None
|
|
61
|
+
self.timer: Union[QTimer, None] = None # 定時器
|
|
62
|
+
self.still_run_program = True # 程式是否仍在執行
|
|
63
|
+
self.process: Union[subprocess.Popen, None] = None # 子程序
|
|
64
|
+
self.run_output_queue = queue.Queue() # 標準輸出佇列
|
|
65
|
+
self.run_error_queue = queue.Queue() # 錯誤輸出佇列
|
|
51
66
|
self.program_language = program_language
|
|
52
67
|
self.program_encoding = program_encoding
|
|
53
68
|
self.program_buffer = program_buffer
|
|
54
|
-
self.renew_path()
|
|
55
|
-
run_instance_manager.instance_list.append(self)
|
|
69
|
+
self.renew_path() # 設定 Python 直譯器路徑
|
|
70
|
+
run_instance_manager.instance_list.append(self) # 註冊到全域執行管理器
|
|
56
71
|
|
|
57
72
|
def renew_path(self) -> None:
|
|
73
|
+
"""更新 Python 直譯器路徑 / Renew compiler path"""
|
|
58
74
|
jeditor_logger.info("ExecManager renew_path")
|
|
59
75
|
if self.main_window.python_compiler is None:
|
|
60
|
-
#
|
|
76
|
+
# 如果主視窗沒有指定 Python,則使用虛擬環境
|
|
61
77
|
if sys.platform in ["win32", "cygwin", "msys"]:
|
|
62
78
|
venv_path = Path(str(Path.cwd()) + "/venv/Scripts")
|
|
63
79
|
else:
|
|
@@ -67,8 +83,8 @@ class ExecManager(object):
|
|
|
67
83
|
self.compiler_path = self.main_window.python_compiler
|
|
68
84
|
|
|
69
85
|
def later_init(self) -> None:
|
|
86
|
+
"""延遲初始化,設定輸出區與計時器 / Setup code result area and timer"""
|
|
70
87
|
jeditor_logger.info("ExecManager later_init")
|
|
71
|
-
# Enable timer and code result area
|
|
72
88
|
if self.main_window is not None:
|
|
73
89
|
self.code_result: QTextEdit = self.main_window.code_result
|
|
74
90
|
self.timer = QTimer(self.main_window)
|
|
@@ -77,71 +93,83 @@ class ExecManager(object):
|
|
|
77
93
|
|
|
78
94
|
def exec_code(self, exec_file_name, exec_prefix: Union[str, list] = None) -> None:
|
|
79
95
|
"""
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
:
|
|
96
|
+
執行指定檔案
|
|
97
|
+
Execute given file
|
|
98
|
+
:param exec_file_name: 要執行的檔案名稱
|
|
99
|
+
:param exec_prefix: 使用者自定義前綴 (例如 python -m)
|
|
83
100
|
"""
|
|
84
101
|
jeditor_logger.info(f"ExecManager exec_code "
|
|
85
102
|
f"exec_file_name: {exec_file_name} "
|
|
86
103
|
f"exec_prefix: {exec_prefix}")
|
|
87
104
|
try:
|
|
88
|
-
self.exit_program()
|
|
89
|
-
self.code_result.
|
|
90
|
-
self.code_result.setPlainText("")
|
|
105
|
+
self.exit_program() # 確保先結束舊的程式
|
|
106
|
+
self.code_result.setPlainText("") # 清空輸出區
|
|
91
107
|
file_path = Path(exec_file_name)
|
|
92
108
|
reformat_os_file_path = str(file_path.absolute())
|
|
93
|
-
# detect file is exist
|
|
94
109
|
exec_file = reformat_os_file_path
|
|
95
|
-
|
|
110
|
+
|
|
111
|
+
# 建立執行參數
|
|
96
112
|
if exec_prefix is None:
|
|
97
113
|
execute_program_param = [self.compiler_path, exec_file]
|
|
98
114
|
else:
|
|
99
115
|
if isinstance(exec_prefix, str):
|
|
100
116
|
execute_program_param = [self.compiler_path, exec_prefix, exec_file]
|
|
101
117
|
else:
|
|
102
|
-
execute_program_param =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
execute_program_param.append(prefix)
|
|
106
|
-
execute_program_param.append(exec_file)
|
|
118
|
+
execute_program_param = [self.compiler_path] + exec_prefix + [exec_file]
|
|
119
|
+
|
|
120
|
+
# 非 Windows 平台需轉為字串
|
|
107
121
|
if sys.platform not in ["win32", "cygwin", "msys"]:
|
|
108
122
|
execute_program_param = " ".join(execute_program_param)
|
|
123
|
+
|
|
124
|
+
# 建立子程序
|
|
109
125
|
self.process = subprocess.Popen(
|
|
110
126
|
execute_program_param,
|
|
111
127
|
stdout=subprocess.PIPE,
|
|
112
128
|
stderr=subprocess.PIPE,
|
|
113
129
|
stdin=subprocess.PIPE,
|
|
114
|
-
shell=
|
|
130
|
+
shell=False
|
|
115
131
|
)
|
|
116
132
|
self.still_run_program = True
|
|
117
|
-
|
|
133
|
+
|
|
134
|
+
# 啟動輸出讀取執行緒
|
|
118
135
|
self.read_program_output_from_thread = Thread(
|
|
119
136
|
target=self.read_program_output_from_process,
|
|
120
137
|
daemon=True
|
|
121
138
|
)
|
|
122
139
|
self.read_program_output_from_thread.start()
|
|
123
|
-
|
|
140
|
+
|
|
141
|
+
# 啟動錯誤讀取執行緒
|
|
124
142
|
self.read_program_error_output_from_thread = Thread(
|
|
125
143
|
target=self.read_program_error_output_from_process,
|
|
126
144
|
daemon=True
|
|
127
145
|
)
|
|
128
146
|
self.read_program_error_output_from_thread.start()
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
147
|
+
|
|
148
|
+
# 顯示執行的檔案路徑
|
|
149
|
+
text_cursor = self.code_result.textCursor()
|
|
150
|
+
text_format = QTextCharFormat()
|
|
151
|
+
text_format.setForeground(actually_color_dict.get("normal_output_color"))
|
|
152
|
+
text_cursor.insertText(self.compiler_path + " " + reformat_os_file_path, text_format)
|
|
153
|
+
text_cursor.insertBlock()
|
|
154
|
+
|
|
155
|
+
# 啟動定時器,每 10ms 更新輸出
|
|
133
156
|
self.timer = QTimer(self.main_window)
|
|
134
157
|
self.timer.setInterval(10)
|
|
135
158
|
self.timer.timeout.connect(self.pull_text)
|
|
136
159
|
self.timer.start()
|
|
160
|
+
|
|
137
161
|
except Exception as error:
|
|
138
|
-
|
|
139
|
-
self.code_result.
|
|
140
|
-
|
|
162
|
+
# 發生錯誤時顯示錯誤訊息
|
|
163
|
+
text_cursor = self.code_result.textCursor()
|
|
164
|
+
text_format = QTextCharFormat()
|
|
165
|
+
text_format.setForeground(actually_color_dict.get("normal_output_color"))
|
|
166
|
+
text_cursor.insertText(str(error), text_format)
|
|
167
|
+
text_cursor.insertBlock()
|
|
141
168
|
if self.process is not None:
|
|
142
169
|
self.process.terminate()
|
|
143
170
|
|
|
144
171
|
def full_exit_program(self):
|
|
172
|
+
"""完全結束程式 / Fully exit program"""
|
|
145
173
|
jeditor_logger.info("ExecManager full_exit_program")
|
|
146
174
|
self.timer.stop()
|
|
147
175
|
self.exit_program()
|
|
@@ -149,64 +177,90 @@ class ExecManager(object):
|
|
|
149
177
|
|
|
150
178
|
def pull_text(self) -> None:
|
|
151
179
|
jeditor_logger.info("ExecManager pull_text")
|
|
180
|
+
# 從佇列中取出訊息並顯示到 QTextEdit
|
|
152
181
|
# Pull text from queue and put in code result area
|
|
153
182
|
try:
|
|
154
|
-
|
|
183
|
+
# 處理標準輸出
|
|
155
184
|
if not self.run_output_queue.empty():
|
|
156
185
|
output_message = self.run_output_queue.get_nowait()
|
|
157
186
|
output_message = str(output_message).strip()
|
|
158
187
|
if output_message:
|
|
159
|
-
self.code_result.
|
|
160
|
-
|
|
188
|
+
text_cursor = self.code_result.textCursor()
|
|
189
|
+
text_format = QTextCharFormat()
|
|
190
|
+
text_format.setForeground(actually_color_dict.get("normal_output_color"))
|
|
191
|
+
text_cursor.insertText(output_message, text_format)
|
|
192
|
+
text_cursor.insertBlock()
|
|
193
|
+
# 處理錯誤輸出
|
|
161
194
|
if not self.run_error_queue.empty():
|
|
162
195
|
error_message = self.run_error_queue.get_nowait()
|
|
163
196
|
error_message = str(error_message).strip()
|
|
164
197
|
if error_message:
|
|
165
|
-
self.code_result.
|
|
166
|
-
|
|
198
|
+
text_cursor = self.code_result.textCursor()
|
|
199
|
+
text_format = QTextCharFormat()
|
|
200
|
+
text_format.setForeground(actually_color_dict.get("error_output_color"))
|
|
201
|
+
text_cursor.insertText(error_message, text_format)
|
|
202
|
+
text_cursor.insertBlock()
|
|
167
203
|
except queue.Empty:
|
|
204
|
+
# 如果佇列是空的就忽略
|
|
168
205
|
pass
|
|
206
|
+
|
|
207
|
+
# 如果子程序已經結束(returncode 不為 None),則完全退出
|
|
169
208
|
if self.process.returncode == 0:
|
|
170
209
|
self.full_exit_program()
|
|
171
210
|
elif self.process.returncode is not None:
|
|
172
211
|
self.full_exit_program()
|
|
212
|
+
|
|
213
|
+
# 如果程式仍在執行,持續檢查狀態
|
|
173
214
|
if self.still_run_program:
|
|
174
|
-
# poll
|
|
215
|
+
# poll() 不會阻塞,只是更新 returncode
|
|
175
216
|
self.process.poll()
|
|
176
217
|
|
|
177
|
-
#
|
|
218
|
+
# 結束程式:將執行旗標設為 False,清理執行緒、佇列與子程序
|
|
219
|
+
# Exit program: change run flag to false and clean read thread, queue, and process
|
|
178
220
|
def exit_program(self) -> None:
|
|
179
221
|
jeditor_logger.info("ExecManager exit_program")
|
|
180
222
|
self.still_run_program = False
|
|
223
|
+
# 清除讀取執行緒的引用
|
|
181
224
|
if self.read_program_output_from_thread is not None:
|
|
182
225
|
self.read_program_output_from_thread = None
|
|
183
226
|
if self.read_program_error_output_from_thread is not None:
|
|
184
227
|
self.read_program_error_output_from_thread = None
|
|
228
|
+
# 清空佇列
|
|
185
229
|
self.print_and_clear_queue()
|
|
230
|
+
# 如果子程序存在,則終止
|
|
186
231
|
if self.process is not None:
|
|
187
232
|
self.process.terminate()
|
|
188
|
-
self.code_result.
|
|
233
|
+
text_cursor = self.code_result.textCursor()
|
|
234
|
+
text_format = QTextCharFormat()
|
|
235
|
+
text_format.setForeground(actually_color_dict.get("normal_output_color"))
|
|
236
|
+
text_cursor.insertText(f"Program exit with code {self.process.returncode}", text_format)
|
|
237
|
+
text_cursor.insertBlock()
|
|
189
238
|
self.process = None
|
|
190
239
|
|
|
191
|
-
#
|
|
240
|
+
# 清空輸出與錯誤佇列
|
|
241
|
+
# Pull all remaining strings in queues and reset them
|
|
192
242
|
def print_and_clear_queue(self) -> None:
|
|
193
243
|
jeditor_logger.info("ExecManager print_and_clear_queue")
|
|
194
244
|
self.run_output_queue = queue.Queue()
|
|
195
245
|
self.run_error_queue = queue.Queue()
|
|
196
246
|
|
|
247
|
+
# 從子程序 stdout 持續讀取資料並放入輸出佇列
|
|
248
|
+
# Continuously read from process stdout and put into output queue
|
|
197
249
|
def read_program_output_from_process(self) -> None:
|
|
198
250
|
jeditor_logger.info("ExecManager read_program_output_from_process")
|
|
199
251
|
while self.still_run_program:
|
|
200
|
-
program_output_data: str = self.process.stdout.
|
|
252
|
+
program_output_data: str = self.process.stdout.readline(
|
|
201
253
|
self.program_buffer).decode(self.program_encoding, "replace")
|
|
202
254
|
if self.process:
|
|
203
255
|
self.process.stdout.flush()
|
|
204
256
|
self.run_output_queue.put_nowait(program_output_data)
|
|
205
257
|
|
|
258
|
+
# 從子程序 stderr 持續讀取資料並放入錯誤佇列
|
|
259
|
+
# Continuously read from process stderr and put into error queue
|
|
206
260
|
def read_program_error_output_from_process(self) -> None:
|
|
207
261
|
jeditor_logger.info("ExecManager read_program_error_output_from_process")
|
|
208
262
|
while self.still_run_program:
|
|
209
|
-
program_error_output_data: str = self.process.stderr.
|
|
263
|
+
program_error_output_data: str = self.process.stderr.readline(
|
|
210
264
|
self.program_buffer).decode(self.program_encoding, "replace")
|
|
211
265
|
if self.process:
|
|
212
266
|
self.process.stderr.flush()
|