Editor support generalized: shared core, language server, Vim and VS Code (from dev eb5baf9cbe59)
doc/edit/ now holds a shared Python implementation of the language's structural layer (klammertext_edit.py) and a dependency-free language server (klammertext_ls.py), with integrations for Emacs, Sublime Text, Vim, and Visual Studio Code. The editor test suite in tst/ covers the core's API and CLI, the language server protocol, the VS Code extension, headless Vim, and Emacs byte-equality. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
85
doc/edit/README.md
Normal file
85
doc/edit/README.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Klammertext editor support
|
||||
|
||||
Editing support for Klammertext files (`.kt` documents and `.k` klammer
|
||||
definitions) in four editors, built around one shared implementation.
|
||||
|
||||
| Directory | Contents |
|
||||
|---|---|
|
||||
| `shared/` | **The shared editor core** (`klammertext_edit.py`) and the **Klammertext language server** (`klammertext_ls.py`). Everything structure-aware — indentation, table alignment, delimiter matching, delimiter diagnostics — implemented once, in dependency-free Python. |
|
||||
| `emacs/` | Emacs major mode. An independent elisp implementation of the same algorithms (Emacs cannot call Python per keystroke), held byte-equal to the shared core by the test suite. |
|
||||
| `sublime/` | Sublime Text package. Syntax file plus thin plugin wrappers that import the shared core directly (Sublime's plugin host is Python). |
|
||||
| `vim/` | Vim plugin. Syntax/ftplugin files plus commands that run the shared core's CLI; with `+python3`, the core also runs in-process (`=` operator, live match highlighting). |
|
||||
| `vscode/` | Visual Studio Code extension. TextMate grammar plus a dependency-free extension that spawns the language server and speaks LSP to it. |
|
||||
|
||||
## The architecture
|
||||
|
||||
Klammertext's *structural layer* — @-run tiers, bar-run dimension,
|
||||
`^`-escapes, `#` removal, literal spans, nesting depth — is independent of
|
||||
both the Klammermachine and any klammer set, and every editor needs the
|
||||
same operations on it. Those operations live in
|
||||
**`shared/klammertext_edit.py`**:
|
||||
|
||||
- **Indentation** — 2 spaces per nesting level; bar runs and closing
|
||||
delimiters sit at their opener's column; `@document` is transparent;
|
||||
verbatim/`@eval`/removed content is never touched. Explicit-only in
|
||||
every editor: whitespace is content in Klammertext.
|
||||
- **Table alignment** — pad a `@table`'s rows so the depth-0 `|`
|
||||
separators line up (rows end with `||`; cells over 30 characters or
|
||||
spanning lines opt their row out; over 100 columns the command declines;
|
||||
never a space inside a bar run).
|
||||
- **Delimiter matching** — open ↔ close for klammer applications, literal
|
||||
klammers matched by name with opaque content, everything else by depth.
|
||||
- **Diagnostics** — whole-buffer balance check over all three `@`-tiers:
|
||||
unclosed openings, extra closes, name and tier mismatches, unclosed
|
||||
literal spans and `#[` blocks.
|
||||
- **A CLI** (`indent | align | match | check` over stdin/stdout) for
|
||||
editors that shell out (Vim), and for scripts.
|
||||
|
||||
**`shared/klammertext_ls.py`** puts a language server in front of the same
|
||||
core: JSON-RPC over stdio, no dependencies. It serves publishDiagnostics,
|
||||
document/range formatting (reindentation), documentHighlight and
|
||||
definition (the matcher), and a `klammertext.alignTable` command. The
|
||||
VS Code extension is its first client; any LSP client works — Neovim's
|
||||
built-in LSP, Emacs eglot, Sublime's LSP package — with a one-line
|
||||
configuration pointing at `python3 klammertext_ls.py`.
|
||||
|
||||
Syntax highlighting and cursor-latency features stay native in each editor
|
||||
(a tokenizer or a per-keystroke matcher cannot round-trip to Python), so
|
||||
each editor directory carries its own syntax artifact and, where relevant,
|
||||
its own thin glue.
|
||||
|
||||
## Locating the shared core
|
||||
|
||||
The Sublime, Vim, and VS Code integrations find `klammertext_edit.py` (and
|
||||
VS Code additionally `klammertext_ls.py`) in this order: a copy at the
|
||||
integration's own root (the **editing zip** vendors one there, so each
|
||||
unpacked folder is self-contained), `../shared/` relative to the
|
||||
integration (this repository's layout — using an editor directory straight
|
||||
from a checkout just works), then `$KLAMMERTEXT_HOME/doc/edit/shared/`.
|
||||
|
||||
## Keeping things in sync
|
||||
|
||||
`klammertext_edit.py` is the source of truth for the policy lists
|
||||
(`LITERAL_KLAMMERS`, `TRANSPARENT_KLAMMERS`, `CODE_KLAMMERS`,
|
||||
`ALIGN_KLAMMERS`) and limits (`INDENT_OFFSET`, `CELL_MAX`, `ROW_MAX`).
|
||||
Two kinds of artifact cannot read it and restate parts of it by hand:
|
||||
|
||||
1. **The Emacs mode** — a full independent implementation with its own
|
||||
defcustoms, checked byte-for-byte against the shared core by
|
||||
`tst/editor_test.sh`.
|
||||
2. **The static syntax files** — the literal-klammer set (`@code`) appears
|
||||
in the Sublime `.sublime-syntax`, the Vim `syntax/klammertext.vim`, and
|
||||
the VS Code `tmLanguage.json` grammar (and the Emacs defcustom). When
|
||||
you add a literal klammer, change them together; each file's header
|
||||
carries the same SYNC note.
|
||||
|
||||
## Testing
|
||||
|
||||
`tst/editor_test.sh` (run by `dbg/rebuild.sh` and `make -C tst test`)
|
||||
drives the fixture pairs in `tst/editor/` through the shared core's API
|
||||
and CLI, checks idempotence, checks the Emacs implementation for
|
||||
byte-equality, runs the language server through a scripted LSP client
|
||||
(`ls_test.py`), exercises the VS Code extension against the real server
|
||||
under a stubbed VS Code API (`vscode_ext_test.js`), and runs the Vim
|
||||
plugin's commands headlessly. Emacs, Vim, and Node/VS Code halves skip
|
||||
gracefully where not installed.
|
||||
Reference in New Issue
Block a user