VSCode language support for GOC files (.goc, .goh) and GEOS parameter
files (.gp) from the PC/GEOS/FreeGEOS SDK: syntax highlighting, folding,
hover tooltips, outline, include navigation, and diagnostics.
Author: Jirka Kunze License: Apache License 2.0 (see LICENSE and NOTICE)
- Visual Studio Code ≥ 1.75
- Node.js ≥ 18 (for building/development; not
required to simply install a prebuilt
.vsix) - A PC/GEOS SDK with the
ROOT_DIRenvironment variable set (needed for include navigation; all other features work without an SDK as well)
- Download the
.vsixfile (see Build to create it yourself, or grab it from this repo's releases if available). - Install it in VSCode:
Alternatively via the GUI: Extensions view (
code --install-extension vscode-geos-goc-0.1.0.vsix
Ctrl+Shift+X) →...menu → "Install from VSIX..." → select the file.
See Build.
git clone <repo-url>
cd vscode-geos-goc
npm install
npm run compilenpm run compile compiles src/extension.ts into out/extension.js
(TypeScript → JavaScript). To automatically recompile on changes:
npm run watchnpm install -g @vscode/vsce
npm run packageThis produces vscode-geos-goc-0.1.0.vsix in the project directory,
installable as described under Option A.
- Open the repo in VSCode and run
npm install. - Press
F5– this launches an Extension Development Host and automatically opens the bundledexamples/folder as the workspace (.vscode/launch.jsonalso setsROOT_DIR=examples/fake-sdk, so include navigation works right away without a real SDK). - In the Development Host, open
examples/sample.gocand try things out:- Highlighting and folding are visible immediately.
- Hover the mouse over
@class,@object, or any other Goc keyword → hover tooltip. Ctrl+Shift+Oopens the outline withMyObjectClass,MyObject,MSG_MY_OBJECT_UPDATE,MyDataResource.- Ctrl+click
geos.h,ec.h, orstdapp.gohjumps to the respective file underfake-sdk/CInclude. - Delete an
@endc→ a warning appears in "Problems" and as an underline in the editor.
- Open
examples/bad-include.gocto see the.goh/#includeerror.
Changes to src/extension.ts require npm run compile (or a running
npm run watch) and a restart of the Development Host
(Ctrl+R/Cmd+R in the Development Host window). Changes to data/*.json,
the syntaxes/*.tmLanguage.json files, or the language-configuration*.json
files take effect after restarting the Development Host without needing to
recompile.
| Setting | Default | Description |
|---|---|---|
geos-goc.sdkEnvVar |
"ROOT_DIR" |
Name of the environment variable pointing to the SDK root directory. |
geos-goc.sdkIncludeSubdirs |
["CInclude"] |
Subdirectory/ies relative to the SDK root that are searched for <...> includes. |
geos-goc.includePaths |
[] |
Additional, absolute include search paths (supports ${workspaceFolder}). |
Example (workspace or user settings.json):
{
"geos-goc.sdkEnvVar": "ROOT_DIR",
"geos-goc.sdkIncludeSubdirs": ["CInclude"]
}This already matches the default – explicit configuration is only needed if your setup differs (e.g. a different variable name, additional include subdirectories).
- Syntax highlighting for
.goc/.goh(all 54 Goc directives) and.gp(all 20 parameter fields, including allowed values/flags). - Folding for
@start/@end,@class/@endc,@deflib/@endlib, and@if/@ifdef/@ifndef/@endif. - Hover tooltips: hovering over a Goc keyword (e.g.
@vardataAlias) or a.gpfield (e.g.resource) shows syntax, description, and "See also" – the data source isdata/goc-keywords.json/data/gp-keywords.json. - Outline / breadcrumbs (
.goc):@class/@classdecl,@object,@method, and@startresource blocks appear in the Outline view and viaCtrl+Shift+O. - Include navigation (
#includeand@include): Ctrl+click on a filename jumps to the referenced file – whether it's in the SDK or in your own project. - Diagnostics:
- warns when a block pair (
@start/@end,@class/@endc,@deflib/@endlib,@if(def/ndef)/@endif) is not properly closed or nested. - reports an error when a
.gohfile is included via#includeinstead of@include(the C preprocessor/compiler cannot process the Goc syntax it contains). - warns when an include target cannot be found in any configured search path.
- warns when a block pair (
vscode-geos-goc/
├── package.json # Extension manifest (languages, grammars, settings, ...)
├── language-configuration.json # Comments, brackets, folding for .goc/.goh
├── language-configuration-gp.json # same, for .gp
├── syntaxes/
│ ├── goc.tmLanguage.json # TextMate grammar for GOC
│ └── gp.tmLanguage.json # TextMate grammar for .gp
├── data/
│ ├── goc-keywords.json # All 54 Goc directives with syntax/description/seeAlso
│ └── gp-keywords.json # All 20 .gp fields with syntax/description
├── src/
│ └── extension.ts # Hover provider, outline, include navigation, diagnostics
├── examples/
│ ├── sample.goc # Test file (highlighting, folding, outline, include navigation)
│ ├── bad-include.goc # Demonstrates the .goh/#include error
│ ├── sample.gp # Test file for .gp highlighting
│ └── fake-sdk/CInclude/ # Minimal "SDK" for the example setup (via ROOT_DIR in launch.json)
└── tsconfig.json
In addition to regular { } blocks (handled automatically by VSCode), the
following Goc directive pairs are configured as foldable regions (in
language-configuration.json, folding.markers section):
| Opens | Closes | Use |
|---|---|---|
@start |
@end |
Resource block |
@class |
@endc |
Class definition |
@deflib |
@endlib |
Library header file |
@if |
@endif |
Conditional compilation |
@ifdef |
@endif |
Conditional compilation |
@ifndef |
@endif |
Conditional compilation |
@classdecl intentionally has no counterpart and is therefore not treated
as a fold marker. Automatic indentation (indentationRules) remains
unchanged, based purely on { } brackets, since indenting based on these
directives isn't common practice in the GOC community.
src/extension.ts registers one hover provider each for goc and
geos-gp. Both look up the word under the cursor in the respective
data/*.json file and show syntax + description + "See also". For .goc,
a custom word pattern (@?[A-Za-z_][A-Za-z0-9_]*) is used so that, for
example, @vardataAlias is recognized as a whole.
Adding/changing hover text: simply edit the entries in
data/goc-keywords.json or data/gp-keywords.json – no need to recompile
the logic, just reload the extension (or restart the Development Host / VSCode).
GocDocumentSymbolProvider in src/extension.ts is a lightweight,
regex-based scanner (not a full parser). It recognizes:
@class <Name>, <Super>; ... @endc→ symbol of type "Class"@classdecl <Name>→ symbol of type "Class declaration" (single line)@object <Class> <Name> = { ... }→ symbol of type "Object"; brace matching accounts for strings/comments so that{/}inside them aren't counted incorrectly@method <Class>, <Message> { ... }→ symbol of type "Method"@start <Name> ... @end→ symbol of type "Resource block"
Symbols are currently reported flat (not nested), i.e. an @method
inside an @class block appears as a standalone entry rather than as a
child of the class symbol.
Both #include <file.h>/"file.h" and @include <file.goh>/"file.goh"
are recognized and turned into clickable links to the resolved file. The
resolution order matches the description in the GOC reference:
- Quotes (
"..."): first in the directory of the current file, then in the search paths. - Angle brackets (
<...>): first in the search paths, then (as a fallback) in the directory of the current file.
The search paths are assembled from (in this order):
geos-goc.includePaths– explicitly configured, absolute directories.<SDK root>/<sdkIncludeSubdirs>– the SDK root is read from theROOT_DIRenvironment variable (see Configuration).- The standard
INCLUDEenvironment variable, if already set by the Watcom toolchain (:- or;-separated).
Rule: .goh only via @include. .goh files contain Goc syntax (e.g.
@classdecl) that the C preprocessor/Watcom compiler cannot process. A
#include <something.goh> is therefore always flagged as an error,
regardless of whether the file can be found.
checkBlockBalance() in src/extension.ts scans .goc documents line by
line using a stack and reports:
- a closing keyword without a matching opening one (e.g.
@endcwithout a preceding@class) - a block pair left unclosed at the end of the file
The check runs on open and – with a 400 ms debounce – on every change to a
.goc document. It only checks Goc directives (@start/@end etc.),
not the balance of regular { } braces in C code.
The grammar in syntaxes/goc.tmLanguage.json is organized into named
sections (repository), including:
comments,strings,numbers,preprocessor– generic Cgoc-object-block,goc-keywords–@class/@object/@methodetc.geos-messages–MSG_*,C_MSG_*,ATTR_*,GI_*geos-types–word,dword,fixed_t,optr,ChunkHandle, ...
Adding new keywords/types: extend the appropriate regex in the relevant
rule (e.g. add more types from your codebase to geos-types).
Other possible extensions:
- Snippets:
contributes.snippetsinpackage.jsonplus asnippets/goc.json. - Commands/build integration (glue/swat/DOSBox workflow directly from VSCode).
.gpfield-value validation (e.g. warn about invalidtypeattributes).- Nested outline (methods as children of their class).
- Language server (go-to-definition, find references for
MSG_*).
- Highlighting, outline, include navigation, and diagnostics are all regex-/scan-based rather than built on a real parser. Very unusually formatted code (e.g. multiple directives on one line) can be misdetected.
- Include resolution does not account for conditional compilation
(
@ifdef/#ifdef) – an include inside an inactive branch is still resolved/checked. - The Goc directives (
@class,@object,@message, ...) come from the complete reference list (54 entries). The GEOS types (word,fixed_t,optr, ...) and message/attribute prefixes (MSG_,ATTR_,GI_, ...), on the other hand, are still a starting point derived from context and should be extended as needed. - In
.gpfiles, comments start with#(to end of line). - In
.gpfiles, the mapping of field → allowed values (e.g.typeonly withprocess|driver|appl|library|single|...) is not yet checked contextually – all known values are highlighted globally, regardless of the surrounding field.
The code of this extension is licensed under the Apache License 2.0 (see LICENSE).
The keyword reference data in data/goc-keywords.json and
data/gp-keywords.json (syntax and short descriptions) is extracted from
the official documentation of the FreeGEOS project, also licensed under the
Apache License 2.0. See NOTICE for details.