Name: PHP Formatter PHP-CS-Fixer (vscode-just-php-cs-fixer)
Version: 1.4.0
Author: Marvin Heilemann (muuvmuuv)
License: GPL-3.0-only
A minimalist VS Code extension that integrates PHP-CS-Fixer as a document formatter for PHP files. Philosophy: "zero dependencies" - does one thing well without bundling PHP-CS-Fixer itself.
- Do NOT commit without explicit approval from the user
- Do NOT delete git tags - if a tag was already created/pushed, create a new patch/minor version instead
- Use conventional commits (enforced by commitlint)
- Use SPDX-compliant license identifiers (e.g.,
GPL-3.0-only, notGPLv3)
- Must use npm (not pnpm/yarn) - required for VS Code extensions
- CommonJS output required - VS Code does not support ESM extensions yet
- Use
spawn/execfor external tools (allowed and standard practice) - Declare Workspace Trust capabilities when executing workspace code
- Use
module: "ES2022"withmoduleResolution: "bundler"(no.jsextensions needed) - esbuild handles bundling to CommonJS for VS Code runtime
- Keep build scripts (esbuild.js, .vscode-test.js) as CommonJS
- Use remote schema URL (not local node_modules) for
migratecommand compatibility - Enable
recommended: truefor linting rules - Exclude testProject from linting/formatting
- Disable AI features, MCP, accounts, git, telemetry in test workspace settings
- Use
--disable-extensionsand environment variables to prevent test hangs - Tests output to
dist/test/, markmochaas external in esbuild
- Document formatting provider for PHP files
- Single-folder and multi-root workspace support
- Auto-discovers
vendor/bin/php-cs-fixerexecutable (with global fallback) - Auto-discovers
.php-cs-fixer.phpand.php-cs-fixer.dist.phpconfiguration files - Configurable risky rules support
- Logging via VS Code Output Channel ("PHP-CS-Fixer")
- Caches file lookups for performance (with validation)
- Workspace Trust support (restricted mode for untrusted workspaces)
vscode-php-cs-fixer/
├── src/ # TypeScript source
│ ├── extension.ts # Entry point - registers formatter
│ ├── formatter.ts # DocumentFormattingProvider implementation
│ ├── utils.ts # File discovery (executable, config)
│ ├── cache.ts # Path caching system (string-keyed)
│ ├── log.ts # Output channel logging
│ └── test/
│ ├── unit/ # Unit tests (cache, exit codes)
│ └── integration/ # Integration tests (formatting)
├── assets/
│ └── logo.png # Extension icon
├── testProject/ # Development test fixtures
│ ├── no-workspace/ # Single folder test project
│ ├── ws-project-1/ # Multi-root workspace folder 1
│ ├── ws-project-2/ # Multi-root workspace folder 2
│ └── ws-project.code-workspace # Multi-root workspace config
├── dist/ # Bundled output (extension + tests)
├── package.json # Extension manifest
├── tsconfig.json # TypeScript config
├── biome.json # Biome linter/formatter
├── esbuild.js # Build script (CommonJS)
├── .vscode-test.js # Test runner config (CommonJS)
└── lefthook.yml # Git hooks
Minimal entry point that registers DocumentFormattingProvider for PHP language.
DocumentFormattingProvider class workflow:
- Validate document is PHP
- Find PHP-CS-Fixer executable (user config > local vendor/bin > global PATH)
- Find PHP-CS-Fixer config (user config > workspace .php-cs-fixer*.php)
- Write document content to temp file (
/tmp/pcf-<timestamp>.php) - Execute via
spawn:php-cs-fixer fix --using-cache=no --allow-risky=yes|no -n -q --config=<config> <tempfile> - Handle exit codes correctly (0=no changes, 8=fixed, others=error)
- Read fixed content from temp file
- Return
TextEditreplacing entire document - Clean up temp file
fileExists(path)- Check if file is accessiblecommandExists(command)- Check if command exists in PATHgetWorkspaceFile(pattern, excludePattern?, token?)- Find files in workspace with cachingfindPhpCsFixerExecutable(token?)- Priority: user config > vendor/bin > global PATHfindPhpCsFixerConfig(token?)- Priority: user config > .php-cs-fixer.php > .php-cs-fixer.dist.php
String-keyed Map cache (workspaceUri::pattern::excludePattern). Validates cached paths still exist before returning.
Dedicated "PHP-CS-Fixer" output channel for debugging.
Settings under php-cs-fixer.*:
| Setting | Type | Default | Description |
|---|---|---|---|
php-cs-fixer.executable |
string |
auto-detect | Path to PHP-CS-Fixer executable |
php-cs-fixer.config |
string |
auto-detect | Path to config file |
php-cs-fixer.allow-risky |
boolean |
false |
Enable risky rules |
Note: executable and config are restricted in untrusted workspaces (Workspace Trust).
None. Integrates with VS Code's built-in formatting:
Format Document(Shift+Alt+F)Format Document With...editor.formatOnSave
npm run dev # Watch mode
npm run compile # One-time build
npm run package # Production build (minified)
npm run check # Biome lint check
npm run format # Biome format
npm test # Run tests (unit + integration)- Bundler: esbuild (CommonJS output)
- Entry:
src/extension.ts→dist/extension.js - Tests:
src/test/**/*.test.ts→dist/test/**/*.test.js - External:
vscode,mocha(provided at runtime)
- Biome - Linting (recommended rules) and formatting
- Commitlint - Conventional commits
- Lefthook - Git hooks (pre-commit, commit-msg)
- Unit tests:
dist/test/unit/*.test.js- Cache, exit codes - Integration tests:
dist/test/integration/*.test.js- Formatting in VS Code - Test workspace:
testProject/no-workspace
| Package | Purpose |
|---|---|
@biomejs/biome |
Linting/formatting |
@commitlint/cli |
Commit linting |
@vscode/test-cli |
Test runner |
esbuild |
Bundler |
typescript |
Compiler |
- PHP - Must be in PATH
- PHP-CS-Fixer - Via Composer:
composer require --dev friendsofphp/php-cs-fixer
- Minimalist Design - No bundled PHP-CS-Fixer, no custom commands
- Multi-Root Workspace Support - Cache is workspace-folder-aware
- Graceful Degradation - Auto-discovers executables/configs, falls back to global, shows helpful errors
- Cross-Platform - Handles Windows
.batextension, usesspawnwithshell: true - Cancellation Support - Respects
CancellationToken, kills process on cancel - Lazy Activation - Only activates on
onLanguage:php - Workspace Trust -
executableandconfigsettings restricted in untrusted workspaces - Proper Exit Codes - Handles PHP-CS-Fixer exit code 8 (files fixed) as success
- Update version in
package.json - Commit:
git commit -m "chore: release vX.Y.Z" - Tag:
git tag -a vX.Y.Z -m "vX.Y.Z\n\n## What's Changed\n..." - Publish:
npx @vscode/vsce publish
Note: Ensure PAT (Personal Access Token) is valid before publishing.
| Action | Command/Location |
|---|---|
| Build | npm run compile |
| Package | npm run package |
| Test | npm test |
| Debug | F5 in VS Code |
| Main logic | src/formatter.ts |
| Config | package.json contributes section |
| Logs | Output panel > "PHP-CS-Fixer" |
- Formatting not working: Check Output panel > "PHP-CS-Fixer" for logs
- Executable not found: Install via
composer require --dev friendsofphp/php-cs-fixeror setphp-cs-fixer.executable - Config not found: Create
.php-cs-fixer.phpin project root or setphp-cs-fixer.config - Untrusted workspace: Grant trust or configure settings at user level
- Tests hanging: Ensure AI/MCP/accounts disabled in test settings