Windows: product names, the editors, WSL; the Linux page's image step

Assembled from development commit c3c40f6c8fca. Since 830b193: on Windows the
products carry Windows names (ktext.exe, klammertext.dll, document.dll,
reflect.dll) and the console's output code page is UTF-8 for a run; the
editor tooling works on Windows (VS Code, Sublime Text, Vim, with the
interpreter's name chosen by platform) and Notepad++ joins it
(doc/edit/notepadpp: a User Defined Language and two Run-menu commands);
a sixth install page, doc/install/windows_wsl_install.md, for Linux
inside WSL; the Windows page opens with the three routes and gains its
editor section, the PowerShell quoting and Path notes; the Linux page
installs OpenImageIO from the python3-openimageio package and verifies
with kdiag --machine; the README lists all six install pages. Linux and
macOS behaviour is unchanged.
This commit is contained in:
ack committed 2026-09-25 18:43:22 +02:00
1 parent 830b19394d
commit ee8bcf5300
33 files changed
+741 -122

No files matched your search

+3 -1
View File
@@ -62,7 +62,9 @@ def main():
out = run_cli(script, ['align', str(line), str(col)], s)
else:
sys.exit("editor_driver.py: unknown mode: " + mode)
with open(outfile, 'w') as f:
# newline='': the core's "\n" reaches the file untranslated on every
# system (text mode would write CRLF on Windows, against LF fixtures).
with open(outfile, 'w', newline='') as f:
f.write(out)
# Error and diagnostics paths.
+3 -1
View File
@@ -81,7 +81,9 @@ const vscodeStub = {
Uri: { parse: (s) => ({ toString: () => s }) },
DiagnosticSeverity: { Error: 0, Warning: 1 },
workspace: {
getConfiguration: () => ({ get: (k) => (k === 'pythonPath' ? 'python3' : '') }),
// Both settings blank: the extension's own defaults are what is tested
// (python3, on Windows python; the server located by the search chain).
getConfiguration: () => ({ get: () => '' }),
textDocuments: [fakeDoc],
onDidOpenTextDocument: (fn) => { listeners.open.push(fn); return { dispose() {} }; },
onDidChangeTextDocument: (fn) => { listeners.change.push(fn); return { dispose() {} }; },
+50 -8
View File
@@ -59,6 +59,17 @@ FIX="$HERE/editor"
OUT="$(mktemp -d)"
trap 'rm -rf "$OUT"' EXIT
# A path written INSIDE a Python string must be one the interpreter can open.
# Under MSYS2 the shell's /c/... form is converted only for standalone
# arguments to a native program, never inside a string, so those get the
# Windows form (forward slashes; a backslash in a Python literal is an escape).
native() {
if command -v cygpath >/dev/null 2>&1; then cygpath -m "$1"; else printf '%s' "$1"; fi
}
SHARED_NATIVE="$(native "$SHARED_DIR")"
SUBLIME_NATIVE="$(native "$SUBLIME_DIR")"
OUT_NATIVE="$(native "$OUT")"
INDENT_FIXTURES="indent_list indent_document indent_table indent_untouched
indent_defs indent_escapes indent_named_close indent_literal_c"
ALIGN_FIXTURES="align_mixed align_empty_cells align_boundary align_colspan
@@ -105,10 +116,10 @@ fi
# --- the Sublime adapters resolve to the shared core -----------------------
if PYTHONDONTWRITEBYTECODE=1 "$PYTHON" -c "
import sys
sys.path.insert(0, '$SUBLIME_DIR')
import os, sys
sys.path.insert(0, '$SUBLIME_NATIVE')
import Klammertext, Klammertext_indent, Klammertext_align
assert Klammertext.KE.__file__.startswith('$SHARED_DIR')
assert os.path.normpath(Klammertext.KE.__file__).startswith(os.path.normpath('$SHARED_NATIVE'))
" 2>"$OUT/sublime.log"; then
echo "${green}PASS${reset} sublime adapters import the shared core"
PASS=$((PASS + 1))
@@ -118,6 +129,25 @@ else
FAIL=$((FAIL + 1))
fi
# --- the Notepad++ UDL: well-formed, and it restates the literal klammer -----
# (a static artifact of the SYNC set; nothing else can check it)
if PYTHONDONTWRITEBYTECODE=1 "$PYTHON" -c "
import sys, xml.etree.ElementTree as ET
u = ET.parse('$(native "$EDIT_DIR")/notepadpp/Klammertext.udl.xml').getroot().find('UserLang')
assert u.get('name') == 'Klammertext' and set(u.get('ext').split()) == {'kt', 'k'}, u.attrib
lists = {k.get('name'): (k.text or '') for k in u.find('KeywordLists')}
assert '00@code' in lists['Delimiters'].split() and '02code@' in lists['Delimiters'].split(), lists['Delimiters']
assert lists['Keywords1'].strip() == '@@@' and lists['Keywords2'].strip() == '@@' and lists['Keywords3'].strip() == '@'
assert '03#[' in lists['Comments'].split() and '04]#' in lists['Comments'].split()
" 2>"$OUT/udl.log"; then
echo "${green}PASS${reset} notepad++ UDL is well-formed and restates the literal klammer"
PASS=$((PASS + 1))
else
echo "${red}FAIL${reset} notepad++ UDL is well-formed and restates the literal klammer"
cat "$OUT/udl.log"
FAIL=$((FAIL + 1))
fi
# --- the language server protocol test -------------------------------------
if PYTHONDONTWRITEBYTECODE=1 "$PYTHON" "$FIX/ls_test.py" "$SHARED_DIR" "$FIX" >"$OUT/ls.log" 2>&1; then
echo "${green}PASS${reset} language server protocol ($(grep -c '^PASS' "$OUT/ls.log") checks)"
@@ -230,17 +260,29 @@ else
fi
# --- the VS Code extension (optional: needs a Node runtime) ----------------
# node itself, or VS Code's Electron binary run as Node.
# node itself, or VS Code's Electron binary run as Node, wherever an
# installed VS Code keeps it: the Linux package, the macOS app bundle, the
# Windows per-user install (LOCALAPPDATA is a Windows variable, so the shell
# is MSYS2 there and cygpath exists).
CODE_BIN=""
if [ -x /usr/share/code/code ]; then
CODE_BIN=/usr/share/code/code
elif [ -x "/Applications/Visual Studio Code.app/Contents/MacOS/Electron" ]; then
CODE_BIN="/Applications/Visual Studio Code.app/Contents/MacOS/Electron"
elif [ -n "$LOCALAPPDATA" ] && command -v cygpath >/dev/null 2>&1; then
c="$(cygpath -u "$LOCALAPPDATA")/Programs/Microsoft VS Code/Code.exe"
[ -x "$c" ] && CODE_BIN="$c"
fi
run_node() {
if command -v node >/dev/null 2>&1; then
node "$@"
elif [ -x /usr/share/code/code ]; then
ELECTRON_RUN_AS_NODE=1 /usr/share/code/code "$@"
elif [ -n "$CODE_BIN" ]; then
ELECTRON_RUN_AS_NODE=1 "$CODE_BIN" "$@"
else
return 127
fi
}
if command -v node >/dev/null 2>&1 || [ -x /usr/share/code/code ]; then
if command -v node >/dev/null 2>&1 || [ -n "$CODE_BIN" ]; then
if run_node "$FIX/vscode_ext_test.js" "$EDIT_DIR/vscode" "$FIX" >"$OUT/vscode.log" 2>&1; then
echo "${green}PASS${reset} vscode extension ($(grep -c '^PASS' "$OUT/vscode.log") checks)"
PASS=$((PASS + 1))
@@ -260,7 +302,7 @@ cp -R "$EDIT_DIR/vscode" "$EDIT_DIR/shared" "$OUT/vsix/"
if ( cd "$OUT/vsix/vscode" && ./make_vsix.sh >/dev/null 2>&1 ) && \
PYTHONDONTWRITEBYTECODE=1 "$PYTHON" -c "
import sys, zipfile
names = set(zipfile.ZipFile('$OUT/vsix/vscode/klammertext.vsix').namelist())
names = set(zipfile.ZipFile('$OUT_NATIVE/vsix/vscode/klammertext.vsix').namelist())
need = {'extension.vsixmanifest', '[Content_Types].xml',
'extension/package.json', 'extension/extension.js',
'extension/language-configuration.json', 'extension/README.md',
+6 -2
View File
@@ -86,7 +86,10 @@ check_contains() {
FAIL=$((FAIL + 1))
return
fi
if printf '%s' "$output" | grep -qF "$needle"; then
# Wrap-insensitive: error text is justified to 80 columns, and where the
# needle breaks across a line depends on the installation's path length
# (found in Windows Sandbox, whose user name is long: "was not \nfound").
if printf '%s' "$output" | tr '\n' ' ' | tr -s ' ' | grep -qF "$needle"; then
echo "${green}PASS${reset} $test_name"
PASS=$((PASS + 1))
else
@@ -114,7 +117,8 @@ check_fails() {
FAIL=$((FAIL + 1))
return
fi
if printf '%s' "$output" | grep -qF "$needle"; then
# Wrap-insensitive, like the other helper above.
if printf '%s' "$output" | tr '\n' ' ' | tr -s ' ' | grep -qF "$needle"; then
echo "${green}PASS${reset} $test_name"
PASS=$((PASS + 1))
else