A powerful, AST-based code formatter for CFML (ColdFusion Markup Language) for Visual Studio Code.
This extension provides robust, opinionated code formatting for .cfm
and .cfc
files, inspired by Prettier. It parses your code into an Abstract Syntax Tree (AST) and then prints it back out, enforcing a consistent style. It intelligently handles mixed CFML, HTML, and even formats SQL within <cfquery>
tags without breaking your code logic.
Features
- AST-Based & Logic-Safe: More reliable than regex-based formatters. It understands CFML structure to format your code without altering the underlying logic.
- SQL Formatting: Automatically formats SQL inside
<cfquery>
blocks for improved readability.
- Code Modernization: Optionally rewrites legacy
CreateObject()
calls to the modern new
syntax and standardizes built-in function casing.
- Configurable: Adjust formatting options to match your team's style guide.
- Handles Mixed Content: Works seamlessly with CFML tags, HTML, and script blocks.
Usage
- Install the extension from the VS Code Marketplace.
- Open a
.cfm
or .cfc
file.
- Format the document by:
- Right-clicking and selecting "Format Document".
- Using the shortcut
Shift+Alt+F
(on Windows), Shift+Option+F
(on macOS), or Ctrl+Shift+I
(on Linux).
- Enabling "Format on Save" in your VS Code settings for automatic formatting.
Configuration
You can configure the formatter in your VS Code settings.json
file.
Setting |
Type |
Default |
Description |
cfmlFormatter.tabWidth |
number |
4 |
Number of spaces per indentation-level. |
cfmlFormatter.useTabs |
boolean |
false |
Indent using tabs instead of spaces. |
cfmlFormatter.quoteStyle |
string |
"double" |
The type of quote to use for attributes ("double" or "single" ). |
cfmlFormatter.formatSql |
boolean |
true |
Enable formatting for SQL code inside <cfquery> tags. |
cfmlFormatter.attributeThreshold |
number |
3 |
The number of attributes that must be exceeded to break them onto new lines. |
cfmlFormatter.pascalCaseBuiltInFunctions |
boolean |
true |
Convert built-in function calls (e.g., isdefined ) to PascalCase (IsDefined ). |
cfmlFormatter.preferNewOverCreateObject |
boolean |
true |
Convert CreateObject('component', ...) to the modern new Component() syntax. |
Example settings.json
{
"[cfml]": {
"editor.defaultFormatter": "AkhilTeotia.cfml-formatter-pro",
"editor.formatOnSave": true
},
"cfmlFormatter.tabWidth": 4,
"cfmlFormatter.quoteStyle": "double"
}
Before and After
Before:
<cfcomponent hint="Service for managing users" output="false">
<cffunction name="saveUser" access="public" returntype="numeric">
<cfargument name="userData" type="struct" required="true" />
<cftry>
<cfif StructKeyExists(arguments.userData, 'userId') AND arguments.userData.userId GT 0>
<!--- Update existing user --->
<cfquery name="qryUpdate" datasource="#variables.dsn#">
UPDATE users SET firstName = <cfqueryparam value="#arguments.userData.firstName#" cfsqltype="cf_sql_varchar" />, lastName = <cfqueryparam value="#arguments.userData.lastName#" cfsqltype="cf_sql_varchar" /> WHERE userId = <cfqueryparam value="#arguments.userData.userId#" cfsqltype="cf_sql_integer" />
</cfquery>
<cfreturn arguments.userData.userId />
<cfelse>
<!--- Insert new user --->
<cfquery name="qryInsert" datasource="#variables.dsn#" result="insertResult">
INSERT INTO users (firstName, lastName, email) VALUES (<cfqueryparam value="#arguments.userData.firstName#" cfsqltype="cf_sql_varchar" />, <cfqueryparam value="#arguments.userData.lastName#" cfsqltype="cf_sql_varchar" />, <cfqueryparam value="#arguments.userData.email#" cfsqltype="cf_sql_varchar" />)
</cfquery>
<cfreturn insertResult.generatedKey />
</cfif>
<cfcatch type="any">
<cflog file="UserService" type="error" text="Error saving user: #cfcatch.message#" />
<cfthrow type="DatabaseError" message="Failed to save user data" />
</cfcatch>
</cftry>
</cffunction>
</cfcomponent>
After:
<cfcomponent hint="Service for managing users" output="false">
<cffunction name="saveUser" access="public" returntype="numeric">
<cfargument name="userData" type="struct" required="true" />
<cftry>
<cfif StructKeyExists(arguments.userData, 'userId') AND arguments.userData.userId GT 0>
<!--- Update existing user --->
<cfquery name="qryUpdate" datasource="#variables.dsn#">
UPDATE
users
SET
firstName = <cfqueryparam value="#arguments.userData.firstName#" cfsqltype="cf_sql_varchar" />,
lastName = <cfqueryparam value="#arguments.userData.lastName#" cfsqltype="cf_sql_varchar" />
WHERE
userId = <cfqueryparam value="#arguments.userData.userId#" cfsqltype="cf_sql_integer" />
</cfquery>
<cfreturn arguments.userData.userId />
<cfelse>
<!--- Insert new user --->
<cfquery name="qryInsert" datasource="#variables.dsn#" result="insertResult">
INSERT INTO
users (firstName, lastName, email)
VALUES
( <cfqueryparam value="#arguments.userData.firstName#" cfsqltype="cf_sql_varchar" />, <cfqueryparam value="#arguments.userData.lastName#" cfsqltype="cf_sql_varchar" />, <cfqueryparam value="#arguments.userData.email#" cfsqltype="cf_sql_varchar" /> )
</cfquery>
<cfreturn insertResult.generatedKey />
</cfif>
<cfcatch type="any">
<cflog file="UserService" type="error" text="Error saving user: #cfcatch.message#" />
<cfthrow type="DatabaseError" message="Failed to save user data" />
</cfcatch>
</cftry>
</cffunction>
</cfcomponent>
Built with ❤️ for the CFML community.