Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>K2 Script SupportNew to Visual Studio Code? Get it now.
K2 Script Support

K2 Script Support

Jakub Schober asi

|
22 installs
| (1) | Free
K2 ERP Pascal script language support — syntax highlighting, code formatter, and error diagnostics
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

K2Script — VS Code Extension

Language support for K2Script, the Pascal-dialect scripting language used in K2 ERP.

Status: Early preview / incomplete — expect rough edges. The extension is actively being developed and tested. Some features may not work correctly in all situations.

Bug reports and feedback: Please report any issues via Microsoft Teams.


Features

Syntax Highlighting

Full TextMate grammar covering K2Script-specific constructs:

  • K2 certificate headers — {!#CERT3=...} blocks shown as documentation comments
  • Compiler directives — {$DESC '...'}, {$TYPE ...} and other {$...} pragmas
  • Code-generation markers — {@GENERATED}, {@ENDGENERATED}, {@MANUAL}, {@ENDMANUAL}
  • K2 date/time literals — %DD.MM.YYYY, %HH:MM:SS
  • info...end metadata blocks — with property names (Title, Author, Keywords, LANGNUM, …) highlighted
  • K2-specific keywords — pureunit, modules, module, exported, files
  • Record-mode constants — remAppend, remEdit, remDelete, remFree, remReplace, remAll, …
  • K2 built-in functions — K2Now, FirmPath, ExecK2Form, RunScript, ProcessIndicator, …
  • Standard Pascal functions — IntToStr, Format, FormatDateTime, IncMonth, Trim, …
  • K2 constant naming patterns — ec*, er*, mr*, tf*, sdm*, cD_* prefixes
  • K2 operators — ^ (AsControlValue) and ° (TDataField field accessor)
  • K2 type names — TDate, TTime, ArrayOfString, TxxxDM data-module types
  • K2 global variables — aktdm, CurrentDM, FirSet, CurrentUFContext, …
  • Standard Pascal keywords, control flow, types, numbers, strings, and // / { } / (* *) comments

Code Formatter

The extension bundles a full automatic code formatter for K2Script .PAS files — one of its most important features.

Trigger with the standard VS Code format command:

  • Shift + Alt + F (Windows / Linux)
  • Shift + Option + F (macOS)
  • Or right-click → Format Document

What the formatter does:

Rule Detail
Indentation 2-space indent, consistent across all block types
begin/end blocks try/except/finally, repeat/until, case/of, record all indented correctly
Soft sections uses, var, const, type, modules — content indented, section closed automatically when the next section starts
Single-statement constructs if x then stmt; / for ... do stmt; / while ... do stmt; indented without extra wrap
info...end blocks K2 metadata block indented as a unit
Multi-line program(...) Continuation lines inside unclosed (...) get an extra indent level
Blank lines Collapses consecutive blank lines to at most one
Standalone // comments Always placed at column 0, regardless of surrounding indent
Column-0 markers {!#CERT...}, {@GENERATED}, {@ENDGENERATED} never indented

Error Diagnostics

Basic validation with red-underline diagnostics for common mistakes:

  • Mismatched begin/end block depth
  • Unknown or misspelled K2-specific keywords (limited coverage — work in progress)

Supported File Types

.PAS and .pas files are automatically recognised as K2Script.


Requirements

  • VS Code 1.80 or newer
  • No runtime dependencies — pure TypeScript, no external tools needed

Known Limitations

  • Formatter is not perfect. Complex nested constructs (deep case of, inline end else begin chains, with blocks) may indent incorrectly in edge cases.
  • Diagnostics coverage is limited. Only a small subset of possible errors is detected.
  • No go-to-definition. Ctrl-clicking a symbol does not navigate to its declaration.
  • Type inference is file-local. The extension resolves types from var declarations and modules aliases in the current file only — cross-file references are not tracked.
  • Tested only against internal K2 ERP .PAS scripts — third-party Pascal files may not format correctly.

Release Notes

2.3.2

New:

  • "Looks undefined" warnings. The extension now underlines (yellow, warning-level — never red/error) calls like SomeFunction(...) where SomeFunction isn't recognised as a built-in, a locally-declared function/procedure, something pulled in via uses, or a method of a known class. This is a heuristic, not a real compiler check — it doesn't see K2's own module/framework registry, so it's expected to have false positives on legitimate K2-specific functions and classes it simply doesn't know about yet. It deliberately does not check dot-qualified calls (obj.Method(...)) — that would need full type resolution to avoid being wrong constantly — and it allows calling any method of any class known in the file without Self. (K2Script's implicit self-dispatch), since this check isn't scoped per-enclosing-class.
  • Added ~54 previously-missing standard/K2 built-in function signatures — the LinkF* family (LinkFLong, LinkFDateTime, LinkReferenceStr1, LinkFBit, LinkFCurrency), conversion functions (RoundTo, CurrToStr, StrToCurr, StrToDateTime, StrToDateExt, BoolToStr), GetRPMStdText, and things like GauInit/GauClose, WTransaBegin, RDSEnable, AddDirectLink, AddDynamicLink, AddAttachedDocument, AddBindByProgName, GetPermission/SetPermission, ISO8601ToDate/DateToISO8601, TryStrToInt, StrToFloatDef, K2Round, GetFieldNoDm, PayPaymentByInternalDocument, and more — plus 4 previously-unregistered classes used as type casts in real code (TRozpoctyRozpocty, TPurchaseContractDM, TCustomDataM, TObjectPropK2). Discovered by running the new warning check across ~90 real project files and fixing every case that was a genuinely missing built-in rather than a real mistake. A handful of very K2-specific signatures (ReadSQLValueDM, LinkFStrTR, FormatDateTimeByLCID, AddDirectLink, AddDynamicLink, AddBindByProgName, PayPaymentByInternalDocument) were inferred from how they're actually called in real code, not from official K2 documentation — the parameter types are a best guess.

Bug fixes (found while building the above):

  • constructor/destructor weren't recognised as keywords by the tokenizer, which (among other things) made a class's own constructor Create(...) declaration look like an undefined call.
  • A program Name(...) or unit Name; declaration's own name was being flagged as an unknown call — a program/unit header has the exact same shape as a function call.
  • inherited MethodName(...) (calling the parent class's implementation of the current method) was being flagged — it's now treated the same as obj.Method(...): not checked, since there's no visibility into the parent class's members here.

Known limitation: project-specific business functions/classes that aren't declared anywhere as a .PAS/.pas file in the open workspace (e.g. names specific to one company's modules) will still show as false positives — there's no way to distinguish those from genuinely undefined calls without a real K2 compiler/framework registry. If this gets noisy in practice, the check can be scoped down or disabled.

2.2.0

New:

  • Go to Definition (Ctrl+Click / F12) — jump to where a function, procedure, constant, class, or var/modules alias is actually declared. Works across files pulled in via uses: clicking a call to a function or a class method declared in another unit opens that file and jumps straight to it. Clicking a unit name inside a uses clause itself opens that unit's file. For a class method, jumps to the qualified implementation (TSomeClass.Method) rather than just the forward declaration inside the class body, when both exist.
  • Function/procedure completions now auto-fill their parameters — selecting a function from the suggestion list inserts FuncName(param1, param2) with each parameter name as a tab-stop placeholder (press Tab to move between them), and immediately pops up parameter hints. Applies to local functions, uses-included functions, class methods, and built-ins. A zero-parameter function is inserted as a plain name (no forced ()), since Pascal allows referencing those without parens.
  • Completion suggestions now pop up automatically as you type, not just after ./: or Ctrl+Space — e.g. while filling in a function call's arguments inside (...). (Sets editor.quickSuggestions for .PAS/.pas files; doesn't affect other languages.)

