je-editor 0.0.222__py3-none-any.whl → 0.0.224__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 je-editor might be problematic. Click here for more details.

Files changed (75) hide show
  1. je_editor/__init__.py +2 -2
  2. je_editor/git_client/commit_graph.py +7 -7
  3. je_editor/git_client/git_action.py +0 -7
  4. je_editor/pyside_ui/browser/browser_view.py +16 -4
  5. je_editor/pyside_ui/browser/browser_widget.py +43 -29
  6. je_editor/pyside_ui/browser/main_browser_widget.py +85 -0
  7. je_editor/pyside_ui/code/auto_save/auto_save_manager.py +34 -2
  8. je_editor/pyside_ui/code/auto_save/auto_save_thread.py +19 -6
  9. je_editor/pyside_ui/code/code_format/pep8_format.py +53 -9
  10. je_editor/pyside_ui/code/code_process/code_exec.py +88 -52
  11. je_editor/pyside_ui/code/plaintext_code_edit/code_edit_plaintext.py +116 -55
  12. je_editor/pyside_ui/code/running_process_manager.py +19 -1
  13. je_editor/pyside_ui/code/shell_process/shell_exec.py +71 -48
  14. je_editor/pyside_ui/code/syntax/python_syntax.py +45 -10
  15. je_editor/pyside_ui/code/syntax/syntax_setting.py +40 -12
  16. je_editor/pyside_ui/code/textedit_code_result/code_record.py +34 -12
  17. je_editor/pyside_ui/code/variable_inspector/inspector_gui.py +53 -6
  18. je_editor/pyside_ui/dialog/ai_dialog/set_ai_dialog.py +30 -3
  19. je_editor/pyside_ui/dialog/file_dialog/create_file_dialog.py +35 -2
  20. je_editor/pyside_ui/dialog/file_dialog/open_file_dialog.py +33 -5
  21. je_editor/pyside_ui/dialog/file_dialog/save_file_dialog.py +25 -3
  22. je_editor/pyside_ui/dialog/search_ui/search_error_box.py +26 -1
  23. je_editor/pyside_ui/dialog/search_ui/search_text_box.py +26 -1
  24. je_editor/pyside_ui/git_ui/code_diff_compare/code_diff_viewer_widget.py +11 -11
  25. je_editor/pyside_ui/git_ui/git_client/commit_table.py +46 -8
  26. je_editor/pyside_ui/git_ui/git_client/git_branch_tree_widget.py +49 -15
  27. je_editor/pyside_ui/git_ui/git_client/git_client_gui.py +81 -16
  28. je_editor/pyside_ui/git_ui/git_client/graph_view.py +64 -20
  29. je_editor/pyside_ui/main_ui/ai_widget/ai_config.py +20 -5
  30. je_editor/pyside_ui/main_ui/ai_widget/ask_thread.py +20 -1
  31. je_editor/pyside_ui/main_ui/ai_widget/chat_ui.py +56 -41
  32. je_editor/pyside_ui/main_ui/ai_widget/langchain_interface.py +45 -6
  33. je_editor/pyside_ui/main_ui/console_widget/console_gui.py +44 -12
  34. je_editor/pyside_ui/main_ui/console_widget/qprocess_adapter.py +34 -13
  35. je_editor/pyside_ui/main_ui/dock/destroy_dock.py +33 -2
  36. je_editor/pyside_ui/main_ui/editor/editor_widget.py +104 -20
  37. je_editor/pyside_ui/main_ui/editor/editor_widget_dock.py +34 -7
  38. je_editor/pyside_ui/main_ui/editor/process_input.py +38 -11
  39. je_editor/pyside_ui/main_ui/ipython_widget/rich_jupyter.py +46 -11
  40. je_editor/pyside_ui/main_ui/main_editor.py +180 -42
  41. je_editor/pyside_ui/main_ui/menu/check_style_menu/build_check_style_menu.py +51 -28
  42. je_editor/pyside_ui/main_ui/menu/dock_menu/build_dock_menu.py +83 -36
  43. je_editor/pyside_ui/main_ui/menu/file_menu/build_file_menu.py +70 -17
  44. je_editor/pyside_ui/main_ui/menu/help_menu/build_help_menu.py +35 -4
  45. je_editor/pyside_ui/main_ui/menu/language_menu/build_language_server.py +41 -1
  46. je_editor/pyside_ui/main_ui/menu/python_env_menu/build_venv_menu.py +100 -42
  47. je_editor/pyside_ui/main_ui/menu/run_menu/build_run_menu.py +57 -7
  48. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_debug_menu.py +50 -4
  49. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_program_menu.py +52 -6
  50. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_shell_menu.py +44 -4
  51. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/utils.py +23 -1
  52. je_editor/pyside_ui/main_ui/menu/set_menu_bar.py +37 -12
  53. je_editor/pyside_ui/main_ui/menu/style_menu/build_style_menu.py +44 -7
  54. je_editor/pyside_ui/main_ui/menu/tab_menu/build_tab_menu.py +127 -44
  55. je_editor/pyside_ui/main_ui/menu/text_menu/build_text_menu.py +65 -1
  56. je_editor/pyside_ui/main_ui/save_settings/setting_utils.py +18 -1
  57. je_editor/pyside_ui/main_ui/save_settings/user_color_setting_file.py +33 -3
  58. je_editor/pyside_ui/main_ui/save_settings/user_setting_file.py +38 -11
  59. je_editor/pyside_ui/main_ui/system_tray/extend_system_tray.py +39 -2
  60. je_editor/start_editor.py +26 -1
  61. je_editor/utils/encodings/python_encodings.py +101 -98
  62. je_editor/utils/file/open/open_file.py +36 -19
  63. je_editor/utils/file/save/save_file.py +35 -14
  64. je_editor/utils/json/json_file.py +29 -14
  65. je_editor/utils/json_format/json_process.py +33 -2
  66. je_editor/utils/logging/loggin_instance.py +38 -8
  67. je_editor/utils/multi_language/multi_language_wrapper.py +29 -4
  68. je_editor/utils/redirect_manager/redirect_manager_class.py +49 -11
  69. je_editor/utils/venv_check/check_venv.py +45 -15
  70. {je_editor-0.0.222.dist-info → je_editor-0.0.224.dist-info}/METADATA +1 -1
  71. {je_editor-0.0.222.dist-info → je_editor-0.0.224.dist-info}/RECORD +74 -74
  72. je_editor/git_client/github.py +0 -81
  73. {je_editor-0.0.222.dist-info → je_editor-0.0.224.dist-info}/WHEEL +0 -0
  74. {je_editor-0.0.222.dist-info → je_editor-0.0.224.dist-info}/licenses/LICENSE +0 -0
  75. {je_editor-0.0.222.dist-info → je_editor-0.0.224.dist-info}/top_level.txt +0 -0
