Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Blohm G-Code Syntax HighlightingNew to Visual Studio Code? Get it now.
Blohm G-Code Syntax Highlighting

Blohm G-Code Syntax Highlighting

Alexej Berger

|
51 installs
| (2) | Free
Blohm G-Code syntax highlighting (ISO 6983 / Siemens 840D). Supports .gcode, .nc, .mpf, .spf and more.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Blohm G-Code Syntax Highlighting

Syntax highlighting, semantic coloring, and live diagnostics for G-Code (ISO 6983 / Siemens SINUMERIK 840D sl / 828D), tailored to Blohm grinding cycles and the Blohm variable naming conventions.

Supported file extensions: .gcode · .nc · .cnc · .gc · .ngc · .txt · .mpf · .spf

Features

Syntax highlighting

  • G / M commands — G0, G1, G41.1, M3, M30, …
  • Siemens 840D cycles & commands — CYCLE832, POCKET3, TRANS, ROT, SCALE, MIRROR, MCALL, CALL, RET, STOPRE, MSG, SPOS, Pos/POSA, interrupt keywords (SETINT, PRIO, BLSYNC, LIFTFAST, CLRINT, …) and more.
  • R-parameters — R1, R100, …
  • Blohm variables — identifiers ending in _ (e.g. MyVar_), $-system variables (e.g. $AA_IW, $TC_DP1), and plain mixed-case globals.
  • Comments — ; and ' line comments (semicolons inside (...) and "..." are not treated as comments).
  • Function calls, DEF/DEFINE keywords, type keywords, labels, and the %_N_… program header.

Semantic (depth-based) coloring

Nesting levels are colorized by depth (5 cycling levels) for:

  • IF / ELSE / ENDIF
  • FOR / ENDFOR and WHILE / ENDWHILE
  • Parentheses ( )
  • Variable index brackets [ ] (e.g. $AN_CEC_STEP[N_LOOP1])

Diagnostics (error / warning squiggles)

