OpenEdge ABL language definition

May 11, 2026 ยท View on GitHub

This is a TextMate grammar for the Progress OpenEdge ABL Language (formerly known as 4GL).

It's used in the OpenEdge ABL for Visual Studio Code extension.

Contributing

The main file is abl.tmLanguage.json so contributors should hand-modify this file.

Tests

Tests are run from the root folder

npm install
npm test

If you noticed a syntax highlight issue in the VSCode extension, please try to create a failing test case first, and then modify the grammar accordingly.

Debugging

Clone the https://github.com/microsoft/vscode-textmate repo locally (represented by /path/to/vscode-textmate).

Debug ABL statement(s) using the command below.

cd path/to/vscode-textmate
node out/tests/inspect.js /path/to/abl-tmlanguage/abl.tmLanguage.json /path/to/abl-tmlanguage/debug-in.txt > /path/to/abl-tmlanguage/debug-out.txt

The /path/to/abl-tmlanguage/debug-out.txt file contains the line-by-line resolution of the code using rules defined in the abl-tmlanguage.json file.

Notes

VSCode extension

You can test this grammar locally with the associated VSCode extension:

git clone git@github.com:chriscamicas/abl-tmlanguage.git
cd abl-tmlanguage
npm link
cd ..
git clone git@github.com:chriscamicas/vscode-abl.git
cd vscode-abl
npm link abl-tmlanguage

You can now run and debug the extension from the vscode-abl directory (with the Launch Extension task). Every modification to the abl-tmlanguage project should be reflected in the vscode-abl directory immediately.

See npm link.

JSON vs plist

This project uses the JSON format over the plist one, mainly because I find it much more readable.

If you prefer the plist format, or the YAML one, there is an extension for VSCode that can convert them: TextMate Languages.

Note: I plan on using the YAML syntax (even more compact and readable) but it needs a build step as VSCode does not handle YAML natively.

Tokenize

This project uses the vscode-textmate package to tokenize and test the grammar.

Keywords

Part of this grammar is generated from a keyword list file. See [index.js] for information on how to generate that file, as well as the others required for the generation.

When npm run build is executed, a file called grammar.json is created, which contains properties for keywords (all the keywords), abl-functions and handle-attributes (attributes and method calls on ABL handles). The contents of this file should be copied into the abl.tmLanguage.json file, replacing the existing contents.

Scopes

The ABL-specific scopes produced by the ABL grammar listed in the table below. The scope names are largely based on the naming conventions at https://macromates.com/manual/en/language_grammars#language_rules and https://www.sublimetext.com/docs/scope_naming.html .

Scope NameUsed for/by
comment.block.ablEverything between /* and */
comment.line.double-slash.ablEverything in a // comment, incl. slashes
comment.preprocessor.analyze-suspend.abl&analyze-suspend, &analyze-resume
constant.character.escape.abl~ and the next char
constant.language.abltrue, false, yes, no, ? (unknown value)
constant.language.abl99/99/9999 (or similar) when used as a format clause
constant.numeric.abl0x00-0xFF, 0-9, scientific notation
entity.name.function.ablMethod call, property call, method name, property name, handle attributes, handle methods, event names
entity.name.function.preprocessor.ablPreprocessor names, including built-ins like opsys and process-architecture
entity.name.include.ablInclude file names
entity.name.label.ablBlock label names
entity.name.package.ablPackage names for using
entity.name.procedure.ablInternal and external procedure names
entity.name.tag.ablAnnotation names
entity.name.type.ablClass/interface/enum names
entity.name.type.generic.ablGeneric type names
entity.other.attribute-name.ablAnnotation attribute names
keyword.control.directive.conditional.abl&if , &else, &elseif, &end
keyword.control.directive.define.abl&scoped-define, &global-define, &undefine
keyword.operator.ablcontains, begins, matches, eq, le, lt, ge, gt, ne, <=, <>, >=, =, +, -, /, <, >, *, +=, -=, /=, *=, ?:
keyword.other.ablAny ABL keyword (incl those covered by other scopes like support.function.abl and entity.name.function.abl)
punctuation.accessor.abl: when used for method, property and attribute access. :: when used to reference buffer field names or dataset buffer names
punctuation.definition.bracket.square.begin.abl[ used for array arguments
punctuation.definition.bracket.square.end.abl] used for array arguments
punctuation.definition.generic.begin.abl< used for generic type arguments
punctuation.definition.generic.end.abl> used for generic type arguments
punctuation.definition.preprocessor.ablLeading & of referenced preprocessor and directives
punctuation.definition.string.begin.ablStarting " or ' of a quoted string
punctuation.definition.string.end.ablClosing " or ' of a quoted string
punctuation.section.abl{ and }
punctuation.separator.comma.abl,
punctuation.separator.continuation.abl~ at the end of a line (preprocessor)
punctuation.separator.period.abl.
punctuation.terminator.abl. and :
storage.data.database.ablStatically-defined database names, e.g.in the create alias statement
storage.data.dataset.ablStatically-defined dataset names, data-relation names
storage.data.table.abl(Temp-)Table names, field names, index names
storage.other.opsys-device.ablFiles and other operating system devices
storage.type.ablPrimitive datatypes
storage.type.function.abldefined keyword and preprocessor directives like &message
string.quoted.double.ablString in " quotes
string.quoted.single.ablString in ' quotes
support.function.ablopsys, proversion, ABL functions (eg base64-encode). Includes functions like today that have no or optional parameters. Note that transaction in a for each statement will be scoped this way
support.other.ablTranslation attributes :L, :R, :T, :C, :U
support.other.argument.abl&<name|number> arguments in includes
variable.language.ablABL system handles (eg session or this-object)
variable.other.ablVariable names
variable.parameter.ablParameter names in method, function, procedure definition

There are also a number of 'meta' scopes that usually cover multiple other scopes.

Scope NameUsed for/by
meta.argument.ablUnnamed arguments like {1}
meta.array.literal.ablLiteral values in an array
meta.block.ablA block statement like do, repeat and ` finally
meta.brace.round.abl( and )
meta.declaration.annotation.ablAn annotation from the @ to the .
meta.define.ablAn entire define statement
meta.define.class.ablA class definition, from the class keyword to its closing :
meta.define.enum.ablAn enum definition, from the enum keyword to its closing :
meta.define.function.ablA user-defined function definition, from the function keyword to its closing :
meta.define.interface.ablAn interface definition, from the interface keyword to its closing :
meta.define.method.ablA method, constructor or destructor definition, from the methodkeyword to the ending : or . Includes parameter definitions, if any.
meta.define.parameter.ablAn individual parameter definition
meta.define.stream.ablA stream definition
meta.define-type.implements.ablThe type names that a type implements and/or inherits
meta.function.arguments.ablCaptures what's between ( and ) when calling a function, excluding the braces
meta.function-call.ablThe name of an ABL function, including get-class, type-of and cast
meta.generic.ablGeneric type names
meta.include.ablInclude file references, from { to }
meta.include.argument.ablInclude argument references like &arg and &arg=
meta.preprocessor.ablPreprocessor definitions, functions and usage
meta.procedure.ablAn internal procedure definition, from the procedure keyword to its closing : or .
meta.statements.ablAll ABL statements
meta.using.ablA using definition

Checking scopes

The standard VS Code install includes a command (available via F1 or SHIFT-CTRL-P) named Developer: Inspect Editor Tokens and Scopes . This will pop a tooltip showing the scopes at the cursor location. It contains a group called textmate scopes , which shows the current scope. The topmost scope should be in the table above.

License

MIT