turbo-editors/turbo-pythonpublic Fork 0
v1.0.0
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-python.git
git clone ssh://git@rickub.com/turbo-editors/turbo-python.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

summary.md · 143 lines · 11.3 KBmarkdown Blame HistoryRaw
📦 Turbo Python 6fc62ea k33g 11h ago1# turbo-python — summary
2
3A snapshot of the present. Edited in place; the history is in `history.md`.
4
5## What this is
6
7A Turbo C-style terminal IDE for Python, written in Go, built on
8**[turbo-core](https://rickub.com/turbo-editors/turbo-core)** — the library Turbo Go and
9Turbo Rust already share. This repository holds the command, the profile that says the
10editor is for Python, and the Python scanner. Everything else — the event loop, the
11windows, the dialogs, the themes, the LSP client, the terminal emulator, the project tree,
12the snippets and tools machinery — is the library's, and none of it is copied here.
13
14Module `rickub.com/turbo-editors/turbo-python`, `require`ing turbo-core **v0.4.1** from
15the module proxy with **no active `replace`**. The commented-out `replace` at the bottom of
16`go.mod` documents the escape hatch without being one; `01-release.tag.sh` refuses to tag a
17release whose `go.mod` carries a live one.
18
19## Layout
20
21| | |
22| --- | --- |
23| `main.go` | flags, the terminal, `pythonlang.Register()`, the profile, the loop |
24| `internal/pythonlang/pythonlang.go` | `Name`, `Slug`, `Language`, `Profile()`, `Register()`, the four server directories |
25| `internal/pythonlang/scan.go` | the scanner's dispatcher, comments, decorators |
26| `internal/pythonlang/literals.go` | strings — all six prefixes, both triple quotes, line continuations |
27| `internal/pythonlang/words.go` | numbers, keywords, soft keywords, the name-shape rules |
28| `internal/pythonlang/*.toml.tmpl` | the three starter files, embedded by `templates.go` |
29| `diagram_test.go` | holds `docs/diagrams/packages.drawio` to `go list` |
30| `docs/{en,fr}/` | 33 pages each (README included), Diátaxis |
31
32## How to build, test and measure
33
34```bash
35make check # fmt, vet, then the whole suite — what a commit should pass
36make build # into bin/turbo-python, then check the binary reports its version
37make install # build, install onto PATH, report what it found
38go test ./... # 129 tests; the pylsp ones skip themselves without a server
39```
40
41Quality gate, separate from the tests:
42
43```bash
44python3 ~/.claude/skills/quality/scripts/quality_report.py --workspace .
45```
46
47To build against a turbo-core you have changed but not released:
48
49```bash
50go work init . ../turbo-core
51go list -f '{{.Dir}}' rickub.com/turbo-editors/turbo-core/app # must NOT be under pkg/mod
52```
53
54`go.work` and `go.work.sum` are gitignored. **Everything still builds and still passes**
55while testing the published library instead of your changes, so run that second line.
56
57## Decisions in force
58
59- **The toolchain menu is `~P~ython`, not `uv`.** `P` is free — the fixed menus take F, E,
60 S, R, C, O, W, N and H. Named after the language because the menu holds whatever the
61 project put in its tools file, and a menu called `uv` holding `docker compose up` is a lie
62 about what the menu is.
63- **The language server is `pylsp`, and the install hint says `pipx install
64 "python-lsp-server[all]"`.** The `[all]` is load-bearing: installed bare, pylsp starts,
65 completes and jumps, and publishes an **empty** diagnostics list for a file that does not
66 parse, because the linters are extras. A gutter blank for want of a linter looks exactly
67 like a gutter blank for want of a bug.
68- **pylsp answers seven of turbo-core's nine questions.** It advertises neither
69 `implementation` nor `workspace/symbol`, so those two items report nothing found. That is
70 documented rather than worked around, and a test asserts it so a future pylsp gaining them
71 is noticed.
72- **`Profile()` is a function, not a variable**, because `Server.Dirs` reads the
73 environment, and a variable would freeze whatever `VIRTUAL_ENV` said at link time — for a
74 Python tool, the one value most likely to change between two runs in the same shell.
75- **Four places are searched for the server besides `PATH`**: the active virtual
76 environment's `bin`, `~/.local/bin`, pyenv's shims, and every
77 `~/Library/Python/<version>/bin` that exists. The last is read rather than guessed, and is
78 on nobody's `PATH` on macOS.
79- **Root markers, in order: `pyproject.toml`, `setup.py`, `setup.cfg`.**
80- **A name wholly in capitals is a constant; any other capitalised name is a type.** Turbo
81 Rust has only the second rule and documents `SCREAMING_SNAKE_CASE` as a known wrong
82 answer; PEP 8 separates the two conventions well enough that the wrong answer was worth
83 removing rather than inheriting. The cost is a class named `HTTP`.
84- **A capitalised name is a type even when it is called.** `ValueError("nope")` and
85 `parse("nope")` are the same shape. This is the one rule Turbo Python and Turbo Rust order
86 differently, on purpose.
87- **`self` and `cls` are coloured as builtins** although the language does not name them.
88- **An f-string is one string span**, `{…}` included. Finding where an expression ends
89 inside a literal needs a parser; this is a scanner.
90- **The starter templates are embedded files, not Go constants**, with the `.tmpl` suffix
91 because `settings.toml.tmpl` holds `theme = %q`, which is not valid TOML.
92- **`autosave = true` in the starter settings file, `false` in `settings.Default()`.** Two
93 statements in two places on purpose: a project that created a settings file has said what
94 it wants; a directory somebody merely started the editor in has not.
95- **Agent windows are turbo-core's, and what belongs here is the starter file.** `acp.toml.tmpl` is the fourth embedded template, and `profile.Templates.Agents` is the whole of Turbo Python's contribution to the feature. The example agent is `docker agent serve acp .turbo-python/agent.yaml`; the only other thing about this editor in it is the sentence saying a ```python fence is coloured by the scanner this editor colours its own files with. Every other editor got agent windows the same way — one file, one line. The reasoning, and why it could not have been built here, is in `docs/*/explanation/agent-windows.md`.
96- **The starter agents file teaches the window's keyboard as well as the format.** `Enter`, `Alt-Enter`, `Tab`, `Esc`, `Ctrl-W` and the copying keys are all in its comments, because a file the editor hands you is the one document a user is guaranteed to see.
97
98## State as of 2026-09-03
99
100- **Complete and green.** `go test ./...` passes; `gofmt -l` and `go vet` are clean.
101- **Quality gate: PASS.** 0 errors, 0 warnings, 0 smells; total complexity 91.
102- **Documentation**: 33 files × EN + FR (32 pages plus each language's README), a `README.md` at the root, and
103 `docs/diagrams/packages.drawio` checked against `go list` by `diagram_test.go`.
104- **Verified in a real pty**, not only by tests: the Python menu under `Alt-P` with
105 `Create tools file` available (`30;42`) and `Open tools file` greyed (`90;47`); `def`
106 `97;44;1`, a called name `93;44;1`, `print` `96;44;1`, strings `92;44`, comments
107 `38;2;143;143;143`; a triple-quoted f-string carried across a line break; the About box
108 reading **"A Turbo C-style editor for Python, / written in Go."**; `Ctrl-Y` deleting a
109 line; the theme dialog opening on the current theme; and — the one that matters —
110 **a file that does not parse, opened by a relative path, showing `×` in the gutter and
111 `⚠ invalid syntax` on the status bar**, which is the failure mode Turbo Go shipped with
112 for months.
113- **The server is found outside `PATH`.** Verified by running the binary with `PATH`
114 stripped to `/usr/bin:/bin`: it still said `LSP: ready`, from `~/.local/bin`. With `HOME`
115 moved too it says `LSP: no pylsp — pipx install "python-lsp-server[all]"`.
116- **The editor is registered in the family.** turbo-core's `README.md`, both doc `README`s,
117 `profile/profile.go`'s package comment, the release and workspace how-tos in both
118 languages, both architecture explanations and `.memory/summary.md` now count three
119 editors. turbo-core's `.go` strings were swept for hardcoded language names; every hit was
120 a false positive, a doc-comment example, or a true statement about the implementation.
121- **Released as `v0.1.0`**, tagged and pushed at `bccbb0b` on `main`, working tree clean.
122 turbo-core was tagged `v0.4.1` the same day — a docs-and-comment release, no behaviour
123 change — and all three editors now pin it.
124
125## Not yet established
126
127- **Agent windows have never been opened in this editor.** The feature is turbo-core's and was driven end to end from turbo-go against a real `docker agent` and a real llama.cpp; what is here is the starter file, covered by tests that create it, load it back and check it names this editor's own language. Nobody has run `turbo-python`, pressed `Alt-A` and talked to an agent from it.
128
129
130- **Never run on macOS or Windows.** Everything here was verified on Linux. The user's
131 machine is macOS, so a binary built in this sandbox is an ELF they cannot run.
132- **No CI.** There is no pipeline configuration in the repository.
133- **The release scripts have never been run from this sandbox.** `v0.1.0` exists, tagged by the user; `01`–`04` have only ever been read here.
134- **Performance on a large file is unmeasured.** The scanner is a line at a time and carries
135 three pieces of state, but nothing has been timed.
136- **Only pylsp has been tried.** pyright and ruff-lsp would both fit the profile; neither
137 has been pointed at.
138
139## State as of 2026-09-19 — moved to Rickub, released by a workflow
140
141- **Module path `rickub.com/turbo-editors/turbo-python`**, depending on `rickub.com/turbo-editors/turbo-core v1.0.0` — the first turbo-core version published under that path (`v0.9.0` on the proxy still declares the Codeberg path and cannot be required as `rickub.com/…`). Every import, the Makefile's `VERSION_PKG`, `scripts/install.sh`, the README and the docs say `rickub.com`. `GOWORK=off make check` green. The repository on this side is a fresh `git init` with `origin` at `ssh://git@rickub.com/turbo-editors/turbo-python.git` and **no commit yet**; `01-release.tag.sh` makes the first one.
142- **Releases are one script and one workflow**, modelled on turbo-core's and identical to turbo-go's. `01-release.tag.sh` runs `make check` under `TURBO_PYTHON_RELEASING=1`, refuses a tag taken locally or on origin (bump, never move), refuses a `replace` in `go.mod`, commits, pushes the current branch, then tags and pushes the tag. That push starts `.github/workflows/release.yml`: `go test` with `TURBO_PYTHON_RELEASING=1`, `./02-build-releases.sh "${GITHUB_REF_NAME}"`, release notes from the tag message, a run artifact, then `softprops/action-gh-release@v2` attaching `turbo-python-*`, `SHA256SUMS` and `README.md` with the job's own `GITHUB_TOKEN` — the only credential Rickub's release API accepts. **`02-release.publish.sh` and `04-release.upload-binaries.sh` are gone**; the build script is now `02-build-releases.sh`, takes the tag as `$1` (CI has no `release.env`), validates it, refuses a `replace`, and starts from an empty `release/${TAG}/`. `release.env` holds only `TAG` and `ABOUT`; `turbo-python.token.env` is read by nothing.
143- **`release_test.go`** runs `01` for real against a throwaway bare remote (publishes, then refuses the same tag), runs `02` alone to see it refuse `v0.o.0`, and asserts the workflow's trigger, `contents: write`, `./02-build-releases.sh`, `fail_on_unmatched_files`, docs linked at the tag, no `secrets.`, and `TURBO_PYTHON_RELEASING`. The copy of the module for the clone leaves out `.git`, `bin`, `release`, `kits`, `demo`, `demos`, `*.env` and `go.work*`; children run with `GOWORK=off`.