@@ -23,7 +23,6 @@ from je_editor.utils.venv_check.check_venv import check_and_choose_venv
23
23
 
24
24
 
25
25
  class ShellManager(object):
26
-
27
26
  def __init__(
28
27
  self,
29
28
  main_window: Union[EditorWidget, None] = None,
@@ -31,36 +30,41 @@ class ShellManager(object):
31
30
  program_buffer: int = 1024,
32
31
  after_done_function: Union[None, Callable] = None
33
32
  ):
33
+ # 初始化 ShellManager,記錄基本設定
34
+ # Initialize ShellManager, log basic settings
34
35
  jeditor_logger.info(f"Init ShellManager "
35
36
  f"main_window: {main_window} "
36
37
  f"shell_encoding: {shell_encoding} "
37
38
  f"program_buffer: {program_buffer} "
38
39
  f"after_done_function: {after_done_function}")
39
40
  """
40
- :param main_window: Pyside main window
41
- :param shell_encoding: shell command read output encoding
42
- :param program_buffer: buffer size
41
+ :param main_window: Pyside 主視窗 / Pyside main window
42
+ :param shell_encoding: shell 輸出編碼 / shell command output encoding
43
+ :param program_buffer: 緩衝區大小 / buffer size
43
44
  """
44
- self.read_program_error_output_from_thread = None
45
- self.read_program_output_from_thread = None
46
- self.main_window: EditorWidget = main_window
47
- self.compiler_path = None
48
- self.code_result: Union[QTextEdit, None] = None
49
- self.timer: Union[QTimer, None] = None
50
- self.still_run_shell: bool = True
51
- self.process = None
52
- self.run_output_queue: queue.Queue = queue.Queue()
53
- self.run_error_queue: queue.Queue = queue.Queue()
54
- self.program_encoding: str = shell_encoding
55
- self.program_buffer: int = program_buffer
56
- self.after_done_function = after_done_function
57
- self.renew_path()
58
- run_instance_manager.instance_list.append(self)
45
+ self.read_program_error_output_from_thread = None # 錯誤輸出讀取執行緒 / thread for reading stderr
46
+ self.read_program_output_from_thread = None # 標準輸出讀取執行緒 / thread for reading stdout
47
+ self.main_window: EditorWidget = main_window # 主視窗 / main window
48
+ self.compiler_path = None # Python 編譯器路徑 / Python compiler path
49
+ self.code_result: Union[QTextEdit, None] = None # 顯示輸出結果的文字框 / QTextEdit for displaying results
50
+ self.timer: Union[QTimer, None] = None # 定時器 / QTimer for periodic updates
51
+ self.still_run_shell: bool = True # 是否仍在執行 / flag for running state
52
+ self.process = None # 子程序物件 / subprocess object
53
+ self.run_output_queue: queue.Queue = queue.Queue() # 標準輸出佇列 / stdout queue
54
+ self.run_error_queue: queue.Queue = queue.Queue() # 錯誤輸出佇列 / stderr queue
55
+ self.program_encoding: str = shell_encoding # 編碼設定 / encoding setting
56
+ self.program_buffer: int = program_buffer # 緩衝區大小 / buffer size
57
+ self.after_done_function = after_done_function # 完成後的回呼函數 / callback after done
58
+ self.renew_path() # 更新 Python 執行路徑 / renew Python path
59
+ run_instance_manager.instance_list.append(self) # 註冊到執行管理器 / register instance
59
60
 
