Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,10 @@ Workspace rule shared by every repository under `D:\Codes` (full text: `D:\Codes

- Run PyBreeze's tests as `pytest test/test_utils`. A bare `pytest` or `pytest test` also collects
`test/unit_test/start_automation`, which launches the app and ends in "no output, exit 0".
- **PyBreeze pins JEditor's shapes in its own `test/test_utils/test_jeditor_contract.py`**: parameter
lists, private names and fragments of source. Adding even an optional parameter to a method it
pins fails there, and nothing in this repository notices. After any change to a class or function
PyBreeze could see, run that file against this tree — from PyBreeze,
`PYTHONPATH=<this repository> pytest test/test_utils/test_jeditor_contract.py` — and judge the
result against the same run on the commit before, since PyBreeze's own environment has failures
of its own.
47 changes: 47 additions & 0 deletions PROGRESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,50 @@
`# 初始化並記錄日誌` 被當成「註解掉的程式碼」。這是本專案雙語註解的正常寫法,不該刪。
要清掉這一項得在 SonarCloud 把 issue 轉成 False Positive(用 API 改狀態需要 Administer
Issues 權限)。
- **#21** 〔未確認〕整套測試在機器忙碌時偶爾被 Qt 中止(`Fatal Python error: Aborted`,結束代碼 3)。
2026-10-08 看到兩次,都是主工作樹裡同時還有別的 pytest 行程在跑的時候;其中一次留有紀錄,停在
`test_toolbar_actions.py::TestTheBranchScan::test_a_subdirectory_still_finds_the_repository` 的 setup,
pytest-qt 的 `_process_events` 裡。在獨立的工作樹各跑三次(`132246e` 與診斷那次修改)六次都通過,
所以不是那次修改造成的。還沒用 `pytest -s` 抓到 Qt 的訊息,不知道是哪個物件。
同一天 CI 也有一次:`45655aa` 的 Python 3.10 那一格在單元測試那一步以結束代碼 1 失敗(是測試失敗,不是當掉),
3.11 ~ 3.14 通過;下一個 commit `d4c8f27`(同一份程式碼加一個小修正)五個版本都通過,在本機以 Python 3.10.22
跑同一份程式碼兩次也都通過(2654 passed)。那一格的記錄檔要登入才看得到,所以不知道是哪個測試。
另外,U-20261008-08 找到並修掉了這一類問題的其中一個成因(走訪所有元件時發生垃圾回收),
但那個的表現是當掉,跟這裡的兩種都不一樣。

### 下一代編輯器藍圖(`docs/roadmap/2026-editor-next.md`,PR #270)

M0(`je_editor/core/` 服務層)、M2(診斷模型與 Tree-sitter 語法引擎)、M3(工作區與多根專案)、M5(AI 供應者)已完成,M4(DAP 除錯)已完成,見 `docs/updates/2026-10.md`。
以下依相依關係排序。

- **#9** M1(UI 重新設計、指令與快捷鍵、語系補齊)。可以先做不改變外觀的部分:每個指令有不隨翻譯
變動的 ID。語系那一項大部分已經有了:四份字典的鍵與佔位符的 parity、空白值、退回英文都
由 `test/test_languages.py` 在 CI 守著;還沒做的是「語系載入改成資料驅動」。〔決定〕UI 的版面方向
(活動列、編輯區、側邊面板、底部面板)要先定,才能動視窗層。
- **#23** M2 沒有涵蓋的部分(語法引擎與高亮已完成,見 U-20261008-08):語法樹目前只用來上色。大綱
(`utils/symbols`)、折疊(`utils/code_folding`)與智慧選取(`utils/selection`)仍然用各自的分析,
還沒有改用 `SyntaxSession.regions()`;編輯器是直接向引擎要 session,沒有經過 `DocumentStore`,
所以 `SyntaxLanguageService` 只有宿主程式自己開文件時才用得到;`LspClient` 也還沒有包成
`LanguageService`。支援的語言只有 Python、JavaScript、JSON,其餘仍用關鍵字表。
- **#24** 升級 `tree-sitter` 之前要重新確認:0.26.0 的 `Point.row` / `Point.column` 每讀一次就少算
那個整數一次參考(Python 3.11 上讀幾萬次後行程當掉),引擎因此一律以索引讀取位置,
`test_syntax_engine.py::TestTheBindingIsUsedSafely` 守著。這個問題還沒有回報給上游(這台機器沒有
`gh`)。另外 `tree-sitter-json` 0.24.8 自帶的高亮查詢是照「先寫的規則優先」排的,跟 Python、
JavaScript 的文法相反,所以 `queries/json/highlights.scm` 重新指定了鍵;文法升級後可能不再需要。
- **#22** M3 沒有涵蓋的部分(工作區本身已完成,見 U-20261008-07):執行程式、測試面板、終端機、Git
工具列與 Python 直譯器(venv)仍然只認主要的根目錄,也就是工作目錄。藍圖要的「每個根目錄有自己的
語言 / 工具設定與環境」還沒做;Git 面板也還沒有依根目錄切換。
- **#25** M4 沒有涵蓋的部分(除錯服務與除錯面板已完成,見 U-20261008-11、-12):pdb 主控台還留著當
debugpy 沒有登記時的退路,要等確認每一種發佈方式(含打包成執行檔,那時 `sys.executable` 不是直譯器)
都帶得到 debugpy 之後才能拿掉;例外中斷目前固定只停在未捕捉的例外,沒有做設定;沒有監看式、
沒有滑鼠停在變數上顯示值;中斷點的條件與 `BreakpointStatus`(轉接器說某個中斷點沒設上)還沒有顯示在
行號區;執行程式(非除錯)仍然走 `BaseProcessManager`,還沒有改用 `TaskRunner`。
- **#14** M6(遠端開發)。實作 `RemoteSession`,並補上遠端檔案系統、連接埠轉送、直譯器探索的介面。
〔決定〕第一個傳輸是不是 SSH(PR #270 的審查問題 3)。
- **#15** M7(可嵌入元件)。`import je_editor.core` 不再載入 Qt(頂層 `__init__` 要改成延後匯入);
搬動 `pyside_ui/` 底下不含 Qt 的模組時,保留 PyBreeze 以模組路徑匯入的名稱
(`test/test_public_api_contract.py` 列著)。
- **#16** M8(教學文件)。相依 M7。
- **#17** 〔決定〕PR #270 的審查問題 1、5 還沒有答覆:里程碑是否都以 `dev` 為整合分支、哪些里程碑要
另開追蹤 issue。M0 目前直接提交在 PR #270 的分支 `roadmap/editor-next` 上;PR 的描述仍寫著
「這個 PR 不含實作」,要改。
59 changes: 49 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ same picker back into command mode.
`ruff` runs on the **buffer** rather than the file on disk, on a worker thread once typing pauses, so
unsaved edits are covered and a stale result from a superseded run is discarded. Findings are
underlined in place and listed in the Problems panel, where **Apply Fixes** applies everything ruff
can fix by itself.
can fix by itself. A language server's diagnostics land in the same list, and the panel filters both
by severity (Error, Warning, Information, Hint) and by source.

<p align="center">
<img src="image/screenshot-problems-panel.png" alt="Problems panel listing ruff diagnostics"/>
Expand Down Expand Up @@ -245,7 +246,7 @@ window never leaves you with dark-theme syntax colours.
| **Execution** | Run Python scripts (F5), debug mode (F9), shell commands, virtual environment detection |
| **Code Quality** | YAPF formatting, format on save, PEP8 checking, Ruff linting with a problems panel, language-server diagnostics and quick fixes, pytest panel with tracebacks and coverage, JSON reformatting |
| **Git** | Branch management, commit history, side-by-side diff viewer, gutter change markers, per-change staging and revert, inline blame, stash, conflict resolution, audit logging |
| **AI** | OpenAI GPT integration via LangChain, interactive chat widget, configurable models & prompts |
| **AI** | Chat panel with interchangeable providers: OpenAI-compatible endpoints (LangChain) and Anthropic (streamed), per-provider models, keys & prompts |
| **Console** | Interactive shell, Jupyter/IPython console, command history, multi-shell support |
| **Browser** | Embedded web browser, URL navigation, in-page search |
| **Plugins** | Custom syntax highlighting, UI translations, run configurations, auto-discovery |
Expand Down Expand Up @@ -295,7 +296,10 @@ Core dependencies are installed automatically:
| jedi | Python auto-completion & analysis |
| ruff | Fast Python linter |
| gitpython | Git repository operations |
| langchain_openai + langchain_core | AI/LLM integration |
| langchain_openai + langchain_core | OpenAI-compatible AI provider |
| anthropic | Anthropic AI provider |
| tree-sitter + tree-sitter-python / -javascript / -json | Syntax parsing for highlighting |
| debugpy | Python debug adapter (Debug Adapter Protocol) |
| watchdog | File system monitoring |
| pycodestyle | PEP8 style checking |
| qtconsole | Jupyter/IPython console widget |
Expand All @@ -320,14 +324,33 @@ start_editor()

The editor launches maximized with a dark amber theme by default.

The parts of the editor that are not widgets — the workspace, open documents and diagnostics, plus
the interfaces for language services, debugging, task execution, remote sessions and AI providers
— live in `je_editor.core` and need no window:

```python
from je_editor.core import Diagnostic, EditorServices, Severity, TextRange, Workspace, to_uri

services = EditorServices(Workspace.single_root("my_project"))
uri = to_uri("my_project/main.py")
services.diagnostics.publish("ruff", uri, [
Diagnostic("`os` imported but unused", TextRange.from_lines(1, 8), Severity.WARNING, code="F401"),
])
print(services.diagnostics.counts()[Severity.WARNING]) # 1
services.shutdown()
```

This layer is the foundation of the next-generation editor; the editor window does not consume it
yet. See the *Core Services* page of the [documentation](https://je-editor.readthedocs.io/en/latest/).

---

## Feature Details

### Code Editing

- **Multi-tab editor** -- Work on multiple files simultaneously with closable tabs.
- **Syntax highlighting** -- Built-in Python highlighting with extensible plugin support for additional languages.
- **Syntax highlighting** -- Python, JavaScript and JSON are coloured from a real parse (Tree-sitter) that follows each edit, so function and type names, f-string expressions and multi-line strings come out right. Other languages use keyword tables, and plugins add more.
- **Auto-completion** -- Context-aware code suggestions powered by Jedi.
- **Line numbers** -- Displayed alongside the editor with current line highlighting.
- **Search & Replace** -- Search within the current file, across folders, or project-wide with regex and case-sensitive options. Runs in background threads for large projects.
Expand Down Expand Up @@ -365,7 +388,7 @@ The editor launches maximized with a dark amber theme by default.
### Code Execution & Debugging

- **Run Python scripts** (F5) -- Execute the current file with real-time output streaming.
- **Debug mode** (F9) -- Launch the Python debugger for step-through debugging, with breakpoints toggled from the gutter (`Ctrl+F9`).
- **Debug mode** (F9) -- Debug through the Debug Adapter Protocol (debugpy): a Debug Panel with threads, the call stack, variables you can open, expression evaluation and the program's output; the stopped line is marked in the editor. Breakpoints are toggled from the gutter (`Ctrl+F9`) and can carry a condition, and a program started with `debugpy --listen` can be attached to.
- **Shell commands** -- Execute arbitrary shell/terminal commands from within the editor.
- **Virtual environment detection** -- Automatically detects and activates Python virtual environments.
- **Process management** -- Stop individual or all running processes.
Expand All @@ -387,6 +410,7 @@ The editor launches maximized with a dark amber theme by default.

- **Create, open, save** files with standard shortcuts (Ctrl+N, Ctrl+O, Ctrl+S).
- **Open folders** (Ctrl+K) -- Navigate project directory structures.
- **Multi-root workspace** -- Add more folders beside the project (File → Add Folder to Workspace). Quick open, the TODO and Problems panels, project search and language servers then cover every folder, and same-named files in different folders stay apart.
- **Auto-save** -- Automatic periodic file saving to prevent data loss.
- **Session restore** -- Reopens every file that was open at the last shutdown, not just the last one. Missing, duplicate and already-open files are skipped, the list is capped, and a corrupt or hand-edited settings file can never block startup. Disable by setting `restore_session` to `false` in `.jeditor/user_setting.json`.
- **Multi-encoding** -- Seamlessly handle UTF-8, GBK, Latin-1, and other encodings with automatic detection.
Expand All @@ -405,10 +429,17 @@ The editor launches maximized with a dark amber theme by default.

### AI Assistant

- **OpenAI models via LangChain** -- Connect to OpenAI's language models.
- **Interactive chat widget** -- Conversational AI panel within the editor.
- **Configurable models** -- Set custom API keys, endpoints, model names, and system prompts.
- **Async messaging** -- Non-blocking AI interaction using a message queue.
- **Interchangeable providers** -- The chat panel talks to whichever provider is selected: any
OpenAI-compatible endpoint through LangChain, or Anthropic through its official SDK. A plugin can
register another one without touching the panel.
- **Conversations, not single prompts** -- Follow-up questions carry the conversation so far; **New
chat** starts over.
- **Streaming and cancelling** -- Anthropic replies appear as they are generated, and **Stop** cancels
a request in flight.
- **Per-provider settings** -- Each provider keeps its own API key, endpoint, model and system prompt.
Settings apply to the session and are only written to disk when you tick the box.
- **Never blocks the window** -- Requests run on a background thread; failures are explained in a
dialog and token usage is shown when the provider reports it.

### Console & REPL

Expand Down Expand Up @@ -540,6 +571,11 @@ je_editor/
│ ├── dialog/ Search & replace, shortcuts, snippets, file dialogs
│ ├── git_ui/ Git client, commit graph, diff viewers
│ └── main_ui/ Main window, menus, toolbar, panels, settings, AI, console
├── core/ Service layer, no Qt: workspace, documents, diagnostics, and the
│ interfaces for language services, debugging, tasks, remote and AI
├── adapters/ Implementations of those interfaces, no Qt: the AI providers, the
│ Tree-sitter syntax engine, the local task runner and the DAP
│ debug session
├── code_scan/ Ruff execution and watchdog file monitoring
├── git_client/ Git operations (GitPython + git CLI)
├── plugins/ Plugin registry and loader
Expand All @@ -552,6 +588,9 @@ manager in `pyside_ui/` wires it to widgets. Folding, for example, is `utils/cod
`pyside_ui/code/folding/`. That is why most of the behaviour above can be tested without opening a
window.

`core/` sits between the two: it composes that logic into services a host application can use
without the JEditor window. A test walks its import graph and fails on any Qt import beneath it.

A module-by-module reference — what every file does, the threading model, the global singletons and
the settings layout — is kept in **[`architecture_explore.md`](architecture_explore.md)**.

Expand Down Expand Up @@ -635,7 +674,7 @@ JEDITOR stores user settings in a `.jeditor/` directory inside the working direc
| `user_setting.json` | General preferences (font, theme, language, recent files, open tabs, reassigned shortcuts) |
| `user_color_setting.json` | Editor and output colours, including syntax highlighting |
| `snippets.json` | Your own snippets, merged over the built-in sets |
| `ai_config.json` | AI assistant settings — read at startup, never written; create it yourself |
| `ai_config.json` | AI assistant settings, grouped by provider — written only when you tick saving in the AI settings dialog, since it holds the key as plain text |

Each file is backed up to `<name>.bak` before it is rewritten.

Expand Down
Loading