Bug fixes:

  • Comma-separated multi-alias groups in modules/files sections no longer trigger a false "není standardní K2 modul" warning. zak1, zak2: TInvoiceOutDM previously flagged zak1 (every name in the group except the one immediately before the :) as if it were an unrecognised module type name.
  • Classes declared directly in the current file (with no uses involved) now resolve for completion, hover, and go-to-definition. Previously only classes pulled in via uses were recognised — var R: TMyOwnClass; followed by R. offered nothing at all if TMyOwnClass was declared right there in the same file.
  • Self inside one of your own class's methods now resolves to that class, instead of a hard-coded generic TDataM fallback — Self.SomeMethod inside TMyClass.SomeOtherMethod now completes, hovers, and jumps to definition correctly, scoped per method (a Self inside TAlpha's methods never leaks TBeta's members, even in the same file). Self used outside any class method still falls back to TDataM as before.

2.1.0

New:

  • uses support — cross-file IntelliSense. Referencing another .PAS/.pas file's unit in a uses clause now works like a textual include: every function, procedure, constant, class, and var/modules alias declared in that unit becomes available in the current file's autocomplete, hover, and signature help — exactly as if it had been typed directly into the current file. This matches how units are actually written in this codebase (no interface/implementation/exported split — everything a unit declares is visible, with no public/private filtering).
    • Unit names are matched to workspace files case-insensitively, by filename (without extension) — e.g. uses jic_u_konstanty; finds JIC_U_Konstanty.PAS anywhere in the open folder.
    • A unit's type SomeClass = class ... end; declarations are parsed too, so var R: SomeClass; resolves and R. offers that class's constructors, destructors, methods, and fields.
    • A uses entry that doesn't match any file in the workspace (e.g. a standard K2 module like FM_ARTICLE that isn't a local .PAS file) is silently skipped — nothing breaks, it's just not resolvable content.
    • Constants (const Name [: Type] = Value;) are now recognised for the first time, in both the current file and used units — including plain var Name: Type = Value; entries with an initializer, which behave the same way. Hover shows the value.

