ooRexx Language for VS Code
Make Rexx and ooRexx programs easier to read with language-aware highlighting,
ooRexx Dark and ooRexx Light themes, instruction and function syntax hints, and hover
explanations for possible mistakes. Built for ooRexx 5.2.0.
Get started
- Install ooRexx Language by YancyFox.
- Open a
.rex or .rexx file. If needed, select ooRexx using the language
name in the bottom-right corner of VS Code. .cls files are also supported;
because other languages use that extension, check the selected language.
- When asked “Use an ooRexx enhanced color theme?”, choose ooRexx Dark,
ooRexx Light, or Keep Current Theme.
- Hover over a red, underlined name to see an explanation or spelling suggestion.
Choose ooRexx Dark or ooRexx Light to get all of the highlighting described
below. Other themes may not display the special object/value colors, stem and
compound-variable colors, special Rexx-name colors, or red text and underlining
for possible mistakes and unused variables.
You do not need an ooRexx installation for highlighting. The extension examines
text as you edit; it does not run your program. Running Rexx programs requires
an interpreter installed separately.
Completion lists and Tab
Start a word with a capital letter to see matching ooRexx keywords and
functions. Type S for names such as Say, Select, Sign and Substr;
type more letters to narrow the list. Core built-ins and the extension’s
RexxUtil function catalog are included. After ~ or ~~, the list offers the
supported String methods. Typing :: immediately opens all nine directive names,
including Class, Method, Requires, and Routine. Continue typing to filter
(case-insensitively), then press Tab to insert the selected name after ::.
Completions use capitalized names such as Say, Substr and Left; RexxUtil
names retain their conventional spelling, such as SysFileTree. Your variable
spelling is preserved, including camelCase names such as myVar.
Use the arrow keys to select a suggestion and press Tab to insert it.
The extension enables Editor: Tab Completion for ooRexx. Completion inserts
only the name, so you can add a space for an instruction or ( for a function
or method and continue with the parameter hints. Existing parentheses are
preserved when replacing a name in the middle of a line.
Lowercase initials, comments, string literals, resource bodies and compound
variable names do not get this extension’s completion list. VS Code may still
offer its own word suggestions. Set oorexx.completions.enabled to false to
disable the feature. Automatic lists use VS Code’s Editor: Suggest On Trigger
Characters setting; Ctrl+Space can reopen suggestions for a capitalized
prefix. If you have overridden Editor: Tab Completion for ooRexx, set it to
on to enable Tab completion. Open examples/completions.rex to try it.
Instruction and function syntax hints
While typing, the popup shows only the next parameter or keyword. It updates
as you enter values and separators, and moves back when you edit earlier text.
For example:
| You have typed |
Next hint |
ADDRESS |
[environment (SYSTEM, COMMAND, ...) \| VALUE] |
ADDRESS SYSTEM |
[command expression \| WITH] |
ADDRESS SYSTEM 'echo Hello' WITH |
INPUT \| OUTPUT \| ERROR |
USE STRICT |
ARG |
USE STRICT ARG |
[parameter name \| ...] |
USE STRICT ARG name = |
default value |
DO i = 1 TO |
limit expression |
SUBSTR( |
string |
SUBSTR(text, |
start |
SUBSTR(text, 2, |
[length] |
CALL WORD text, |
word number |
'This is a string'~Left( |
length |
myVar~SubStr(1, |
[length] |
Call SysFileTree pattern, |
result stem or array |
Call SysSleep |
seconds |
In syntax hints, UPPERCASE identifies keywords and fixed option values;
lowercase identifies data you supply, such as file name or length. For
example, ON / OFF offers fixed choices, while [A (ascending) / D (descending)]
shows option letters with lowercase explanations. This also applies to full
signatures on hover and in completion details. Completion names still use your
capitalized style, such as Say and Substr.
Square brackets mark optional parts; | separates alternatives. Popups contain
no explanations or examples. Hover over the instruction, function or supported method name when you want
its complete syntax and examples. Both forms of help work with any theme.
Press Escape to dismiss a popup. Reopen it with Trigger Parameter Hints
from the Command Palette (normally Ctrl+Shift+Space on Windows/Linux).
Typing a space, tab, comma, parenthesis, equals sign, or quote can trigger a
hint when the cursor is in an instruction or function call. The guide recognizes
all 35 instruction/control keywords, 84 core built-in function names, and all
74 names in the RexxUtil completion catalog.
Function hints follow commas at the current call level, including omitted
arguments. Nested calls show the inner function’s parameter, then return to the
outer call when closed. The same function signatures work with CALL syntax.
The String method equivalents also have hints: the receiver supplies the string
or number, so text~Left( starts with length, while text~SubStr( starts with
start. These are String syntax guides selected by method name; a custom class
can define a method with different parameters.
All nine directives also have next-part hints. After accepting Method from the
:: list, press Space to see method name. After entering the name and another
space, the hint offers available options; DELEGATE prompts for delegate name.
Likewise, ::Requires prompts for filename, followed by [LIBRARY | NAMESPACE];
NAMESPACE prompts for namespace name. Keywords are uppercase and data
placeholders lowercase. Hover over a directive name for its full syntax guide.
Try examples/directive-hints.rex.
Hints use explicit keywords, separators and expression structure to identify
the next part; a space within an unfinished expression does not start a new
parameter. Optional continuations may be offered when an expression could
already end. These prompts are guidance, not instruction validation. They do
not insert code. User-defined routines, other method signatures,
and host command syntax are outside this feature. Internal labels
that override built-in function names suppress those built-in hints. Existing
highlighting checks are independent.
RexxUtil hover and completion details include signatures, descriptions and platform
notes. Hover also includes examples. Popups remain one parameter at a time,
including Call forms and omitted arguments. Windows-only and Unix-only
utilities remain available in help when editing code for another platform.
Open examples/syntax-hints.rex, examples/function-hints.rex, or
examples/rexxutil-hints.rex to try the prompts. If automatic popups do not
appear, check Editor: Parameter Hints: Enabled. Set
oorexx.syntaxHints.enabled to false to disable both popups and syntax
hover help. To retain hover help while stopping automatic popups, turn off
Editor: Parameter Hints: Enabled instead.
Two themes designed for ooRexx
ooRexx Dark uses a dark gray background. ooRexx Light uses a white
background. Both use the same categories, with colors adjusted for readability.
Bold text emphasizes classes, declarations, known object references, and special
Rexx names. Recognized built-in methods use italics.
| What you are reading |
Example |
ooRexx Dark |
ooRexx Light |
| Variable holding a known object or class reference |
items = .Array~new |
Gold |
Dark gold |
| Variable holding a known string, number, or boolean |
count = 10 |
Light blue |
Blue |
| Stem or compound variable |
items. or items.index |
Light purple |
Purple |
| Class name |
.Array, .Greeting, ::class Greeting |
Teal |
Dark teal |
| Method call |
items~append(1), widget~render |
Teal |
Dark teal |
| Recognized built-in method |
.Array~new, items~append(1) |
Teal, italic |
Dark teal, italic |
| Function call |
length(text) |
Pale yellow |
Brown |
| Method or routine declaration |
::method render, ::routine greet |
Bold in its category color |
Bold in its category color |
| Special Rexx name |
RC, RESULT, SIGL, SELF, SUPER, .TRUE, .FALSE, .NIL |
Orange |
Dark orange |
| Instruction or directive keyword |
SAY, PARSE, ::CLASS |
Purple-pink |
Purple |
| Hex / binary string |
'4869'X, '01001000'B |
Purple / blue |
Purple / blue |
| String / number / comment |
'Hello', 42, /* comment */ |
Salmon / light green / muted green |
Dark red / green / muted green |
| Possible mistake or unused variable |
lenght(text), an unused assignment |
Red and underlined |
Red and underlined |
Ordinary variables whose values are unknown use the theme's normal variable
color. Red warnings take precedence over ordinary value colors.
The object/value colors are reading aids. In ooRexx, strings and numbers are
objects too; these colors distinguish familiar simple values from references
to constructed objects and class objects when the extension can determine the difference.
Choosing or changing a theme
Open the Command Palette and run Preferences: Color Theme, then select
ooRexx Dark or ooRexx Light. No settings-file edits are needed.
The first-use prompt appears once. Choosing Keep Current Theme or dismissing
it keeps your existing theme. Later manual theme changes are respected.
A theme applies to the whole VS Code window. The bundled themes include general
colors for other languages and additional rules specifically for ooRexx. They
remain selected when you switch between languages.
Some highlighting features will not appear in other themes unless those themes
support the extension's ooRexx color rules. Selecting Keep Current Theme or
switching to another theme can mean losing:
- Bold gold for known object references and blue for simple values.
- Purple for stems and compound variables.
- Orange emphasis for special Rexx names such as
RC and .NIL.
- Distinct function/method colors and italic emphasis for recognized built-in methods.
- Red text and underlining for possible mistakes and unused variables.
The extension still checks your code, and hover explanations remain available
for detected issues, even when your theme does not visibly mark them. Select
ooRexx Dark or ooRexx Light to see the full set of highlighting features
without configuring individual colors yourself.
Rexx and ooRexx highlighting
- Variables and changing values: follow simple assignments and copies so a
variable's color can change when it is assigned a different kind of value.
- Stems and compound variables: recognize Rexx names such as
records. and
records.index, along with parameters and exposed variables.
- Functions and methods: distinguish function calls from message sends using
~ and ~~, including chained messages and cascades.
- Classes and methods you write: recognize class, method, routine, attribute,
and constant declarations in the current file, plus public classes and supported
inherited methods from
::REQUIRES source files.
- Built-in methods: check methods against the known class of the object,
using an ooRexx 5.2.0 catalog covering 57 core classes and inherited methods.
Class methods and methods on instances are checked separately.
- Rexx syntax: recognize instructions, directives, labels,
USE ARG,
PROCEDURE, EXPOSE, PARSE templates, strings, numbers, line continuations,
-- comments, and nested /* ... */ comments.
The example in both themes
These images show the example using the extension's ooRexx Dark and ooRexx Light
colors. They retain those colors regardless of the theme used to view this page.


Copy the example: the text below is provided for copying. Open it in an
ooRexx editor with a bundled theme to see the highlighting shown above.
items = .Array~new
items~append('Hello')
items~~append('Rexx')~~append('ooRexx')
say items~items
say length('Hello')
widget = .Greeting~new
say widget~render
::class Greeting
::method render
return 'Hello from ooRexx'
Here, length() is a function, new and append are recognized built-in
methods, and render is a method defined in your Greeting class. A method is
checked against the class receiving the message; a method supported by one
class is not automatically valid for every class.
Red text, underlining, and hover explanations
The bundled themes use red text with underlining for these checks:
| Check |
What it looks for |
Example hover |
| Misspelled instruction or directive |
A close match in a position where an instruction or directive is expected |
“Possible misspelled instruction: sya. Did you mean SAY?” |
| Invalid dependency |
An unreadable required source file, missing filename, or unclosed filename quote |
“Required file could not be read: logger.cls” |
| Unresolved reference |
A dot-prefixed or qualified reference whose definition could not be resolved |
“Unresolved reference: .Logger” |
| Missing object reference |
A variable assigned from an unresolved reference, including aliases |
“Missing object reference: log” |
| Missing method |
A method absent from the known class and its checked parents, when dynamic handling does not prevent the check |
“Method not found: apend” |
| Unused variable |
An assigned or declared local variable whose value does not appear to be used, excluding known object-reference assignments |
“Unused variable: r. Its value does not appear to be used.” |
Spelling hovers also explain that an intentional command or external routine
may have the name you entered. Unknown function and command names without a close spelling match
are not automatically marked as mistakes. Unresolved dot-prefixed references
are checked separately.
Checks include methods on user-defined classes in the current file and resolved
::REQUIRES source files. For
example, if Greeting defines render, widget~rener can be marked as a missing
method when widget is known to hold a Greeting object. The warning concerns
the method name; the class has been recognized. An UNKNOWN method can handle
otherwise unrecognized messages, so its presence can prevent a missing-method
warning.
Hover explanations appear on detected issues. A normal method color identifies
a message send; it does not mean the method was verified. If a receiver cannot
be resolved, the extension flags the reference without adding cascading
missing-method warnings. Methods on recognized environment entries are not
validated. Ordinary names do not have general reference-documentation hovers.
These checks provide highlighting and explanations; they do not add compiler
errors to the Problems panel.
Classes from required files
The extension reads ::REQUIRES source files to recognize their public classes
and check supported methods. Class names come from declarations, not filenames:
telnet.cls can export a class named Logger.
loggerClass = .Logger
log = loggerClass~new
log~write('Hello')
::requires "telnet.cls"
If telnet.cls declares ::class Logger public with ::method write, the
extension recognizes .Logger, colors loggerClass and log as object
references, and can flag a misspelled method such as log~writ. Namespaces such
as net:Logger are also supported with ::requires "telnet.cls" namespace net.
Private dependency classes are not exposed to the caller, but can contribute
inherited methods to public classes.
Required files are searched for in the requiring file's folder, the workspace
folder, additional oorexx.dependencies.searchPaths, then REXX_PATH and
PATH. Extensionless names also try the caller's extension and .rex, .rexx,
and .cls. Relative configured paths start at the workspace folder.
Checks use unsaved contents of open dependency files and refresh when files
change. An unresolved reference is red and underlined, with a short hover such
as Unresolved reference: .Logger. An unreadable source filename or malformed
filename quote on ::REQUIRES is marked separately. Resolving the dependency
allows imported methods to be checked. Variables assigned from an unresolved
reference, and copies of those variables, are red with Missing object reference: log
hovers. Reassigning a variable clears its bad-reference state for subsequent
uses; existing aliases retain their own state. Unknown receiver methods are
not reported as missing. Dependency scanning is bounded to 100
files, 32 levels, and approximately 4 MiB of source text.
Reference lookup and environment entries
Reference identity does not depend on the following method name: .Logger~Ne()
and .Logger~New() resolve .Logger in the same way. Constants .true, .false,
and .nil take precedence; local classes and imported public classes are checked
before built-in classes, followed by known environment entries. The REXX:
namespace explicitly selects built-in classes.
The extension recognizes explicit environment entry names such as
.local["MY.APP.OBJECT"] = value, .environment~my.app.object = value, and
.local~setEntry("MY.APP.OBJECT", value). It recognizes the name without assuming
the object's runtime class, and skips validation of methods on that entry.
Simply using an environment entry does not disable checks on unrelated known
class instances. Computed keys, runtime registrations, and package-local entry
writes are not resolved by this limited static analysis. An Unresolved
reference warning describes what the editor could establish, not proof of a
runtime error.
Known object-reference assignments are exempt from unused-variable warnings.
Updating an element of a stem received through USE ARG or USE STRICT ARG
also counts as using the passed stem: the caller can observe that update, even
without a local read. See examples/stem-argument-usage.rex.
For example, myMonitor = .MyMonitor~New() may perform useful work in Init
without the reference being read later. The exemption applies to that assignment;
an unused simple value later assigned to myMonitor can still be marked.
Class and method checks remain active. String, number, and boolean values retain
their simple-value treatment even though they are also objects in ooRexx.
When a check may be skipped
Rexx permits external routines, commands, and behavior determined while the
program runs. The extension cannot always determine which variables or methods
will be used. In particular:
Built-in, registered, external and unresolved function calls preserve unrelated
object references and unused-variable checks. Unresolved function names are not
reported as errors or spelling suggestions. log=someFunction() is a simple
variable assignment; .Logger~New() establishes an object reference. An
assignment to log does not change an earlier alias of it.
Standalone commands, including function results used as commands, keep
possible unused-variable warnings visible. Their hovers explain that a command
may use variables by name.
INTERPRET, variable references, explicit ADDRESS instructions, unfinished
code, and dynamic variable access can prevent reliable unused-variable checks. Exposed properties and
special Rexx variables are excluded from unused-variable warnings.
Public classes in ::REQUIRES source files are indexed; imported routines
are not. Unreadable or circular dependencies, native libraries, dynamic method
changes, and complex inheritance can prevent complete class or method checks.
Reference tracking uses an editing assumption: written assignments take effect
in source order, without proving conditions true or simulating loop iterations.
A constructor in If, Select/When, Do or Loop establishes a reference
for subsequent code. Branches do not have to agree. An Otherwise Exit does
not discard a Logger established in a When branch.
Explicit changes still matter: log=123 changes subsequent uses to String
method checking; an alias made earlier retains its Logger reference. Drop log
removes the assumption. An assignment in a later branch supersedes an earlier
assignment in source order. Unknown results or explicit dynamic effects may
remove information. Earlier references are not recolored by later writes.
Try examples/logger-editor-assumptions.rex.
Internal routines use known caller bindings, including names listed in
Procedure Expose. Each internal label has its own analysis block. Without an observed call,
the editor uses the enclosing main block’s tracked bindings as its starting
context; it does not copy locals from a preceding routine. Actual caller
information takes precedence. An unconditional routine-level Return ends that invocation’s analysis,
while following labels are analyzed independently. Construction inside a called
routine with Procedure Expose log supplies the caller with the same Logger
reference and method checks. A plain Procedure still isolates locals; conflicting callers and
unknown effects remain conservative. Try examples/logger-routines.rex.
A known internal Call keeps method checks enabled when loading ::Requires
definitions; an external call also keeps those checks enabled.
Known String values also feed method checking across routine boundaries: after
log = '123', log~Message() reports Method not found: Message.
Unassigned, non-exposed Procedure locals receive String method checking too.
Statements after an unconditional routine-level Return or Exit, before
another label or directive, are flagged as Unreachable code. The entire
line is bold red without underlining, including arguments and punctuation, with a hover
explanation shown once per line. A Return does not resume main-program code below the routine.
Conditional returns and infinite-loop reachability are outside this local check.
Try examples/unreachable-return.rex.
These assumptions are editing aids, not runtime proofs. Unknown results and
dynamic effects limit available information. Method arguments, visibility, and
all runtime errors are not validated.
An unmarked name is not a guarantee that the program is correct. This extension
provides editing aids; use the ooRexx interpreter to validate and run your code.
Settings
Open VS Code Settings and search for ooRexx.
| Setting |
Default |
Purpose |
ooRexx › Checks: Typos (oorexx.checks.typos) |
On |
Enable suggestions for possible misspelled instructions and directives. |
ooRexx › Checks: Unused Variables (oorexx.checks.unusedVariables) |
On |
Enable unused local-variable highlighting and hover explanations. |
ooRexx › Dependencies: Search Paths (oorexx.dependencies.searchPaths) |
[] |
Additional directories to search for required source files. Relative paths start at the workspace folder. |
These settings can be changed for an individual workspace. Semantic highlighting
is enabled for ooRexx by default. To see the full color distinctions described
above, select one of the bundled themes.
Examples and feedback
The extension package includes examples for exploring the features:
examples/reference-checks.rex — short warnings, constructor typos, and environment entries.
examples/requires-test.rex — a working Logger import with instructions for testing missing files, imports, and methods.
examples/logger-checks/ — focused dependency and method checks, with expected results in its README.
examples/dependencies/main.rex and examples/dependencies/telnet.cls — imported classes, class aliases, and a deliberate method typo.
examples/highlighting.rex — general Rexx and ooRexx syntax.
examples/theme-preview.rex — theme categories and method calls.
examples/editor-checks.rex — deliberate mistakes and unused variables.
examples/value-changes.rex — variables receiving different kinds of values.
examples/parse-templates.rex — Rexx parsing templates.
examples/procedure-scopes.rex — internal routines, PROCEDURE, and EXPOSE.
The theme-preview, editor-checks, dependency, and numbered Logger error samples
include deliberate mistakes for editor inspection. When reporting unexpected highlighting, include a small
Rexx example, the extension version, and the selected theme.
About this extension
Requires VS Code 1.85 or later. Highlighting runs locally without executing
Rexx code or sending your source to a service. The extension provides syntax and
semantic highlighting, themes, and the checks described here. It does not include
a debugger, compiler, or project-wide language server.
For source builds, run npm test to check the extension and npm run package
to create a VSIX. Use Extensions: Install from VSIX… to install that package.
Development details are retained in docs/implementation-notes.md in the source.
MIT License. Copyright (c) 2026 Yancy Fox.