The @@@klammerset system command formally declares a klammerset — a named, logically related group of klammer definitions — with an operative, idempotent declaration (:requires and :files load in order at the declaration point, relative to the declaring file). A bare symbol given to ktext -k, kdesc --input, or :requires resolves to x/x.k on the search path: the document's directory, then KLAMMERTEXT_KLAMMERSETS, then KLAMMERTEXT_HOME; kdesc --klammerset lists the available sets. sks/sks.k is the first declared klammerset, so `-k sks` loads the SKS by name. The engine's lookup classes were renamed *_set → *_registry to keep the two concepts apart, and the whole C++ tree now follows standard const-correctness conventions. tst/ gains klammerset_test.sh (18 cases). (from dev 64b1abf23e56)
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;
@documentis 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 | checkover 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:
- The Emacs mode — a full independent implementation with its own
defcustoms, checked byte-for-byte against the shared core by
tst/editor_test.sh. - The static syntax files — the literal-klammer set (
@code) appears in the Sublime.sublime-syntax, the Vimsyntax/klammertext.vim, and the VS CodetmLanguage.jsongrammar (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.