Internal: the document-parsing helpers (buildLocalFunctions, buildTypeMap, …) moved to a new shared src/parseUtils.ts module, and a new src/unitResolver.ts handles workspace file lookup and per-file caching (invalidated on file create/delete, and on content change via document version). Completion, hover, and signature-help providers are now asynchronous to support this.

2.0.0

The biggest update since the extension's first release — a full generation of IntelliSense data plus several completion-quality fixes that came out of testing it.

New:

  • Massively expanded data-module coverage — 276 → 1 683 modules (~6×), sourced from the K2 SWS v1 API (/Meta/) instead of the previous hand-picked MCP subset. Autocomplete, hover, and signature help now work on virtually any standard K2 data module, not just the most common ones.
  • Child module accessors are now suggested (e.g. ArtDM.CommentChild, ArtDM.LinkChild) — previously only scalar and FK fields were exposed. Hover shows the target module and a (child) marker.
  • FK fields show their LinkFStr display field — hovering a link field like BrandRID now shows → TWebBrandDM, LinkFStr → Name, so it's clear which field a LinkFStr() call against that link would return.
  • Field types for the ~1 400 newly-covered modules are inferred from the API's ValueType classification (String/Integer/TDate/TTime/TDateTime); the original ~260 modules keep their precise types (Int64/Double/Currency/Boolean/…) from the richer legacy dataset.
  • Field data now ships as a bundled JSON resource loaded once at activation (~50ms) instead of a generated TypeScript literal, keeping compile times and extension size sane at this scale.
  • Standard-module validation list expanded 1 137 → 2 124 (union with the new 1 683-class dataset) — fixes ~987 cases where a real, valid K2 module was flagged with a false "není standardní K2 modul" warning in the modules/files section.
  • Field/method completions now show their type inline — every suggestion (Id, BrandRID, …) displays its type (Integer, Int64, → TWebBrandDM, …) directly in the list, not just in the side documentation panel.
  • Declared var variables now appear in autocomplete — previously only local functions and built-ins were suggested at statement scope; a plain var x: Integer; never showed x as a suggestion.
  • modules aliases are now offered as variables too — modules art: TArticleDM; now suggests art itself (with its type shown) at statement scope, not just art.<member> after typing the dot.

1.2.4

