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>
83 lines
3.1 KiB
Python
83 lines
3.1 KiB
Python
# Klammertext_align.py
|
|
#
|
|
# EXPERIMENTAL. Table alignment for Klammertext files — pads the cells of a
|
|
# klammer's rows so the | separators line up vertically. Counterpart of
|
|
# doc/edit/emacs/klammertext-align.el. This file is a separate unit: delete
|
|
# it (or move it out of the package folder) to disable alignment entirely.
|
|
#
|
|
# Command name (for keymaps / the command palette): klammertext_align_table
|
|
# Keybinding: Ctrl+Alt+A (in Default.sublime-keymap), scoped to Klammertext
|
|
# files. With the caret anywhere inside a @table span, the command aligns
|
|
# that table's rows:
|
|
#
|
|
# @table
|
|
# First item | Second | A third item that's longer ||
|
|
# Row 2 | Text | Not as long ||
|
|
# @
|
|
#
|
|
# The algorithm, its rules (rows end with ||; a row with a cell over
|
|
# CELL_MAX or spanning lines is untouched; beyond ROW_MAX columns nothing
|
|
# changes; only depth-0 bars are separators; no whitespace ever inside a bar
|
|
# run), and the policy lists (ALIGN_KLAMMERS, CELL_MAX, ROW_MAX) live in the
|
|
# shared core, doc/edit/shared/klammertext_edit.py. This file is only the
|
|
# Sublime command wrapper.
|
|
#
|
|
# The shared core is located next to this file (a vendored copy — the
|
|
# installed-package layout produced by doc/make_editing_zip.sh), or in
|
|
# ../shared (the repository layout), or under $KLAMMERTEXT_HOME.
|
|
|
|
import os
|
|
import sys
|
|
|
|
try:
|
|
import sublime
|
|
import sublime_plugin
|
|
_IN_SUBLIME = True
|
|
except ImportError: # standalone import outside Sublime Text
|
|
_IN_SUBLIME = False
|
|
|
|
|
|
def _import_shared():
|
|
here = os.path.dirname(os.path.abspath(__file__))
|
|
candidates = [here, os.path.join(os.path.dirname(here), 'shared')]
|
|
kh = os.environ.get('KLAMMERTEXT_HOME')
|
|
if kh:
|
|
candidates.append(os.path.join(kh, 'doc', 'edit', 'shared'))
|
|
for d in candidates:
|
|
if os.path.isfile(os.path.join(d, 'klammertext_edit.py')):
|
|
if d not in sys.path:
|
|
sys.path.insert(0, d)
|
|
break
|
|
import klammertext_edit
|
|
return klammertext_edit
|
|
|
|
|
|
KE = _import_shared()
|
|
|
|
|
|
if _IN_SUBLIME:
|
|
|
|
class KlammertextAlignTableCommand(sublime_plugin.TextCommand):
|
|
"""Align the columns of the table klammer containing the caret.
|
|
Bound to Ctrl+Alt+A."""
|
|
|
|
def run(self, edit):
|
|
view = self.view
|
|
s = view.substr(sublime.Region(0, view.size()))
|
|
pos = view.sel()[0].b if len(view.sel()) else 0
|
|
span = KE.enclosing_span(s, pos, KE.ALIGN_KLAMMERS)
|
|
if span is None:
|
|
sublime.status_message(
|
|
"Klammertext: the caret is not inside a table klammer (%s)"
|
|
% ", ".join("@" + name
|
|
for name in sorted(KE.ALIGN_KLAMMERS)))
|
|
return
|
|
_name, cs, ce = span
|
|
edits, msg = KE.compute_edits(s[cs:ce])
|
|
for a, b, new in sorted(edits, reverse=True):
|
|
view.replace(edit, sublime.Region(cs + a, cs + b), new)
|
|
sublime.status_message("Klammertext: " + msg)
|
|
|
|
def is_enabled(self):
|
|
return self.view.match_selector(0, "text.klammertext")
|