|
| 1 | +# PyBreeze Plugin Guide / 插件開發指南 |
| 2 | + |
| 3 | +PyBreeze (jeditor) supports external plugins for adding **syntax highlighting** and **UI translations**. |
| 4 | + |
| 5 | +PyBreeze (jeditor) 支援外部插件,可用於新增**語法高亮**和 **UI 翻譯**。 |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Quick Start / 快速開始 |
| 10 | + |
| 11 | +1. Create a `.py` file in the `jeditor_plugins/` directory (under your working directory). |
| 12 | +2. Define a `register()` function. |
| 13 | +3. Optionally define `PLUGIN_NAME`, `PLUGIN_AUTHOR`, `PLUGIN_VERSION` for the Plugins menu. |
| 14 | + |
| 15 | +<!-- --> |
| 16 | + |
| 17 | +1. 在工作目錄下的 `jeditor_plugins/` 建立一個 `.py` 檔案。 |
| 18 | +2. 定義一個 `register()` 函式。 |
| 19 | +3. 可選:定義 `PLUGIN_NAME`、`PLUGIN_AUTHOR`、`PLUGIN_VERSION`,會顯示在插件選單中。 |
| 20 | + |
| 21 | +--- |
| 22 | + |
| 23 | +## Plugin Metadata / 插件元資料 |
| 24 | + |
| 25 | +```python |
| 26 | +PLUGIN_NAME = "My Plugin" # Display name in the Plugins menu / 插件選單顯示名稱 |
| 27 | +PLUGIN_AUTHOR = "Your Name" # Author / 作者 |
| 28 | +PLUGIN_VERSION = "1.0.0" # Version / 版本號 |
| 29 | +``` |
| 30 | + |
| 31 | +All three are optional. If omitted, the filename is used as the plugin name. |
| 32 | + |
| 33 | +三者皆為可選。若未定義,則以檔名作為插件名稱。 |
| 34 | + |
| 35 | +--- |
| 36 | + |
| 37 | +## Syntax Highlighting Plugin / 語法高亮插件 |
| 38 | + |
| 39 | +Use `register_programming_language()` to add syntax highlighting for file types. |
| 40 | + |
| 41 | +使用 `register_programming_language()` 為檔案類型新增語法高亮。 |
| 42 | + |
| 43 | +### API |
| 44 | + |
| 45 | +```python |
| 46 | +from je_editor.plugins import register_programming_language |
| 47 | + |
| 48 | +register_programming_language( |
| 49 | + suffix=".ext", # File extension / 副檔名 |
| 50 | + syntax_words={...}, # Keyword groups / 關鍵字群組 |
| 51 | + syntax_rules={...}, # Regex rules (optional) / 正則規則(可選) |
| 52 | +) |
| 53 | +``` |
| 54 | + |
| 55 | +### syntax_words format / syntax_words 格式 |
| 56 | + |
| 57 | +```python |
| 58 | +from PySide6.QtGui import QColor |
| 59 | + |
| 60 | +syntax_words = { |
| 61 | + "group_name": { |
| 62 | + "words": ("keyword1", "keyword2", ...), # Tuple or set of keywords / 關鍵字元組或集合 |
| 63 | + "color": QColor(r, g, b), # Highlight color / 高亮顏色 |
| 64 | + }, |
| 65 | + # More groups... |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +### syntax_rules format / syntax_rules 格式 |
| 70 | + |
| 71 | +```python |
| 72 | +syntax_rules = { |
| 73 | + "rule_name": { |
| 74 | + "rules": (r"regex_pattern", ...), # Tuple of regex patterns / 正則表達式元組 |
| 75 | + "color": QColor(r, g, b), # Highlight color / 高亮顏色 |
| 76 | + }, |
| 77 | +} |
| 78 | +``` |
| 79 | + |
| 80 | +### Full Example / 完整範例 |
| 81 | + |
| 82 | +```python |
| 83 | +"""Go syntax highlighting plugin.""" |
| 84 | +from PySide6.QtGui import QColor |
| 85 | +from je_editor.plugins import register_programming_language |
| 86 | + |
| 87 | +PLUGIN_NAME = "Go Syntax Highlighting" |
| 88 | +PLUGIN_AUTHOR = "Your Name" |
| 89 | +PLUGIN_VERSION = "1.0.0" |
| 90 | + |
| 91 | +go_syntax_words = { |
| 92 | + "keywords": { |
| 93 | + "words": ( |
| 94 | + "break", "case", "chan", "const", "continue", |
| 95 | + "default", "defer", "else", "fallthrough", "for", |
| 96 | + "func", "go", "goto", "if", "import", |
| 97 | + "interface", "map", "package", "range", "return", |
| 98 | + "select", "struct", "switch", "type", "var", |
| 99 | + ), |
| 100 | + "color": QColor(86, 156, 214), |
| 101 | + }, |
| 102 | + "types": { |
| 103 | + "words": ( |
| 104 | + "bool", "byte", "complex64", "complex128", |
| 105 | + "float32", "float64", "int", "int8", "int16", |
| 106 | + "int32", "int64", "rune", "string", "uint", |
| 107 | + "uint8", "uint16", "uint32", "uint64", "uintptr", |
| 108 | + "error", "nil", "true", "false", "iota", |
| 109 | + ), |
| 110 | + "color": QColor(78, 201, 176), |
| 111 | + }, |
| 112 | +} |
| 113 | + |
| 114 | +go_syntax_rules = { |
| 115 | + "single_line_comment": { |
| 116 | + "rules": (r"//[^\n]*",), |
| 117 | + "color": QColor(106, 153, 85), |
| 118 | + }, |
| 119 | +} |
| 120 | + |
| 121 | + |
| 122 | +def register() -> None: |
| 123 | + register_programming_language( |
| 124 | + suffix=".go", |
| 125 | + syntax_words=go_syntax_words, |
| 126 | + syntax_rules=go_syntax_rules, |
| 127 | + ) |
| 128 | +``` |
| 129 | + |
| 130 | +### Multiple Suffixes / 多個副檔名 |
| 131 | + |
| 132 | +If a language uses multiple file extensions, register each suffix with the same `syntax_words`: |
| 133 | + |
| 134 | +若一個語言使用多個副檔名,用相同的 `syntax_words` 分別註冊每個副檔名: |
| 135 | + |
| 136 | +```python |
| 137 | +def register() -> None: |
| 138 | + for suffix in (".cpp", ".cxx", ".cc", ".h", ".hpp", ".hxx"): |
| 139 | + register_programming_language( |
| 140 | + suffix=suffix, |
| 141 | + syntax_words=cpp_syntax_words, |
| 142 | + syntax_rules=cpp_syntax_rules, |
| 143 | + ) |
| 144 | +``` |
| 145 | + |
| 146 | +They will be grouped under one submenu in the Plugins menu. |
| 147 | + |
| 148 | +它們會在插件選單中合併顯示在同一個子選單下。 |
| 149 | + |
| 150 | +--- |
| 151 | + |
| 152 | +## Translation Plugin / 翻譯插件 |
| 153 | + |
| 154 | +Use `register_natural_language()` to add a new UI language. |
| 155 | + |
| 156 | +使用 `register_natural_language()` 新增 UI 語言。 |
| 157 | + |
| 158 | +### API |
| 159 | + |
| 160 | +```python |
| 161 | +from je_editor.plugins import register_natural_language |
| 162 | + |
| 163 | +register_natural_language( |
| 164 | + language_key="French", # Internal key / 內部鍵值 |
| 165 | + display_name="Francais", # Shown in Language menu / 語言選單顯示名稱 |
| 166 | + word_dict={...}, # Translation dictionary / 翻譯字典 |
| 167 | +) |
| 168 | +``` |
| 169 | + |
| 170 | +### word_dict keys / word_dict 鍵值 |
| 171 | + |
| 172 | +The `word_dict` should contain the same keys as jeditor's built-in `english_word_dict`. |
| 173 | +Common keys include: |
| 174 | + |
| 175 | +`word_dict` 應包含與 jeditor 內建 `english_word_dict` 相同的鍵值。 |
| 176 | +常用鍵值包括: |
| 177 | + |
| 178 | +| Key | Description / 說明 | |
| 179 | +|---|---| |
| 180 | +| `application_name` | Window title / 視窗標題 | |
| 181 | +| `file_menu_label` | File menu / 檔案選單 | |
| 182 | +| `run_menu_label` | Run menu / 執行選單 | |
| 183 | +| `tab_name_editor` | Editor tab / 編輯器分頁 | |
| 184 | +| `language_menu_label` | Language menu / 語言選單 | |
| 185 | +| `help_menu_label` | Help menu / 幫助選單 | |
| 186 | + |
| 187 | +For a complete list, refer to `je_editor.utils.multi_language.english.english_word_dict` |
| 188 | +or see the example plugin `exe/jeditor_plugins/french.py`. |
| 189 | + |
| 190 | +完整鍵值列表請參考 `je_editor.utils.multi_language.english.english_word_dict`, |
| 191 | +或參考範例插件 `exe/jeditor_plugins/french.py`。 |
| 192 | + |
| 193 | +### Full Example / 完整範例 |
| 194 | + |
| 195 | +```python |
| 196 | +"""Japanese translation plugin.""" |
| 197 | +from je_editor.plugins import register_natural_language |
| 198 | + |
| 199 | +PLUGIN_NAME = "Japanese Translation" |
| 200 | +PLUGIN_AUTHOR = "Your Name" |
| 201 | +PLUGIN_VERSION = "1.0.0" |
| 202 | + |
| 203 | +japanese_word_dict = { |
| 204 | + "application_name": "JEditor", |
| 205 | + "file_menu_label": "ファイル", |
| 206 | + "run_menu_label": "実行", |
| 207 | + "tab_name_editor": "エディタ", |
| 208 | + "language_menu_label": "言語", |
| 209 | + "language_menu_bar_english": "英語", |
| 210 | + "language_menu_bar_traditional_chinese": "繁体字中国語", |
| 211 | + "language_menu_bar_please_restart_messagebox": "アプリケーションを再起動してください", |
| 212 | + # ... more keys |
| 213 | +} |
| 214 | + |
| 215 | + |
| 216 | +def register() -> None: |
| 217 | + register_natural_language( |
| 218 | + language_key="Japanese", |
| 219 | + display_name="日本語", |
| 220 | + word_dict=japanese_word_dict, |
| 221 | + ) |
| 222 | +``` |
| 223 | + |
| 224 | +--- |
| 225 | + |
| 226 | +## Run Config (Execute Files) / 執行設定 |
| 227 | + |
| 228 | +Plugins can register a `PLUGIN_RUN_CONFIG` to enable running files from the **Run with...** menu. |
| 229 | + |
| 230 | +插件可定義 `PLUGIN_RUN_CONFIG`,讓使用者可以從 **以...執行** 選單執行檔案。 |
| 231 | + |
| 232 | +### Interpreted Languages / 直譯式語言 |
| 233 | + |
| 234 | +For languages that run directly (Go, Java 11+, Python): |
| 235 | + |
| 236 | +直接執行的語言(Go、Java 11+、Python): |
| 237 | + |
| 238 | +```python |
| 239 | +PLUGIN_RUN_CONFIG = { |
| 240 | + "name": "Go", # Display name in menu / 選單顯示名稱 |
| 241 | + "suffixes": (".go",), # Supported file types / 支援的副檔名 |
| 242 | + "compiler": "go", # Executable / 執行檔 |
| 243 | + "args": ("run",), # Args before file path / 檔案路徑前的參數 |
| 244 | +} |
| 245 | +# Runs: go run file.go |
| 246 | +``` |
| 247 | + |
| 248 | +### Compiled Languages / 編譯式語言 |
| 249 | + |
| 250 | +For languages that need compile-then-run (C, C++, Rust): |
| 251 | + |
| 252 | +需要先編譯再執行的語言(C、C++、Rust): |
| 253 | + |
| 254 | +```python |
| 255 | +PLUGIN_RUN_CONFIG = { |
| 256 | + "name": "C (GCC)", |
| 257 | + "suffixes": (".c",), |
| 258 | + "compiler": "gcc", |
| 259 | + "args": (), |
| 260 | + "compile_then_run": True, # Compile first, then run output / 先編譯再執行 |
| 261 | + "output_flag": "-o", # Flag for output binary / 輸出檔案的旗標 |
| 262 | +} |
| 263 | +# Compiles: gcc file.c -o file |
| 264 | +# Then runs: ./file (Linux/Mac) or file.exe (Windows) |
| 265 | +``` |
| 266 | + |
| 267 | +### Config Keys / 設定鍵值 |
| 268 | + |
| 269 | +| Key | Required | Description | |
| 270 | +|---|---|---| |
| 271 | +| `name` | Yes | Display name / 顯示名稱 | |
| 272 | +| `suffixes` | Yes | Tuple of file extensions / 副檔名元組 | |
| 273 | +| `compiler` | Yes | Compiler/interpreter executable / 編譯器或直譯器 | |
| 274 | +| `args` | No | Extra args before file path / 檔案路徑前的額外參數 | |
| 275 | +| `compile_then_run` | No | If `True`, compile first / 若為 `True` 則先編譯 | |
| 276 | +| `output_flag` | No | Output file flag (default `"-o"`) / 輸出旗標 | |
| 277 | + |
| 278 | +--- |
| 279 | + |
| 280 | +## Directory Structure / 目錄結構 |
| 281 | + |
| 282 | +``` |
| 283 | +working_directory/ |
| 284 | + jeditor_plugins/ |
| 285 | + my_syntax.py # Single-file plugin / 單檔插件 |
| 286 | + my_language.py |
| 287 | + my_package/ # Package plugin / 套件插件 |
| 288 | + __init__.py |
| 289 | +``` |
| 290 | + |
| 291 | +- Plugins are auto-discovered from `jeditor_plugins/` under the current working directory. |
| 292 | +- Files starting with `_` or `.` are ignored. |
| 293 | +- Each plugin must have a `register()` function. |
| 294 | + |
| 295 | +<!-- --> |
| 296 | + |
| 297 | +- 插件會從工作目錄下的 `jeditor_plugins/` 自動載入。 |
| 298 | +- 以 `_` 或 `.` 開頭的檔案會被忽略。 |
| 299 | +- 每個插件必須有 `register()` 函式。 |
| 300 | + |
| 301 | +--- |
| 302 | + |
| 303 | +## Existing Plugins / 現有插件 |
| 304 | + |
| 305 | +| Plugin | File | Type | Run Support | |
| 306 | +|---|---|---|---| |
| 307 | +| C Syntax Highlighting | `c_syntax.py` | Syntax (`.c`) | GCC compile & run | |
| 308 | +| C++ Syntax Highlighting | `cpp_syntax.py` | Syntax (`.cpp`, `.cxx`, `.cc`, `.h`, `.hpp`, `.hxx`) | G++ compile & run | |
| 309 | +| Go Syntax Highlighting | `go_syntax.py` | Syntax (`.go`) | `go run` | |
| 310 | +| Java Syntax Highlighting | `java_syntax.py` | Syntax (`.java`) | `java` | |
| 311 | +| Rust Syntax Highlighting | `rust_syntax.py` | Syntax (`.rs`) | rustc compile & run | |
| 312 | +| French Translation | `french.py` | Language | - | |
| 313 | + |
| 314 | +All plugins are located in `exe/jeditor_plugins/`. |
0 commit comments