Severity Rule
🔴 Error Undefined variable — used but never declared (locally or in a global DEF/GUD file)
🔴 Error Unclosed function call, [, or (; unexpected )
🔴 Error Empty R-assignment (e.g. R11= with no value)
🔴 Error Assignment (=) used instead of == inside IF / WHILE / WHEN conditions
🔴 Error Standalone number not attached to an address/expression
🔴 Error DEF after the first G/M command
🔴 Error Unmatched / unexpected IF, ELSE, ENDIF, ENDFOR, ENDWHILE; unclosed loops at EOF
🔴 Error WHEN without DO; REPEAT without two valid labels
🔴 Error Commented-out program header / missing ;$PATH= / PROC name mismatch with header
🔴 Error Wrong number of indexes on a $TC_ tool-data variable (e.g. $TC_DP4[t,d] needs 2, $TC_TPC4[t] needs 1)
🔴 Error Illegal DEF variable name — longer than 31 characters, first two characters not letters/underscores, $ prefix, character other than letter/digit/underscore, or a reserved SINUMERIK name (alarms 12420 / 12556)
🔴 Error Assigned value is incompatible with the declared data type — DEF INT dummy_ then dummy_ = "text", or R1 = "text" (R-parameters are REAL)
🔴 Error Array index outside the declared dimensions — ZT_HK_[3] with DEF REAL ZT_HK_[3] (valid: 0–2), checked on the rounded value — or an index that is not a number at all
🔴 Error Comparison between incompatible types — REAL == "1"; a STRING also compares only with == / <>
🔴 Error Variable declared twice in the same file — DEF declarations and PROC parameters, compared case-insensitively (alarm 12170)
⚠️ Warning Fractional array index — legal, but the control rounds it (ZT_VK_[1.6] addresses element 2)
⚠️ Warning REAL value assigned to an INT target — legal, but the control rounds to the nearest whole number (100.5 → 101). INT → REAL is exact and not reported
⚠️ Warning Unused variable — declared with DEF but never referenced
⚠️ Warning Undefined or wrong-direction GOTOF / GOTO / GOTOB label target
⚠️ Warning Missing DISPLOF on a PROC line

Cross-file variable resolution

On workspace open, all DEF/GUD files (first line matching %_N_*_DEF) are pre-scanned so variables declared there — including commented-out DEF lines — are known globally and won't be flagged in other files. PROC parameter lists (including STRING[n]) are treated as local declarations. Matching is case-insensitive, and diagnostics refresh live when a DEF file is saved.

Hover documentation

Bilingual (DE/EN) hover tooltips sourced from the Siemens SINUMERIK 840D sl / 828D documentation for:

  • G and M commands (including parameterized forms like M31=10)
  • R parameters and OPTI1_[n] option bits
  • $-variables (691+ BTSS parameters), with per-tool-type tables for $TC_* tool parameters
  • Path methods (ASPLINE, CUT3DCC, SUPA, …) and TOFF / TOFFL / TOFFR
  • Built-in functions and predefined procedures (STRLEN, TAN, SUBSTR, GETT, SETAL, REP, DC, …), shown with their call syntax and a Siemens documentation link. These fire only at a real call site — the name immediately followed by ( — so a German comment such as 'Onlineuebernahme der Daten(R294==1) stays quiet

Go to Definition

F12 (or Ctrl+click / Go to Definition) navigates from a name to where it is declared:

Name under the cursor Jumps to
Cycle call — SEL_STATION(…) The PROC SEL_STATION(…) line, in whichever workspace file defines it
Jump-label target — GOTOF MARKE1, REPEAT START_ END_ The MARKE1: label definition (labels are file-local)
Variable — AX4_, OPTI1_[3] Its DEF / DEFINE … AS / PROC parameter declaration — in this file, or in the DEF/GUD file that declares it globally
Built-in function — STRLEN(…), GETT(…) The Siemens manual, opened in the browser at the page that documents it. A built-in has no declaration to jump to, so this replaces an otherwise dead F12

The cursor lands on the declared name itself, so Peek Definition (Alt+F12) shows the declaration in context. Names with no declaration to jump to (`# Blohm G-Code Syntax Highlighting

Syntax highlighting, semantic coloring, and live diagnostics for G-Code (ISO 6983 / Siemens SINUMERIK 840D sl / 828D), tailored to Blohm grinding cycles and the Blohm variable naming conventions.

Supported file extensions: .gcode · .nc · .cnc · .gc · .ngc · .txt · .mpf · .spf

Features

Syntax highlighting

  • G / M commands — G0, G1, G41.1, M3, M30, …
  • Siemens 840D cycles & commands — CYCLE832, POCKET3, TRANS, ROT, SCALE, MIRROR, MCALL, CALL, RET, STOPRE, MSG, SPOS, Pos/POSA, interrupt keywords (SETINT, PRIO, BLSYNC, LIFTFAST, CLRINT, …) and more.
  • R-parameters — R1, R100, …
  • Blohm variables — identifiers ending in _ (e.g. MyVar_), $-system variables (e.g. $AA_IW, $TC_DP1), and plain mixed-case globals.
  • Comments — ; and ' line comments (semicolons inside (...) and "..." are not treated as comments).
  • Function calls, DEF/DEFINE keywords, type keywords, labels, and the %_N_… program header.

Semantic (depth-based) coloring

Nesting levels are colorized by depth (5 cycling levels) for:

  • IF / ELSE / ENDIF
  • FOR / ENDFOR and WHILE / ENDWHILE
  • Parentheses ( )
  • Variable index brackets [ ] (e.g. $AN_CEC_STEP[N_LOOP1])

Diagnostics (error / warning squiggles)

Severity Rule
🔴 Error Undefined variable — used but never declared (locally or in a global DEF/GUD file)
🔴 Error Unclosed function call, [, or (; unexpected )
🔴 Error Empty R-assignment (e.g. R11= with no value)
🔴 Error Assignment (=) used instead of == inside IF / WHILE / WHEN conditions
🔴 Error Standalone number not attached to an address/expression
🔴 Error DEF after the first G/M command
🔴 Error Unmatched / unexpected IF, ELSE, ENDIF, ENDFOR, ENDWHILE; unclosed loops at EOF
🔴 Error WHEN without DO; REPEAT without two valid labels
🔴 Error Commented-out program header / missing ;$PATH= / PROC name mismatch with header
🔴 Error Wrong number of indexes on a $TC_ tool-data variable (e.g. $TC_DP4[t,d] needs 2, $TC_TPC4[t] needs 1)
🔴 Error Illegal DEF variable name — longer than 31 characters, first two characters not letters/underscores, $ prefix, character other than letter/digit/underscore, or a reserved SINUMERIK name (alarms 12420 / 12556)
🔴 Error Assigned value is incompatible with the declared data type — DEF INT dummy_ then dummy_ = "text", or R1 = "text" (R-parameters are REAL)
🔴 Error Array index outside the declared dimensions — ZT_HK_[3] with DEF REAL ZT_HK_[3] (valid: 0–2), checked on the rounded value — or an index that is not a number at all
🔴 Error Comparison between incompatible types — REAL == "1"; a STRING also compares only with == / <>
🔴 Error Variable declared twice in the same file — DEF declarations and PROC parameters, compared case-insensitively (alarm 12170)
⚠️ Warning Fractional array index — legal, but the control rounds it (ZT_VK_[1.6] addresses element 2)
⚠️ Warning REAL value assigned to an INT target — legal, but the control rounds to the nearest whole number (100.5 → 101). INT → REAL is exact and not reported
⚠️ Warning Unused variable — declared with DEF but never referenced
⚠️ Warning Undefined or wrong-direction GOTOF / GOTO / GOTOB label target
⚠️ Warning Missing DISPLOF on a PROC line

Cross-file variable resolution

On workspace open, all DEF/GUD files (first line matching %_N_*_DEF) are pre-scanned so variables declared there — including commented-out DEF lines — are known globally and won't be flagged in other files. PROC parameter lists (including STRING[n]) are treated as local declarations. Matching is case-insensitive, and diagnostics refresh live when a DEF file is saved.

Hover documentation

Bilingual (DE/EN) hover tooltips sourced from the Siemens SINUMERIK 840D sl / 828D documentation for:

  • G and M commands (including parameterized forms like M31=10)
  • R parameters and OPTI1_[n] option bits
  • $-variables (691+ BTSS parameters), with per-tool-type tables for $TC_* tool parameters
  • Path methods (ASPLINE, CUT3DCC, SUPA, …) and TOFF / TOFFL / TOFFR
  • Built-in functions and predefined procedures (STRLEN, TAN, SUBSTR, GETT, SETAL, REP, DC, …), shown with their call syntax and a Siemens documentation link. These fire only at a real call site — the name immediately followed by ( — so a German comment such as 'Onlineuebernahme der Daten(R294==1) stays quiet

Go to Definition

F12 (or Ctrl+click / Go to Definition) navigates from a name to where it is declared:

Name under the cursor Jumps to
Cycle call — SEL_STATION(…) The PROC SEL_STATION(…) line, in whichever workspace file defines it
Jump-label target — GOTOF MARKE1, REPEAT START_ END_ The MARKE1: label definition (labels are file-local)
Variable — AX4_, OPTI1_[3] Its DEF / DEFINE … AS / PROC parameter declaration — in this file, or in the DEF/GUD file that declares it globally
Built-in function — STRLEN(…), GETT(…) The Siemens manual, opened in the browser at the page that documents it. A built-in has no declaration to jump to, so this replaces an otherwise dead F12

-system variables, R parameters, G/M commands) are left alone.

Which manual F12 opens

Two settings control it, so the link can be swapped without touching the code:

Setting Default Meaning
blohmGCode.documentation.url SINUMERIK ONE NC programming Programming Manual 07/2024 The manual to open. Any URL works, including a local file:///D:/Doku/manual.pdf copy
blohmGCode.documentation.pageAnchors auto Whether to append #page=<n>. auto = only while the URL is the default manual; always for another edition of the same manual; never to always open at page 1

The page numbers were read from the default manual's own outline and full text and verified individually, and its printed page numbers match the PDF pages, so #page=<n> lands on the documented section. They mean nothing in a different manual — a technology manual such as Grinding, Operating Manual does not document the NC-language functions at all — which is why auto drops the anchor as soon as the URL changes.

Tests

npm test compiles the sources and runs the suite with the built-in Node test runner — no test-framework dependency:

npm test

src/test/rules.test.ts covers every diagnostic rule the analyzer produces: one case that must trigger it, plus — wherever the rule risks a false positive — a case that must stay silent (parentheses in a comment, a function result in a comparison, << versus <). src/test/functionDocs.test.ts covers the built-in function table, the call-site restriction and the configurable manual URL.

Each case runs against a fresh document URI with the cross-file registries cleared, because analyzeDocument() memoises per URI and reads global DEF/GUD and PROC state.

Editor integration

  • Bracket-pair highlighting, auto-closing pairs, and surrounding pairs for ( ), [ ], and "…".

Extension settings

Setting Type Default Description
blohmGCode.txtCheckPaths string[] ["content/Zyklen"] Directories whose .txt files are checked (linted) as G-Code.

Directories whose .txt files are checked (linted) as G-Code. Paths may be absolute or relative to a workspace folder — the default content/Zyklen resolves against the VS Code working directory (workspace root). When the list is empty, all .txt files are checked. Files with unambiguous G-Code extensions (.mpf, .spf, .nc, .gcode, .cnc, .gc, .ngc) are always checked regardless of this setting. This affects only the VS Code editor — the lint:gcode CLI is controlled solely by its own --dir argument.

// .vscode/settings.json
{
  "blohmGCode.txtCheckPaths": ["content/Zyklen", "C:\\NC\\programs"]
}

CLI linter (CI / Azure DevOps)

A standalone command-line linter (out/cli.js) runs the same diagnostic checks in a pipeline:

npm run bundle:cli
node out/cli.js --dir <path> [--exclude "<glob>"]... [--fail-on-warnings]
  • Scans a directory recursively for supported G-Code files.
  • Resolves cross-file variables by pre-scanning DEF/GUD files first.
  • Decodes UTF-16 LE (the SINUMERIK default), UTF-8, and UTF-8-with-BOM.
  • In Azure DevOps (TF_BUILD=True), emits each finding as an ##vso[task.logissue] annotation and fails the stage on errors (or warnings with --fail-on-warnings).

Building & packaging

npm ci
npm run bundle      # bundle client + server + CLI into out/
npm run release     # produce a .vsix package
Script Purpose
npm run bundle Bundle the extension client, language server, and CLI
npm run compile / npm run watch TypeScript compile (one-shot / watch)
npm run lint:gcode Build the CLI and lint the bundled ./examples
npm run release Bundle and package a .vsix via vsce
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft