A VS Code extension that toggles comments correctly for CL/CLLE, RPG/RPGLE
(fixed and free format), and SQL source, all with one shortcut: Ctrl+/
(Cmd+/ on Mac).
What it does
| File type |
Extensions |
Comment style |
| CL / CLLE |
.cl, .clle |
Wraps the selection in /* ... */. If the selection touches a multi-line statement joined by trailing +/- continuation characters, the whole statement is expanded to and wrapped as one block, not commented line-by-line. |
| RPG / RPGLE |
.rpg, .rpgle, .sqlrpgle |
Detects fixed vs. free format per line: whole file is free-form if it starts with **FREE; otherwise /free ... /end-free blocks switch mode within an otherwise fixed-format member. Fixed-format lines get * inserted in column 7; free-form lines get // prepended. |
| SQL |
.sql |
Standard -- line comment toggle. |
The command is a single toggle: running it on already-commented lines
removes the comment; running it on plain code adds it — same behavior as
VS Code's built-in Ctrl+/, just language-aware for these IBM i types.
Any other file type falls back to VS Code's default editor.action.commentLine.
For RPG/RPGLE, Ctrl+Shift+/ (Cmd+Shift+/ on Mac) toggles comments for an
entire BEGSR/ENDSR, DCL-PROC/END-PROC, or DCL-PR/END-PR block in
one command — place the cursor anywhere inside the block (including right on
the begin/end line itself), no need to select every line.
It goes further than just the block, so disabling a procedure never leaves
dangling references behind. Also toggled, within the same file:
- The matching
DCL-PR/END-PR prototype, if the block is a procedure.
- Every call site referencing that name elsewhere in the file - a bare
call, one embedded inside another operation (
EVAL, DSPLY, anywhere an
expression can appear), or (for subroutines) an EXSR reference.
Direction is decided once from the block's own current state, not per line,
so the block, its prototype, and every call site always move together - a
notification summarizes what was touched, e.g. "Commented procedure
"proc1" (plus its prototype and 2 call sites)."
Other notes:
- Detection is keyword-based, not column-position-based, so it works for
fixed format, free format, and mixed-format members with
/free ...
/end-free blocks.
- If the cursor isn't inside a recognized block, or the block is
unterminated, you'll get a warning instead of a partial/incorrect edit.
- RPG subroutines and procedures don't nest, so there's no ambiguity about
which block "wins" - it's always the nearest enclosing one.
- Scope is the current file only - references in other files aren't touched.
Try it
- Open this folder in VS Code.
- Run
npm install.
- Press
F5 to launch an Extension Development Host.
- Open a
.cl, .rpgle, or .sql file, select some lines, press Ctrl+/.
Package for real use
npm install -g @vscode/vsce
npm install
npm run compile
vsce package
This produces a .vsix you can install via Extensions → ... → Install from VSIX.
A pre-built icomment-0.1.0.vsix is provided alongside this source for
quick testing, built with the official vsce package command.
It never fails — short lines are padded with spaces automatically:
- RPG fixed-format: if a line is shorter than column 7, it's padded with
spaces up to column 6 before
* is inserted at column 7 (a blank line
becomes *). Uncommenting replaces column 7 with a single space and
never shifts any other column.
- CL and SQL: comment markers are just inserted/appended as text, so
there's no fixed column to run out of space on.
Known limitations (worth knowing before relying on this)
- CL continuation detection is line-ending based. A line is treated as
continued if its last non-whitespace character is
+ or -. This does
not account for a +/- that appears as the last character inside a
quoted string (rare, but possible) — such a line would be incorrectly
treated as continuing.
- RPG fixed-format uncomment doesn't restore an overwritten conditioning
indicator. Commenting a fixed-format line writes
* into column 7.
Uncommenting clears column 7 back to a blank. If that column originally
held something other than a blank (unusual, but possible on older specs),
that original value is not preserved.
- Column-7 detection assumes 1 tab = 1 character (i.e., no literal tabs in
the source, which is standard for IBM i fixed-format members).
- Selections that end at column 0 of a later line (a common artifact of
dragging a full-line selection) are treated as not including that final
line, matching VS Code's normal line-comment behavior.
Extending
- To treat other extensions as CL/RPG/SQL, edit the
classify() function in
src/extension.ts.
- To change the RPG fixed-format comment column, change the
6 / 7
constants in toggleRpgFixedLine().