New:

  • Rainbow block colouring for begin/end — matching block delimiters are coloured by nesting depth (6-colour cycle), so each begin and its end share a colour and nested blocks are easy to pair up. Unlike VS Code's built-in bracket-pair colourization (which mis-pairs in a Pascal dialect because end also closes case/try/record/class), this uses a context-aware semantic-tokens pass that correctly handles forward class declarations, class function prefixes, and variant-record case selectors — so the colours never drift. Covers begin/end, case/end, try/end, record/end, class/end, info/end, and repeat/until.
  • Uses VS Code's standard bracket-pair palette (gold → orchid → blue, cycling). Overridable via editor.semanticTokenColorCustomizations → rules k2block0…k2block5. When semantic highlighting is off, begin/end fall back to a gold grammar colour (scope keyword.control.block.k2script).

1.2.3

Bug fixes:

  • Completions no longer misfire inside strings, comments, case labels, or time literals — the type-suggestion, member-access, and signature-help logic now ignore string/comment content and only offer type names where a type is actually valid (declarations, parameters, record fields — not case labels, statement labels, :=, or %hh:mm:ss literals).
  • Type suggestions now list primitives first — String, Integer, Boolean, TDateTime, … are ranked above the 276 data-module names, which are relevant mainly in the modules section. Typing : in a declaration now triggers the list automatically.
  • Signature help is robust to strings — parentheses, commas, and semicolons inside string arguments (e.g. Format('a)b', x)) no longer break the active-parameter tracking.
  • Commented-out function/procedure declarations are no longer suggested.

1.2.2