60
61
  def renew_path(self) -> None:
62
+ # 更新 Python 編譯器路徑
63
+ # Renew Python compiler path
61
64
  jeditor_logger.info("ShellManager renew_path")
62
65
  if self.main_window.python_compiler is None:
63
- # Renew compiler path
66
+ # 如果主視窗沒有指定 Python,則使用 venv
67
+ # If no compiler specified, use venv
64
68
  if sys.platform in ["win32", "cygwin", "msys"]:
65
69
  venv_path = Path(os.getcwd() + "/venv/Scripts")
66
70
  else:
@@ -70,6 +74,8 @@ class ShellManager(object):
70
74
  self.compiler_path = self.main_window.python_compiler
71
75
 
72
76
  def later_init(self) -> None:
77
+ # 延遲初始化,綁定輸出視窗
78
+ # Late initialization, bind output QTextEdit
73
79
  jeditor_logger.info("ShellManager later_init")
74
80
  if self.main_window is not None:
75
81
  self.code_result: QTextEdit = self.main_window.code_result
@@ -78,22 +84,25 @@ class ShellManager(object):
78
84
 
79
85
  def exec_shell(self, shell_command: Union[str, list]) -> None:
80
86
  """
81
- :param shell_command: shell command will run
82
- :return: if error return result and True else return result and False
87
+ 執行 shell 指令
88
+ Execute shell command
89
+ :param shell_command: 要執行的指令 / command to run
90
+ :return: 若錯誤則回傳錯誤訊息 / return error message if failed
83
91
  """
84
92
  jeditor_logger.info(f"ShellManager exec_shell, shell_command: {shell_command}")
85
93
  try:
86
- self.exit_program()
87
- self.code_result.setPlainText("")
94
+ self.exit_program() # 結束舊的程序 / terminate previous process
95
+ self.code_result.setPlainText("") # 清空輸出視窗 / clear output window
88
96
  if sys.platform in ["win32", "cygwin", "msys"]:
89
97
  args = shell_command
90
98
  else:
91
- args = shlex.split(shell_command)
99
+ args = shlex.split(shell_command) # 非 Windows 系統需分割指令 / split command for Unix-like
92
100
  text_cursor = self.code_result.textCursor()
93
101
  text_format = QTextCharFormat()
94
102
  text_format.setForeground(actually_color_dict.get("normal_output_color"))
95
- text_cursor.insertText(str(args), text_format)
103
+ text_cursor.insertText(str(args), text_format) # 顯示執行的指令 / show executed command
96
104
  text_cursor.insertBlock()
105
+ # 建立子程序 / create subprocess
97
106
  self.process = subprocess.Popen(
98
107
  args=args,
99
108
  stdout=subprocess.PIPE,
@@ -102,24 +111,26 @@ class ShellManager(object):
102
111
  shell=True,
103
112
  )
104
113
  self.still_run_shell = True
105
- # program output message queue thread
114
+ # 建立讀取標準輸出的執行緒 / thread for stdout
106
115
  self.read_program_output_from_thread = Thread(
107
116
  target=self.read_program_output_from_process,
108
117
  daemon=True
109
118
  )
110
119
  self.read_program_output_from_thread.start()
111
- # program error message queue thread
120
+ # 建立讀取錯誤輸出的執行緒 / thread for stderr
112
121
  self.read_program_error_output_from_thread = Thread(
113
122
  target=self.read_program_error_output_from_process,
114
123
  daemon=True
115
124
  )
116
125
  self.read_program_error_output_from_thread.start()
117
- # start timer
126
+ # 啟動定時器,每 10ms 更新一次輸出 / start QTimer for updating output
118
127
  self.timer = QTimer(self.main_window)
119
128
  self.timer.setInterval(10)
120
129
  self.timer.timeout.connect(self.pull_text)
121
130
  self.timer.start()
122
131
  except Exception as error:
132
+ # 若發生錯誤,顯示錯誤訊息並結束程序
133
+ # If error occurs, show error message and terminate process
123
134
  text_cursor = self.code_result.textCursor()
124
135
  text_format = QTextCharFormat()
125
136
  text_format.setForeground(actually_color_dict.get("error_output_color"))
@@ -130,6 +141,8 @@ class ShellManager(object):
130
141
 
131
142
  # tkinter_ui update method
132
143
  def pull_text(self) -> None:
144
+ # 從佇列中拉取輸出與錯誤訊息,並更新到 UI
145
+ # Pull stdout/stderr messages from queue and update UI
133
146
  jeditor_logger.info("ShellManager pull_text")
134
147
  try:
135
148
  if not self.run_output_queue.empty():
@@ -152,61 +165,71 @@ class ShellManager(object):
152
165
  text_cursor.insertBlock()
153
166
  except queue.Empty:
154
167
  pass
168
+ # 檢查子程序是否結束 / check if process finished
155
169
  if self.process.returncode == 0:
156
170
  self.process_run_over()
157
171
  elif self.process.returncode is not None:
158
172
  self.process_run_over()
159
173
  if self.still_run_shell:
160
- # poll return code
174
+ # 持續檢查程序狀態 / keep polling process
161
175
  self.process.poll()
162
-
163
176
  def process_run_over(self):
177
+ # 當子程序結束時呼叫,停止計時器並清理資源
178
+ # Called when subprocess finishes, stop timer and clean up resources
164
179
  jeditor_logger.info("ShellManager process_run_over")
165
- self.timer.stop()
166
- self.exit_program()
167
- self.main_window.exec_shell = None
180
+ self.timer.stop() # 停止定時器 / stop QTimer
181
+ self.exit_program() # 結束程序並清理 / terminate process and cleanup
182
+ self.main_window.exec_shell = None # 重置 main_window 的 exec_shell / reset exec_shell reference
168
183
  if self.after_done_function is not None:
169
- self.after_done_function()
184
+ self.after_done_function() # 執行結束後的回呼函數 / run callback if provided
170
185
 
171
- # exit program change runs flag to false and clean read thread and queue and process
186
+ # exit program: 將執行旗標設為 False,清理執行緒、佇列與子程序
187
+ # exit program: set running flag to False, clean threads, queues, and subprocess
172
188
  def exit_program(self) -> None:
173
189
  jeditor_logger.info("ShellManager exit_program")
174
- self.still_run_shell = False
190
+ self.still_run_shell = False # 停止讀取迴圈 / stop reading loop
175
191
  if self.read_program_output_from_thread is not None:
176
- self.read_program_output_from_thread = None
192
+ self.read_program_output_from_thread = None # 清理 stdout 執行緒 / clear stdout thread
177
193
  if self.read_program_error_output_from_thread is not None:
178
- self.read_program_error_output_from_thread = None
179
- self.print_and_clear_queue()
194
+ self.read_program_error_output_from_thread = None # 清理 stderr 執行緒 / clear stderr thread
195
+ self.print_and_clear_queue() # 清空輸出佇列 / clear output queues
180
196
  if self.process is not None:
181
- self.process.terminate()
197
+ self.process.terminate() # 終止子程序 / terminate subprocess
182
198
  text_cursor = self.code_result.textCursor()
183
199
  text_format = QTextCharFormat()
184
200
  text_format.setForeground(actually_color_dict.get("normal_output_color"))
201
+ # 顯示退出代碼 / show exit code
185
202
  text_cursor.insertText(f"Shell command exit with code {self.process.returncode}", text_format)
186
203
  text_cursor.insertBlock()
187
- self.process = None
204
+ self.process = None # 清空 process 物件 / reset process object
188
205
 
189
206
  def print_and_clear_queue(self) -> None:
207
+ # 清空 stdout 與 stderr 佇列
208
+ # Reset stdout and stderr queues
190
209
  jeditor_logger.info("ShellManager print_and_clear_queue")
191
210
  self.run_output_queue = queue.Queue()
192
211
  self.run_error_queue = queue.Queue()
193
212
 
194
213
  def read_program_output_from_process(self) -> None:
214
+ # 從子程序讀取標準輸出並放入佇列
215
+ # Continuously read stdout from subprocess and put into queue
195
216
  jeditor_logger.info("ShellManager read_program_output_from_process")
196
217
  while self.still_run_shell:
197
218
  program_output_data = self.process.stdout.readline(
198
219
  self.program_buffer) \
199
- .decode(self.program_encoding, "replace")
220
+ .decode(self.program_encoding, "replace") # 解碼輸出 / decode output
200
221
  if self.process:
201
- self.process.stdout.flush()
202
- self.run_output_queue.put_nowait(program_output_data)
222
+ self.process.stdout.flush() # 清空緩衝區 / flush buffer
223
+ self.run_output_queue.put_nowait(program_output_data) # 放入輸出佇列 / enqueue stdout
203
224
 
204
225
  def read_program_error_output_from_process(self) -> None:
226
+ # 從子程序讀取錯誤輸出並放入佇列
227
+ # Continuously read stderr from subprocess and put into queue
205
228
  jeditor_logger.info("ShellManager read_program_error_output_from_process")
206
229
  while self.still_run_shell:
207
230
  program_error_output_data = self.process.stderr.readline(
208
231
  self.program_buffer) \
209
- .decode(self.program_encoding, "replace")
232
+ .decode(self.program_encoding, "replace") # 解碼錯誤輸出 / decode stderr
210
233
  if self.process:
211
- self.process.stderr.flush()
212
- self.run_error_queue.put_nowait(program_error_output_data)
234
+ self.process.stderr.flush() # 清空緩衝區 / flush buffer
235
+ self.run_error_queue.put_nowait(program_error_output_data) # 放入錯誤佇列 / enqueue stderr
@@ -4,46 +4,74 @@ from pathlib import Path
4
4
  from typing import TYPE_CHECKING
5
5
 
6
6
  if TYPE_CHECKING:
7
+ # 僅在型別檢查時匯入,避免循環依賴
8
+ # Only imported during type checking to avoid circular imports
7
9
  from je_editor.pyside_ui.code.plaintext_code_edit.code_edit_plaintext import CodeEditor
8
10
 
9
11
  from PySide6.QtCore import QRegularExpression
10
12
  from PySide6.QtGui import QSyntaxHighlighter
11
13
  from PySide6.QtGui import QTextCharFormat
12
14
 
13
- from je_editor.pyside_ui.code.syntax.syntax_setting import syntax_word_setting_dict, syntax_rule_setting_dict, \
15
+ # 匯入語法設定,包括關鍵字、規則、擴展設定
16
+ # Import syntax settings: keywords, rules, and extended settings
17
+ from je_editor.pyside_ui.code.syntax.syntax_setting import (
18
+ syntax_word_setting_dict,
19
+ syntax_rule_setting_dict,
14
20
  syntax_extend_setting_dict
21
+ )
15
22
  from je_editor.utils.logging.loggin_instance import jeditor_logger
