A production-ready VS Code extension that provides intelligent formatting for CFML (ColdFusion Markup Language) files using AST-based parsing, similar to Prettier.
Features
- AST-based formatting: Uses proper parsing instead of regex rules for reliable results
- Mixed content support: Handles HTML, CFML tags, CFScript, and SQL seamlessly
- Intelligent tag relationships: Understands CFML sibling tags like
cfelse
, cfelseif
- Customizable formatting: Configurable indentation, quotes, and formatting preferences
- SQL formatting: Automatically formats SQL inside
<cfquery>
tags
- Preserve developer intent: Maintains meaningful whitespace in appropriate contexts
- Robust error handling: Gracefully handles malformed markup without crashes
Supported File Types
.cfm
- ColdFusion pages
.cfc
- ColdFusion components
.cfml
- ColdFusion markup files
Installation
From VS Code Marketplace
- Open VS Code
- Go to Extensions (Ctrl+Shift+X)
- Search for "CFML Prettier Formatter"
- Click Install
Manual Installation
- Clone this repository
- Run
npm install
- Run
npm run compile
- Press F5 to open a new Extension Development Host window
- Test the extension with CFML files
Usage
- Format Document:
Shift+Alt+F
(Windows/Linux) or Shift+Option+F
(Mac)
- Format Selection: Select text and use
Ctrl+K Ctrl+F
- Format on Save: Enable
editor.formatOnSave
in VS Code settings
- Open Command Palette (
Ctrl+Shift+P
)
- Run "Format CFML Document" command
Configuration
Configure the formatter through VS Code settings:
{
"cfmlFormatter.enable": true,
"cfmlFormatter.tabWidth": 2,
"cfmlFormatter.useTabs": false,
"cfmlFormatter.singleQuote": false,
"cfmlFormatter.inlineThreshold": 80,
"cfmlFormatter.preserveAttributeWrapping": false,
"cfmlFormatter.formatSQL": true
}
Configuration Options
Setting |
Type |
Default |
Description |
cfmlFormatter.enable |
boolean |
true |
Enable/disable CFML formatting |
cfmlFormatter.tabWidth |
number |
2 |
Number of spaces per indentation level |
cfmlFormatter.useTabs |
boolean |
false |
Use tabs instead of spaces for indentation |
cfmlFormatter.singleQuote |
boolean |
false |
Use single quotes for attributes |
cfmlFormatter.inlineThreshold |
number |
80 |
Maximum line length for inline tags |
cfmlFormatter.preserveAttributeWrapping |
boolean |
false |
Preserve existing attribute line breaks |
cfmlFormatter.formatSQL |
boolean |
true |
Format SQL inside cfquery tags |
Before/After Examples
<!-- Before -->
<cfset name="John Doe"><cfoutput>#name#</cfoutput>
<!-- After -->
<cfset name="John Doe" />
<cfoutput>#name#</cfoutput>
CFIF/CFELSE Blocks
<!-- Before -->
<cfif isDefined("user")><cfset greeting="Hello " & user.name><cfelse><cfset greeting="Hello World"></cfif>
<!-- After -->
<cfif isDefined("user")>
<cfset greeting="Hello " & user.name />
<cfelse>
<cfset greeting="Hello World" />
</cfif>
Mixed HTML/CFML
<!-- Before -->
<html><head><title>User Profile</title></head><body><cfoutput><h1>Welcome #user.name#</h1><p>Last login: #dateFormat(user.lastLogin)#</p></cfoutput></body></html>
<!-- After -->
<html>
<head>
<title>User Profile</title>
</head>
<body>
<cfoutput>
<h1>Welcome #user.name#</h1>
<p>Last login: #dateFormat(user.lastLogin)#</p>
</cfoutput>
</body>
</html>
SQL Queries
<!-- Before -->
<cfquery name="getUsers" datasource="mydb">SELECT id,firstName,lastName,email FROM users WHERE active=1 AND department='IT' ORDER BY lastName,firstName</cfquery>
<!-- After -->
<cfquery name="getUsers" datasource="mydb">
SELECT
id,
firstName,
lastName,
email
FROM users
WHERE active = 1
AND department = 'IT'
ORDER BY
lastName,
firstName
</cfquery>
Architecture
This extension uses a robust Parser → AST → Printer architecture:
- Parser: Converts CFML/HTML into a structured Abstract Syntax Tree (AST)
- AST Processing: Analyzes relationships between tags, identifies block vs inline content
- Printer: Walks the AST and generates formatted output with proper indentation and spacing
This approach avoids the pitfalls of regex-based formatters and provides consistent, reliable results.
Development
Setup Development Environment
# Clone repository
git clone https://github.com/yourusername/cfml-prettier-formatter.git
cd cfml-prettier-formatter
# Install dependencies
npm install
# Compile TypeScript
npm run compile
# Run tests
npm test
# Package extension
npm run package
Project Structure
cfml-prettier-formatter/
├── src/
│ ├── extension.ts # VS Code extension entry point
│ ├── formatter/
│ │ ├── cfmlFormatter.ts # Main formatter class
│ │ ├── parser.ts # CFML/HTML parser
│ │ ├── printer.ts # AST to string printer
│ │ └── types.ts # Type definitions
│ └── test/
│ └── suite/
│ └── extension.test.ts # Unit tests
├── syntaxes/
│ └── cfml.tmLanguage.json # CFML syntax highlighting
├── language-configuration.json # Language configuration
├── package.json # Extension manifest
└── README.md # Documentation
Testing
The extension includes comprehensive unit tests covering:
- Basic CFML tag formatting
- Sibling tag relationships (cfif/cfelse)
- HTML/CFML mixed content
- Self-closing tags
- SQL formatting
- Inline vs block rendering
- Comments preservation
- Attribute formatting
- Malformed markup handling
- Idempotent formatting
Run tests with:
npm test
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
)
- Make your changes
- Add tests for new functionality
- Ensure all tests pass (
npm test
)
- Commit your changes (
git commit -m 'Add amazing feature'
)
- Push to the branch (
git push origin feature/amazing-feature
)
- Open a Pull Request
Publishing
To publish to VS Code Marketplace:
- Install vsce:
npm install -g vsce
- Package:
npm run package
- Publish:
npm run publish
Make sure to update the publisher
field in package.json
with your marketplace publisher ID.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog
1.0.0
- Initial release
- AST-based CFML formatting
- Support for mixed HTML/CFML content
- SQL formatting in cfquery tags
- Comprehensive configuration options
- Robust error handling for malformed markup
- VS Code integration with format-on-save support
Known Issues
- Complex nested CFScript expressions may need manual formatting
- Very large files (>1MB) may experience slower formatting performance
- SQL formatting is basic - consider using dedicated SQL formatters for complex queries
Roadmap
- [ ] Enhanced CFScript formatting with full expression parsing
- [ ] Integration with popular SQL formatters
- [ ] Custom formatting rules configuration
- [ ] Performance optimizations for large files
- [ ] Support for ColdFusion Builder project settings
- [ ] Integration with CF linters and validators
Support
Acknowledgments