>_EXECUTIVE SUMMARY
vscode-awk is the VS Code / VSCodium extension for AWK, backed by the awkrs interpreter — a pattern/action engine written in Rust (POSIX / gawk / mawk-style union CLI). It ships a declarative language contribution (filetype, grammar, editor config), an LSP client that launches awkrs --lsp, a debug adapter that launches awkrs --dap, and a TextMate grammar (source.awk) covering the AWK surface.
Design principle: mirror the proven vscode-stryke runtime wiring. The LSP transport is omitted so the client spawns bare awkrs --lsp and never appends --stdio (the arg-rejection / “connection got disposed” failure mode learned from vscode-stryke). The binary is resolved to an absolute path through $PATH plus common install dirs (~/.cargo/bin, /opt/homebrew/bin, …), so it works even when the editor is launched from the macOS Dock and doesn’t inherit the shell $PATH.
~COMPONENTS
| File | Responsibility |
|---|---|
package.json | Extension manifest — contributes.languages (id awk, *.awk, shebang firstLine), contributes.grammars (source.awk), contributes.configuration (LSP settings), contributes.commands (run / debug), contributes.debuggers (type awk), and the vscode-languageclient dependency. |
language-configuration.json | Line comment #, brackets, auto-closing / surrounding pairs, word pattern, and brace-based indentationRules. |
extension.js | Activates on onLanguage:awk. Starts a LanguageClient running awkrs --lsp over stdio, registers the run command (terminal awkrs -f <file>), and registers a DebugAdapterDescriptorFactory launching awkrs --dap. Missing binary → one non-fatal warning; highlighting still works. |
lib/resolveBinary.js | Pure (vscode-free) resolver that turns the awk.path setting into an absolute, executable path — searching $PATH then the GUI-missed fallback dirs. Unit-tested in CI. |
syntaxes/awk.tmLanguage.json | TextMate grammar — comments, shebang, strings, /.../ regex, numbers, special patterns, keywords, built-in functions / variables, field references, function definitions, and operators. |
scripts/tokenize_test.js | Loads the grammar under vscode-textmate + vscode-oniguruma (the engine VS Code itself uses) and asserts the scope of 13 sample tokens. |
$SCOPE MAP
| Token group | TextMate scope | Sample |
|---|---|---|
| Special patterns | keyword.other.special-pattern.awk | BEGIN END |
| Control flow | keyword.control.awk | if else while for next exit return |
| I/O statements | keyword.other.io.awk | print printf getline |
| Function intro | storage.type.function.awk | function func |
| Built-in variables | variable.language.awk | NR NF FS OFS ORS RS FILENAME SUBSEP |
| String functions | support.function.string.awk | length substr split sub gsub match sprintf |
| Math functions | support.function.math.awk | sin cos atan2 exp log sqrt int rand |
| I/O functions | support.function.io.awk | system close fflush |
| Field references | variable.language.field.awk | $0 $1 $NF $(NF-1) |
| Match operators | keyword.operator.match.awk | ~ !~ |
| Literals | string.* / constant.numeric / string.regexp | strings, numbers, /.../ regex |
#VERIFICATION
The grammar is loaded under the exact engine VS Code uses at runtime — vscode-textmate driving vscode-oniguruma — and a sample is tokenized with the resulting scopes asserted. This proves the grammar compiles under oniguruma and classifies AWK tokens correctly, including the tricky cases: a /.../ regex literal distinguished from division, a field reference such as $1 against the NF built-in, and the function name capture.
| Sample token | Asserted scope |
|---|---|
BEGIN | keyword.other.special-pattern.awk |
FS | variable.language.awk |
/^error/ | string.regexp.awk |
$1 | variable.language.field.awk |
gsub | support.function.string.awk |
function / trim | storage.type.function.awk / entity.name.function.awk |