Bug fixes:

  • class declarations no longer cause false "unmatched class" errors or broken indentation — forward declarations (TFoo = class;), class-method prefixes (class function … / class procedure …), and class-reference types (class of …) are no longer counted as block openers. Real class bodies are unaffected.
  • Variant records no longer report a false "unbalanced record" error — the case … of selector inside a record is recognised as part of the record (closed by the record's single end).
  • Field types display friendly names — the ~668 fields previously shown with raw K2 type tokens (ftEnum, ftArray, ftTimeStamp, …) now display mapped types (Integer, array, TDateTime, …) in completion and hover.

1.2.1

Bug fixes:

  • DM member access now includes inherited methods — typing ArtDM. on a typed data-module variable lists the module's fields first, then the inherited TDataM API (Save, DoNext, Locate, …). Previously only the fields were offered and all methods were missing (also affected hover and signature help).
  • Member completion now works mid-member on Ctrl+Space — pressing Ctrl+Space inside a partially typed member (e.g. ArtDM.Do|) now offers members instead of falling through to global suggestions. Numeric/date literals like %31.12. no longer misfire as member access.

1.2.0

New — IntelliSense:

  • Autocomplete on . — typing . after a variable name suggests its fields, methods, and properties (e.g. dm.DoNext, aktdm.AbcField). Type is inferred from var declarations and modules aliases in the current file; TXxxDM types without an explicit entry fall back to TDataM members.
  • 276 K2 data modules — 8 539 fields available for autocomplete and hover (31 standard parent modules + 245 child/sub-modules, sourced live from MCP). Previously only 8 modules were included.
  • Ctrl+Space at global scope — lists all K2 built-in functions and standard Pascal functions. Functions and procedures defined directly in the current file are listed first.
  • Signature hints — typing ( or , inside a call shows the full parameter signature in a popup; the active parameter is highlighted as you move through arguments. Works for K2/Pascal built-ins, class methods, and functions defined in the current file.
  • Hover docs — hovering over a method, property, or field after . shows its full signature. Global K2/Pascal functions also show their signature on hover.

Supported classes for member access: TDataM, TBaseDataM, TDataField, TK2Page, TIdHTTP, TxStringBuilder, TRegularExpression, TCCFtp, TSqlConnection, TMFile/TAdoFile, TScriptCollection

1.1.3

Bug fixes:

  • class type blocks (type TMyClass = class ... end;) no longer incorrectly flagged as mismatched end — same fix as memfile/adofile
  • class body indented correctly by the formatter (fields inside treated like record)

1.1.2

Bug fixes:

  • adofile type blocks (type X = adofile ... end;) no longer incorrectly flagged as mismatched end — same fix as memfile in 1.0.2
  • adofile now highlighted as a declaration keyword
  • adofile indented correctly by the formatter (fields inside treated like record/memfile)

1.1.1

Bug fixes:

  • Added 58 missing standard K2 modules sourced from complete datove_moduly_vsechny.xlsx registry — total known modules increased from 1 079 to 1 137 (TABCAnalysisDM, TActivityDM, TVehicleDM, TWorkplaceResourceDM, and 54 others)

1.1.0

Formatter:

  • files section (old-style DM declarations) now treated as a soft section — content is indented and the keyword is split to its own line, same as modules/var/uses
  • interface, implementation, initialization, finalization now act as unit-section boundaries — all depth counters reset so each section formats with a clean indent slate; initialization/finalization content is indented one level

Validator:

  • files section no longer causes false-positive "not a standard K2 module" warnings inside a subsequent modules section
  • files section entries validated — the entity type name (after :) is checked against the standard K2 module list (as T{Name}DM); unknown entities are flagged with a warning
  • info block property names validated — unknown properties (anything other than Title, Author, Keywords, AS3Compatible, DefaultDM, LANGNUM) are flagged with a warning
  • modules and files sections: trailing comma on the last entry is now flagged as a warning (last entry must end with ;)

Syntax highlighting:

  • VKU_* virtual key/command constants now highlighted as K2 constants
  • K2 utility classes highlighted as types: TxStringBuilder, TTextSplitter, TRegularExpression, TSQL, TQuery, TEasyForm, TIdHTTP, TExcel, TCCFtp, TScriptPersistent, TScriptItem, TScriptCollection, TDataField
  • Removed misleading Delphi calling conventions from keyword list (external, stdcall, cdecl, register, pascal, safecall) — these do not exist in K2Script
  • {@GENERATED}...{@ENDGENERATED} blocks are now visually dimmed (italic grey) to discourage accidental editing of auto-generated code

1.0.9

New:

  • Soft-section keywords (uses, var, const, type, modules) are now forced onto their own line — content that follows on the same line is automatically split to the next line and indented (e.g. modules api: TBVVApiInterface, → modules / api: TBVVApiInterface,)

1.0.8

Bug fixes:

  • Standalone // comments that contain a keyword (begin, end, if, var, etc.) are no longer moved to column 0 — they keep the current indentation level (treated as commented-out code)

1.0.7

Bug fixes:

  • Added 6 missing standard modules to the known-modules list: TExternalDocumentDM, TAdvanceReceivedDM, TinternalDocumentDM, TMatchingSymbolDM, TOfficerDM, TPrPeriodDM

1.0.6

New:

  • Standard module validation — modules listed in the modules section are checked against 1 073 known standard K2 modules; any module not in the list is highlighted with a warning ("není standardní K2 modul"), so custom or misspelled module names stand out without blocking compilation
  • Correctly handles the alias: TypeName, syntax — only the type name is validated, not the alias

1.0.5

Bug fixes:

  • Fixed inconsistent end keyword colors in case...else...end, try...finally...end and all other block structures — begin/end were registered as VS Code bracket pairs which caused the bracket pair colorization to override the grammar color with a different hue at each nesting depth; removed from bracket pairs entirely

1.0.4

Bug fixes:

  • begin and end now use the same color as if, case, try, finally, else, etc. — previously they used a separate TextMate scope that many themes styled differently, causing inconsistent colors in case...else...end and try...finally...end blocks

1.0.3

Bug fixes:

  • end keyword no longer shows different colors at different nesting depths — bracket pair colorization is now limited to () and [] only
  • end; closing an info block now uses the same color as all other end keywords

1.0.2

Bug fixes:

  • memfile type blocks (type X = memfile ... end;) no longer incorrectly reported as mismatched end
  • memfile now indented correctly by the formatter (fields inside treated like record fields)
  • memfile now highlighted as a declaration keyword
  • pureunit files no longer trigger a false "file must start with program or unit" warning

1.0.1

  • Added README with full feature documentation

1.0.0

  • Renamed extension to K2 Script Support
  • Formatter included as a core feature

0.1.0

Initial public preview:

  • Syntax highlighting for K2Script
  • Code formatter with K2-specific rules
  • Basic error diagnostics

About K2 ERP

K2 is a Czech ERP system. K2Script is a Pascal dialect used to write custom business logic, forms, and integrations directly inside K2. This extension is an unofficial community tool — not affiliated with K2 atmitec s.r.o.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft