⚡Write Oracle CPQ BML in VS Code - with autocomplete, error checking, and the Oracle docs built in.
🤔 Why this exists
Oracle CPQ makes you write BML in a small text box in the admin UI. There is no autocomplete, no error checking, and no way to look up a function without opening the Oracle documentation in another tab.
So most people copy their BML into a real editor, work on it there, and paste it back.
This extension makes that editor understand BML.
|
You get |
| 💡 |
Autocomplete for all 173 BML functions, with their parameters |
| 🚨 |
Error checking as you type, with one-click fixes |
| 📚 |
The Oracle BML documentation, searchable inside VS Code, with no internet connection |
| 🗄️ |
BMQL support - highlighting and validation inside your query strings |
| 🧹 |
A formatter, hover help, snippets, and 18 colour themes |
🚀 Quick start
1️⃣ Install the extension
2️⃣ Create a file ending in .bml
3️⃣ Start typing a function name - for example json
That's it. Autocomplete, error checking and hover help all switch on automatically. ✨
💭 Tip: you can also work in a .txt, .java or .c file. Autocomplete, hover help and snippets work there too, which is handy for quick drafts.
🎁 What you get
Everything below is ordered by what you will reach for most.
💡 Autocomplete for every BML function
Start typing and every BML function appears, with its signature and description. Pick one and the arguments are filled in as placeholders - press Tab to jump between them.
It also suggests:
- 🔤 Variables you have already used in the file
- 🔑 BML keywords -
if, elif, for … in, AND, OR, NOT, throwError
- 🧩 Code templates - loops,
if/elif chains, the standard script header comment
🚨 Error checking as you type
Mistakes are underlined in your editor straight away, the way a compiler would show them.
15 checks run automatically - see the full list in Error checking reference below.
🎯 Two checks a generic linter cannot do
Wrong number of arguments - every call is checked against Oracle's own published signature, so a mistake surfaces while you type instead of at runtime on a quote:
expiry = adddays(startDate); // documented as taking 2 arguments, but 1 was given
value = jsonget(payloadJson); // documented as taking 2 to 4 arguments, but 1 was given
put(headerDict); // documented as taking 3 arguments, but 1 was given
Your own util library functions are never checked - only the ones the extension has a signature for. It is a Warning rather than an Error because Oracle's documentation is not always complete.
Queries and web service calls inside loops - the classic reason a quote gets slow:
for line in line_process {
partRecords = bmql("SELECT ... WHERE part_number = $partNum"); // one query per line
response = urldata(url, "GET", headerDict); // one HTTP call per line
}
On a 200-line quote that is 200 round trips. It looks fine when you test with three lines. Run the query once outside the loop and look the results up from a dictionary instead.
🔧 One-click fixes
Click the 💡 next to an underlined problem and pick a fix:
| ❌ Problem |
✅ Fix |
| Missing semicolon |
Adds it |
isnull x |
Changes it to isnull(x) |
| Two statements on one line |
Splits them onto separate lines |
print with no debug guard |
Wraps it in if (debug) { … } |
| Badly named variable |
Renames it to the suggested name |
| Unused variable |
Removes the line |
Every problem also offers 🔕 "Disable this rule", which writes the setting for you. There is also a ⚡ Fix all action for the whole file.
🖱️ Hover help
Hover over any function to see what it does, its parameters, what it returns, and an example - without leaving your file.
🔮 Parameter hints
While you are typing a function call, the current parameter is highlighted so you know which argument you are on. It works correctly with nested calls like jsonput(obj, "key", upper(name)).
📚 The Oracle documentation, offline
The Documentation panel in the sidebar contains the complete Oracle CPQ BML reference - 28 pages covering every function category, BMQL, the Function Editor and BML coding practices - fully searchable, with no internet connection needed. ✈️
🖱️ Right-click any function in your code and choose Show Documentation for Function at Cursor to jump straight to its page.
🌐 Need something the bundled copy does not cover? The Live help button opens the current Oracle help site in an editor tab, on the same topic you were reading. That one needs an internet connection.
🗄️ BMQL support
BMQL queries are no longer just plain strings:
- 🎨 Highlighting inside
bmql("...") for SELECT, FROM, WHERE, JOIN, ORDER BY, operators, and your $boundVariables
- 🔍 Checks for a
SELECT with no FROM, an INSERT with no INTO, ORDER BY grouped with DISTINCT (which BMQL does not allow), and empty queries
- ⚠️ A warning when a WHERE clause compares against a variable without the required
$ - easy to miss, and it fails at runtime
✅ Variables you bind into a query with $ are correctly counted as used, so they are never wrongly reported as unused.
Press Shift+Alt+F to tidy up indentation and spacing. It understands BML syntax that normal formatters do not - elif, for x in list, AND/OR, and <>.
📏 It uses your editor's tab size and tabs-or-spaces setting.
Browse and search every function by category, in collapsible sections. Each entry shows the syntax, a description and an example, with buttons to 📋 copy it or ➕ insert it at your cursor.
✂️ Snippets
Type a prefix like bml-json or bml-urldata-get and press Tab. Over 200 snippets cover every function plus common patterns like loops and if/elif chains.
🧭 Getting around large files
- 🗂️ Outline view lists your top-level variables and blocks
- 📁 Folding - wrap a section in
// #region Name … // #endregion to collapse it
- ✏️ Rename - put the cursor on a variable and press
F2 to rename it everywhere in the file. Unlike find-and-replace, it will not change matches inside strings or comments
📂 Works in other file types
Drafting BML inside a .txt, .java or .c file? Autocomplete, hover help, parameter hints and snippets all work there too.
🎨 Themes
18 built-in colour themes tuned for reading BML - Dracula, Monokai, Nord, One Dark Pro, GitHub Dark/Light, Solarized and Notepad++ lookalikes.
🚨 Error checking reference
All 15 checks, and whether a one-click fix is available.
|
Check |
What it catches |
Default |
Quick fix |
| 🔴 |
missing-semicolon |
A statement that does not end in ; |
Error |
✅ |
| 🔴 |
missing-parentheses |
isnull x instead of isnull(x) - also upper, lower, not |
Error |
✅ |
| 🔴 |
multiple-statements-per-line |
More than one statement on a line |
Error |
✅ |
| 🟡 |
unreachable-code |
Code after a return or throwError that can never run |
Warning |
- |
| 🟡 |
nested-loop-depth |
Loops nested more than 2 deep (slow in CPQ) |
Warning |
- |
| 🟡 |
naming-convention |
Array, dictionary, record set or boolean names that break the Oracle convention |
Warning |
✅ |
| 🟡 |
line-too-long |
A line over 200 characters |
Warning |
- |
| 🟡 |
bmql-syntax |
Problems inside a bmql("...") query |
Warning |
- |
| 🟡 |
expensive-call-in-loop |
A BMQL query or web service call inside a loop, so it runs once per iteration |
Warning |
- |
| 🟡 |
argument-count |
A function called with a number of arguments its documented signature does not allow |
Warning |
- |
| 🔵 |
unused-variable |
A variable you assign but never read |
Info |
✅ |
| 🔵 |
empty-block |
A { } block with nothing in it |
Info |
- |
| ⚪ |
unguarded-print |
A print not wrapped in if (debug) |
Hint |
✅ |
| ⚪ |
brace-style |
Code sharing a line with an opening or closing brace |
Hint |
- |
| ⚪ |
dictionary-comment |
A dict(...) with no //Key: … Value: … comment explaining it |
Hint |
- |
📖 These follow Oracle's own BML Coding Best Practices.
🎚️ Any of them can be turned off or changed - see Settings below.
⌨️ Commands
Open the Command Palette with Ctrl+Shift+P (Cmd+Shift+P on Mac) and type Developer Tools for CPQ.
|
Command |
What it does |
| 🔍 |
Search BML Functions |
Search all 173 functions and insert one at your cursor. Also on the right-click menu. |
| 📖 |
Show Documentation for Function at Cursor |
Opens the offline docs at the function you are on. Also on the right-click menu. |
| 📚 |
Browse Oracle CPQ Documentation |
Opens the offline documentation panel. |
| 🌐 |
Open Oracle CPQ Help Online |
Opens the live Oracle help site in an editor tab. Needs an internet connection. |
| 🗂️ |
Open Docs Explorer |
Opens the BML Functions sidebar. |
| ✅ |
Validate All BML Files in Workspace |
Checks every .bml file in your project, not just the open ones. |
| 🧹 |
Format Document (Shift+Alt+F) |
Formats the current BML file. |
⚙️ Settings
Open Settings (Ctrl+,) and search for CPQ.
| Setting |
Default |
What it does |
cpqTools.validation.enable |
true |
Turn all error checking on or off. |
cpqTools.validation.run |
onType |
Check as you type, or only when you save (onSave). |
cpqTools.validation.rules |
{} |
Turn individual checks off or change how serious they are. |
cpqTools.validation.maxLineLength |
200 |
When line-too-long starts complaining. |
cpqTools.validation.maxLoopDepth |
2 |
How deeply loops may nest before nested-loop-depth complains. |
cpqTools.validation.attributeSuffixes |
["_quote", "_line", "_c"] |
Name endings that mark a CPQ attribute. These are never reported as unused variables. |
cpqTools.completion.enable |
true |
Turn autocomplete on or off. |
cpqTools.format.useEditorIndent |
true |
Format using your editor's indentation instead of a fixed 4 spaces. |
🔕 Turning off a check you disagree with
The easiest way is to click the 💡 on the problem and choose Disable this rule.
To do it by hand, add this to your settings.json:
"cpqTools.validation.rules": {
"unused-variable": "off", // silence it completely
"unguarded-print": "off",
"line-too-long": "warning" // or just change how serious it is
}
Each check can be set to off, hint, information, warning, error, or default.
📥 Installing
1️⃣ Open VS Code
2️⃣ Press Ctrl+Shift+X to open Extensions
3️⃣ Search for "Developer Tools for CPQ"
4️⃣ Click Install
💬 Questions or problems?
⭐ If you find this useful, a review on the Marketplace helps other CPQ developers find it.
Made for Oracle CPQ developers, by an Oracle CPQ developer.
Not an official Oracle product. Oracle and CPQ are trademarks of Oracle Corporation.