Files
klammertext/doc/edit/sublime/Klammertext.sublime-syntax

188 lines
8.7 KiB
Plaintext
Raw Normal View History

%YAML 1.2
---
# Klammertext.sublime-syntax
#
# Sublime Text syntax highlighting for Klammertext (.kt and .k files).
# A port of the Emacs major mode doc/edit/emacs/klammertext-mode.el.
#
# ---------------------------------------------------------------------------
# What it highlights (mirrors the Emacs mode's eight token classes):
#
# Text removal (#):
# # ... remove to end of line (marker + removed text)
# ## ... remove to end of file (marker + removed text)
# #[ ... ]# remove enclosed text, nestable (markers + removed text)
# #- #+ #/ whitespace operators: NOT removals, left unhighlighted
# (matched only so the '#' above does not eat the line)
#
# Klammer applications (@), definitions (@@), system commands (@@@):
# @name @@name @@@name opening (@ and name are one unit)
# name@ name@@ name@@@ named closing
# @ @@ @@@ bare closing
#
# Escapes: ^@ ^# ^| ^^ the caret makes the next character literal, so it
# is consumed and NOT treated as a delimiter. Left unscoped, to
# match the Emacs mode, which shows escaped characters as ordinary
# text. (A run of carets pairs left-to-right: ^^ is a literal
# caret, a leftover single ^ escapes the following character —
# the '\^.' rule reproduces exactly that parity.)
#
# Literal klammers: @code ... code@ interior is verbatim (no # or @
# interpreted). To add another literal klammer 'foo', copy the
# '@code' rule and the 'literal_code' context below, replacing
# code -> foo.
#
# SYNC: the literal-klammer set's source of truth is
# LITERAL_KLAMMERS in doc/edit/shared/klammertext_edit.py (the
# shared core all the Python-side integrations import). A static
# syntax file cannot read it, so when you add or remove one,
# mirror it in the per-editor artifacts:
# * klammertext-literal-klammers in
# doc/edit/emacs/klammertext-mode.el
# * the @NAME rule + literal_NAME context here
# * the @NAME verbatim region in doc/edit/vim/syntax/klammertext.vim
# * the @NAME rule in
# doc/edit/vscode/syntaxes/klammertext.tmLanguage.json
# All are currently seeded with just 'code'.
#
# ---------------------------------------------------------------------------
# How open vs. close is decided (the same rule the Emacs scanner uses):
# * a delimiter whose NAME follows the @-run (@name) is an OPENING;
# * a bare @-run, or one whose NAME precedes it (name@), is a CLOSING.
# Because this tokenizer runs left-to-right, an opening consumes "@name" as one
# unit, so a trailing bare @ in the compact form @name@ is naturally a close.
# The (?![A-Za-z0-9_@]) look-ahead on every closing keeps "foo@bar" correct:
# @ is followed by a name, so it opens @bar and 'foo' stays plain text.
#
# ---------------------------------------------------------------------------
# Scope -> color. Colors live in the color scheme, not here. The package ships
# additive .sublime-color-scheme overrides for all five of Sublime's built-in
# schemes (Breakers, Celeste, Mariana, Monokai, Sixteen); each merges onto its
# scheme by filename and recolors only .klammertext scopes. They use one hue
# system — application blue, definition green, system orange, each opening bright
# and its close the same hue darker — shown at full intensity on dark grounds and
# scaled down on light grounds. Exact values are in each override's header.
#
# Without a matching override (e.g. a third-party scheme) a stock scheme still
# gives a meaningful default from these scope names: three klammer-family colors
# (function / storage / keyword), muted removed text (comment), plain escapes.
# To get the full palette on another scheme, copy one of the shipped overrides
# to <SchemeName>.sublime-color-scheme.
#
# ---------------------------------------------------------------------------
# Install: put this file — together with its companions Klammertext.py,
# Default.sublime-keymap and Comments.tmPreferences — in a dedicated package
# folder named 'Klammertext' under Packages/ (Preferences -> Browse Packages
# opens Packages/):
# ~/.config/sublime-text/Packages/Klammertext/ (Linux)
# ~/Library/Application Support/Sublime Text/Packages/Klammertext/ (macOS)
# A dedicated folder (not Packages/User/) keeps the bundled keymap from
# merging into your personal one. Sublime picks it all up live and applies
# the syntax to .kt and .k files. (The syntax file alone also works from
# Packages/User/ if you only want highlighting.)
#
# ---------------------------------------------------------------------------
# Known differences from the Emacs mode (deliberate, matching its own limits):
# * @@ and @@@ definition BODIES are highlighted as ordinary Klammertext,
# not treated specially — same as the Emacs mode.
# * Delimiter MATCHING (jump + live highlight) is not in this syntax file —
# Sublime's built-in bracket matching needs fixed character pairs, which @
# (both open and close, decided by context) cannot provide. It lives in
# the companion Klammertext.py instead: klammertext_jump_to_match (C-c C-j
# equivalent) and a ViewEventListener that highlights the matching
# delimiter as the caret moves (show-paren equivalent), both reusing one
# context-sensitive matcher. This is a plugin concern, not a tokenizer one.
# * Comment toggling is provided by the companion Comments.tmPreferences:
# Ctrl-/ inserts '# ' (line removal), Ctrl-Shift-/ wraps in '#[ ... ]#'
# (block removal).
name: Klammertext
file_extensions:
- kt
- k
scope: text.klammertext
version: 2
variables:
# A klammer name: letters, digits, underscore. A hyphen is NOT a name char
# (the abbreviated form @name-arg1-arg2 ends the name at the first hyphen).
name: '[A-Za-z0-9_]+'
# A closing delimiter must not be followed by a name char (that would be an
# opening @name) or another @ (that would be a longer @-run).
not_delim: '(?![A-Za-z0-9_@])'
contexts:
main:
# --- escapes: ^X makes X literal; consumed so # / @ are not delimiters ---
- match: '\^.'
# --- text removal (#) ---
- match: '##'
scope: punctuation.definition.comment.klammertext
push: removal_file
- match: '#\['
scope: punctuation.definition.comment.klammertext
push: removal_block
# whitespace operators #- #+ #/ (with optional count): not removals.
# Matched (and left unscoped) so the '#' line rule below does not consume
# the rest of the line. Add a scope here if you would rather color them.
- match: '#[-+/]\d*'
- match: '#'
scope: punctuation.definition.comment.klammertext
push: removal_line
# --- literal klammer: interior is verbatim (seeded default: @code) ---
- match: '@code(?![A-Za-z0-9_])'
scope: entity.name.function.begin.klammertext
push: literal_code
# --- system / target commands @@@ ---
- match: '@@@{{name}}'
scope: keyword.control.begin.klammertext # @@@name opening
- match: '@@@{{not_delim}}'
scope: keyword.control.end.klammertext # bare @@@ close
- match: '{{name}}@@@{{not_delim}}'
scope: keyword.control.end.klammertext # name@@@ named close
# --- klammer definitions @@ ---
- match: '@@{{name}}'
scope: storage.type.begin.klammertext # @@name opening
- match: '@@{{not_delim}}'
scope: storage.type.end.klammertext # bare @@ close
- match: '{{name}}@@{{not_delim}}'
scope: storage.type.end.klammertext # name@@ named close
# --- klammer applications @ ---
- match: '@{{name}}'
scope: entity.name.function.begin.klammertext # @name opening
- match: '@{{not_delim}}'
scope: entity.name.function.end.klammertext # bare @ close
- match: '{{name}}@{{not_delim}}'
scope: entity.name.function.end.klammertext # name@ named close
# rest of line is removed
removal_line:
- meta_scope: comment.line.klammertext
- match: '\n'
pop: true
# rest of file is removed (## never closes)
removal_file:
- meta_scope: comment.block.klammertext
# #[ ... ]# removed, nestable
removal_block:
- meta_scope: comment.block.klammertext
- match: '#\['
scope: punctuation.definition.comment.klammertext
push: removal_block
- match: '\]#'
scope: punctuation.definition.comment.klammertext
pop: true
# @code ... code@ — interior verbatim (unscoped), only the close ends it
literal_code:
- match: 'code@'
scope: entity.name.function.end.klammertext
pop: true