TextMate grammar for Progress OpenEdge ABL Language
npm install abl-tmlanguageIt's used in the OpenEdge ABL for Visual Studio Code extension.
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 Name | Used for/by |
| ------------- | ------------- |
|comment.block.source.abl | Everything between
/ and / |
|comment.line.double-slash.abl | Everything in a // comment, incl. slashes |
|comment.preprocessor.analyze-suspend.abl | &analyze-suspend, &analyze-resume |
|constant.character.escape.abl | ~ and the next char |
|constant.language.abl | today, now, true, false, yes, no, ? (unknown value) |
|constant.language.source.abl | 99/99/9999 (or similar) when used as a format clause |
|constant.numeric.source.abl | 0x00-0xFF, 0-9, scientific notation |
|entity.name.function.abl | Method call, property call, method name, property name, handle attributes, handle methods, event names |
|entity.name.function.preprocessor.abl | Preprocessor names, including built-ins like opsys and process-architecture |
|entity.name.include.abl | Include file names |
|entity.name.label.abl | Block label names |
|entity.name.package.abl | Package names for using |
|entity.name.procedure.abl | Internal and external procedure names |
|entity.name.tag.abl | Annotation names |
|entity.name.type.abl | Class/interface/enum names |
|entity.name.type.generic.abl | Generic type names |
|entity.other.attribute-name.abl | Annotation attribute names |
|keyword.control.directive.conditional.abl | &if , &else, &elsif &end |
|keyword.control.directive.define.abl | &scoped-define, &global-define, &undefine |
|keyword.operator.source.abl | contains, begins, matches, eq, le, lt, ge, gt, ne, <=, <>, >=, =, +, -, /, <, >, , +=, -=, /=, =, ?: |
|keyword.other.abl | Any ABL keyword (incl those covered by other scopes like support.function.abl and entity.name.function.abl) |
|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.abl | Leading & of referenced preprocessor and directives |
|punctuation.definition.string.begin.abl | Start of a quoted string |
|punctuation.definition.string.end.abl | End of a quoted string |
|punctuation.section.abl | { and } |
|punctuation.separator.comma.abl | , |
|punctuation.separator.continuation | ~ at the end of a line (preprocessor) |
|punctuation.separator.period.abl | . |
|punctuation.separator.colon.abl | : |
|punctuation.terminator.abl | . and : |
|storage.data.database.abl | Statically-defined database names, e.g.in the create alias statement |
|storage.data.dataset.abl | Statically-defined dataset names, data-relation names |
|storage.data.table.abl | (Temp-)Table names, field names, index names |
|storage.other.opsys-device.abl | Files and other operating system devices |
|storage.type.abl | Primitive datatypes |
|storage.type.function.abl | defined keyword and preprocessor directives like &message |
|string.quoted.double.abl | String in " quotes |
|string.quoted.single.abl | String in ' quotes |
|support.function.abl | opsys, proversion, ABL functions (eg base64-encode) |
|support.other.abl | Translation attributes :L, :R, :T, :C, :U |
|support.other.argument.abl | & arguments in includes |
|variable.language.abl | ABL system handles (eg session or this-object) |
|variable.other.abl | Variable names |
|variable.parameter.abl | Parameter names in method, function, procedure definition |There are also a number of 'meta' scopes that usually cover multiple other scopes.
| Scope Name | Used for/by |
| ------------- | ------------- |
|meta.argument.abl | Unnamed arguments like
{1} |
|meta.array.literal.abl | Literal values in an array |
|meta.block.abl | A block statement like do, repeat and finally |( and ) |@ to the . |define statement |class keyword to its closing : |enum keyword to its closing : |function keyword to its closing : |interface keyword to its closing : |methodkeyword to the ending : or . Includes parameter definitions, if any. |get-class, type-of and cast |{ to } |&arg and &arg= |procedure keyword to its closing : or . |using definition |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.