16
23
 
17
24
 
18
25
  class PythonHighlighter(QSyntaxHighlighter):
26
+ """
27
+ Python 語法高亮類別,繼承自 QSyntaxHighlighter
28
+ Python syntax highlighter class, inherits from QSyntaxHighlighter
29
+ """
30
+
19
31
  def __init__(self, parent=None, main_window: CodeEditor = None):
20
32
  jeditor_logger.info(f"Init PythonHighlighter parent: {parent}")
21
33
  super().__init__(parent)
22
34
 
23
- self.highlight_rules = []
35
+ self.highlight_rules = [] # 儲存所有高亮規則 / store all highlight rules
36
+
37
+ # 判斷目前檔案副檔名,若無則預設為 .py
38
+ # Determine current file suffix, default to .py
24
39
  if main_window.current_file is not None:
25
40
  current_file_suffix = Path(main_window.current_file).suffix
26
41
  else:
27
42
  current_file_suffix = ".py"
28
- # Basic Highlight
43
+
44
+ # -------------------------
45
+ # 基本語法規則 (通用)
46
+ # Basic highlight rules (common)
47
+ # -------------------------
29
48
  for rule_variable_dict in syntax_rule_setting_dict.values():
30
- color = rule_variable_dict.get("color")
49
+ color = rule_variable_dict.get("color") # 規則顏色 / rule color
31
50
  text_char_format = QTextCharFormat()
32
51
  text_char_format.setForeground(color)
33
- for rule in rule_variable_dict.get("rules"):
52
+ for rule in rule_variable_dict.get("rules"): # 正則規則 / regex rules
34
53
  pattern = QRegularExpression(rule)
35
54
  self.highlight_rules.append((pattern, text_char_format))
55
+
56
+ # -------------------------
57
+ # Python 語法高亮
58
+ # Python-specific highlight
59
+ # -------------------------
36
60
  if current_file_suffix == ".py":
37
- # Python Highlight
38
61
  for rule_variable_dict in syntax_word_setting_dict.values():
39
62
  color = rule_variable_dict.get("color")
40
63
  text_char_format = QTextCharFormat()
41
64
  text_char_format.setForeground(color)
42
- for word in rule_variable_dict.get("words"):
65
+ for word in rule_variable_dict.get("words"): # 關鍵字清單 / keyword list
66
+ # 使用 \b 確保完整單字匹配 / use \b for whole word match
43
67
  pattern = QRegularExpression(rf"\b{word}\b")
44
68
  self.highlight_rules.append((pattern, text_char_format))
69
+
70
+ # -------------------------
71
+ # 其他語言的擴展高亮
72
+ # Extended highlight for other languages
73
+ # -------------------------
45
74
  else:
46
- # Another Highlight
47
75
  if syntax_extend_setting_dict.get(current_file_suffix):
48
76
  for rule_variable_dict in syntax_extend_setting_dict.get(current_file_suffix).values():
49
77
  color = rule_variable_dict.get("color")
@@ -53,12 +81,19 @@ class PythonHighlighter(QSyntaxHighlighter):
53
81
  pattern = QRegularExpression(rf"\b{word}\b")
54
82
  self.highlight_rules.append((pattern, text_char_format))
55
83
  else:
84
+ # 若無對應規則則略過
85
+ # Skip if no rules found
56
86
  pass
57
87
 
58
88
  def highlightBlock(self, text) -> None:
89
+ """
90
+ 對每一行文字進行語法高亮
91
+ Apply syntax highlighting to each block of text
92
+ """
59
93
  jeditor_logger.info(f"PythonHighlighter highlightBlock text: {text}")
60
94
  for pattern, pattern_format in self.highlight_rules:
61
- match_iterator = pattern.globalMatch(text)
95
+ match_iterator = pattern.globalMatch(text) # 全域比對 / global regex match
62
96
  while match_iterator.hasNext():
63
97
  match = match_iterator.next()
64
- self.setFormat(match.capturedStart(), match.capturedLength(), pattern_format)
98
+ # 設定比對到的文字格式 / apply format to matched text
99
+ self.setFormat(match.capturedStart(), match.capturedLength(), pattern_format)
@@ -1,27 +1,45 @@
1
1
  from PySide6.QtGui import QColor
2
2
 
3
+ # -----------------------------
4
+ # 基本語法規則設定 (數字、註解、字串)
5
+ # Basic syntax rule settings (numbers, comments, strings)
6
+ # -----------------------------
3
7
  syntax_rule_setting_dict: dict = {
4
8
  "number_rule": {
5
- "rules": (r"\b[+-]?[0-9]+[lL]?\b",
6
- r"\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b",
7
- r"\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b"),
8
- "color": QColor(0, 128, 255)
9
+ # 數字規則 (整數、十六進位、小數/科學記號)
10
+ # Number rules (integer, hex, float/scientific notation)
11
+ "rules": (
12
+ r"\b[+-]?[0-9]+[lL]?\b", # 整數 integer
13
+ r"\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b", # 十六進位 hex
14
+ r"\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b" # 浮點數/科學記號 float/scientific
15
+ ),
16
+ "color": QColor(0, 128, 255) # 藍色 Blue
9
17
  },
10
18
  "comment_rule": {
19
+ # 註解規則 (以 # 開頭直到換行)
20
+ # Comment rule (starts with # until newline)
11
21
  "rules": (r"#[^\n]*",),
12
- "color": QColor(0, 230, 0)
22
+ "color": QColor(0, 230, 0) # 綠色 Green
13
23
  },
14
24
  "string_rule": {
25
+ # 字串規則 (單引號與雙引號)
26
+ # String rules (single and double quotes)
15
27
  "rules": (
16
- r"'[^'\\]*(\\.[^'\\]*)*'", # Single
17
- r'"[^"\\]*(\\.[^"\\]*)*"', # Double
28
+ r"'[^'\\]*(\\.[^'\\]*)*'", # 單引號字串 single-quoted string
29
+ r'"[^"\\]*(\\.[^"\\]*)*"', # 雙引號字串 double-quoted string
18
30
  ),
19
- "color": QColor(0, 153, 0)
31
+ "color": QColor(0, 153, 0) # 深綠色 Dark green
20
32
  }
21
33
  }
22
34
 
35
+ # -----------------------------
36
+ # 關鍵字與內建函式設定
37
+ # Keywords and built-in functions
38
+ # -----------------------------
23
39
  syntax_word_setting_dict: dict = {
24
40
  "keywords": {
41
+ # Python 保留字 (語法關鍵字)
42
+ # Python reserved keywords
25
43
  "words": (
26
44
  "False", "None", "True", "and", "as", "assert", "async",
27
45
  "await", "break", "class", "continue", "def", "del",
@@ -29,9 +47,11 @@ syntax_word_setting_dict: dict = {
29
47
  "global", "if", "import", "in", "is", "lambda", "nonlocal",
30
48
  "not", "or", "pass", "raise", "return", "try", "while", "with", "yield"
31
49
  ),
32
- "color": QColor(255, 212, 102)
50
+ "color": QColor(255, 212, 102) # 黃色 Yellow
33
51
  },
34
52
  "builtins_keyword": {
53
+ # Python 內建函式與型別
54
+ # Python built-in functions and types
35
55
  "words": (
36
56
  "abs", "aiter", "all", "any", "anext", "ascii",
37
57
  "bin", "bool", "breakpoint", "bytearray", "bytes",
@@ -55,13 +75,21 @@ syntax_word_setting_dict: dict = {
55
75
  "zip",
56
76
  "__import__"
57
77
  ),
58
- "color": QColor(0, 255, 255)
78
+ "color": QColor(0, 255, 255) # 青色 Cyan
59
79
  },
60
80
  "self": {
81
+ # Python 類別中的 self 關鍵字
82
+ # "self" keyword in Python classes
61
83
  "words": ("self",),
62
- "color": QColor(204, 0, 204)
84
+ "color": QColor(204, 0, 204) # 紫色 Purple
63
85
  }
64
86
  }
65
87
 
88
+ # -----------------------------
89
+ # 擴展語法設定 (其他語言可在此加入)
90
+ # Extended syntax settings (for other languages)
91
+ # -----------------------------
66
92
  syntax_extend_setting_dict: dict = {
67
- }
93
+ # 目前為空,可依副檔名新增規則
94
+ # Currently empty, can add rules for other file suffixes
95
+ }
@@ -7,47 +7,69 @@ from je_editor.utils.logging.loggin_instance import jeditor_logger
7
7
 
8
8
 
9
9
  class CodeRecord(QTextEdit):
10
- # Extend QTextEdit
10
+ # 繼承自 QTextEdit,作為程式碼輸出紀錄區
11
+ # Extend QTextEdit, used as a code output record area
11
12
  def __init__(self):
12
13
  jeditor_logger.info("Init CodeRecord")
13
14
  super().__init__()
14
- self.setLineWrapMode(self.LineWrapMode.NoWrap)
15
- self.setReadOnly(True)
16
- # Search Result
15
+ self.setLineWrapMode(self.LineWrapMode.NoWrap) # 禁止自動換行 / disable line wrapping
16
+ self.setReadOnly(True) # 設為唯讀 / set as read-only
17
+
18
+ # 建立搜尋錯誤的快捷動作
19
+ # Create search error action with shortcut
17
20
  self.search_result_action = QAction("Search Error")
18
21
  self.search_result_action.setShortcut("Ctrl+e")
19
22
  self.search_result_action.triggered.connect(
20
- self.start_search_result_dialog
23
+ self.start_search_result_dialog # 綁定觸發事件 / bind trigger event
21
24
  )
22
25
  self.addAction(self.search_result_action)
23
26
 
24
27
  def append(self, text: str) -> None:
28
+ """
29
+ 新增文字到輸出區,若超過最大行數則清空
30
+ Append text to output area, clear if exceeding max lines
31
+ """
25
32
  jeditor_logger.info("CodeRecord append")
26
33
  max_line: int = user_setting_dict.get("max_line_of_output", 200000)
27
34
  if self.document().lineCount() >= max_line > 0:
35
+ # 若行數超過設定,清空內容
36
+ # Clear content if line count exceeds limit
28
37
  self.setPlainText("")
29
38
  super().append(text)
30
39
 
31
40
  def start_search_result_dialog(self) -> None:
41
+ """
42
+ 開啟搜尋對話框,並綁定搜尋按鈕事件
43
+ Open search dialog and bind search button events
44
+ """
32
45
  jeditor_logger.info("CodeRecord start_search_result_dialog")
33
- # Binding search box
34
- self.search_result_box = SearchResultBox()
46
+ self.search_result_box = SearchResultBox() # 建立搜尋框 / create search box
35
47
  self.search_result_box.search_back_button.clicked.connect(
36
- self.find_back_text
48
+ self.find_back_text # 綁定「上一個」搜尋 / bind "find previous"
37
49
  )
38
50
  self.search_result_box.search_next_button.clicked.connect(
39
- self.find_next_text
51
+ self.find_next_text # 綁定「下一個」搜尋 / bind "find next"
40
52
  )
41
- self.search_result_box.show()
53
+ self.search_result_box.show() # 顯示搜尋框 / show search box
42
54
 
43
55
  def find_next_text(self) -> None:
56
+ """
57
+ 搜尋下一個符合的文字
58
+ Find next matching text
59
+ """
44
60
  jeditor_logger.info("CodeRecord find_next_text")
45
61
  if self.search_result_box.isVisible():
46
62
  text = self.search_result_box.search_input.text()
47
- self.find(text)
63
+ self.find(text) # 使用 QTextEdit 內建 find 方法 / use QTextEdit built-in find
48
64
 
49
65
  def find_back_text(self) -> None:
66
+ """
67
+ 搜尋上一個符合的文字
68
+ Find previous matching text
69
+ """
50
70
  jeditor_logger.info("CodeRecord find_back_text")
51
71
  if self.search_result_box.isVisible():
52
72
  text = self.search_result_box.search_input.text()
53
- self.find(text, QTextDocument.FindFlag.FindBackward)
73
+ # 使用 FindBackward 旗標往回搜尋
74
+ # Use FindBackward flag to search backwards
75
+ self.find(text, QTextDocument.FindFlag.FindBackward)