├── .npmrc ├── icon.png ├── .gitignore ├── .prettierignore ├── pnpm-workspace.yaml ├── prettier.config.cjs ├── testProject ├── ugly.ctp ├── .vscode │ └── settings.json ├── ugly.php └── ugly 1.php ├── .vscodeignore ├── tsdown.config.ts ├── .editorconfig ├── tsconfig.eslint.json ├── src ├── PHPFmtError.ts ├── utils.ts ├── extension.ts ├── Transformation.ts ├── Widget.ts ├── PHPFmt.ts ├── PHPFmtProvider.ts └── meta.ts ├── .vscode ├── tasks.json └── launch.json ├── eslint.config.mjs ├── scripts ├── copy.mts ├── docs.mts └── release.mts ├── tsconfig.json ├── test ├── suite │ ├── index.ts │ └── extension.test.ts └── runTest.ts ├── .github └── workflows │ ├── release.yml │ └── ci.yml ├── THIRDPARTY.md ├── LICENSE ├── README.md ├── CHANGELOG.md └── package.json /.npmrc: -------------------------------------------------------------------------------- 1 | enable-pre-post-scripts=true 2 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kokororin/vscode-phpfmt/HEAD/icon.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | dist 3 | node_modules 4 | npm-debug.log 5 | *.vsix 6 | .vscode-test 7 | *.log 8 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /out 3 | /testProject 4 | .vscode 5 | .vscode-test 6 | *.md 7 | .github 8 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | onlyBuiltDependencies: 2 | - '@vscode/vsce-sign' 3 | - esbuild 4 | - keytar 5 | -------------------------------------------------------------------------------- /prettier.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require('@kokororin/prettierrc'), 3 | endOfLine: 'auto' 4 | }; 5 | -------------------------------------------------------------------------------- /testProject/ugly.ctp: -------------------------------------------------------------------------------- 1 | 2 |

Teste

3 |
8 |

9 | Teste 10 |

11 | -------------------------------------------------------------------------------- /testProject/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensions.supportUntrustedWorkspaces": true, 3 | "phpfmt.psr2": true, 4 | "phpfmt.indent_with_space": 4, 5 | "phpfmt.ignore": [ 6 | ".ctp", 7 | ".blade.php" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .* 2 | .**/** 3 | patches/** 4 | src/** 5 | scripts/** 6 | out/** 7 | test/** 8 | testProject/** 9 | *.config.ts 10 | *.config.mjs 11 | *.config.cjs 12 | tsconfig*.json 13 | pnpm-lock.yaml 14 | *.log 15 | *.tgz 16 | *.vsix 17 | -------------------------------------------------------------------------------- /tsdown.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsdown'; 2 | 3 | export default defineConfig({ 4 | entry: ['src/extension.ts'], 5 | format: ['cjs'], 6 | dts: false, 7 | noExternal: [/^((?!(vscode)).)*$/], 8 | external: ['vscode'] 9 | }); 10 | -------------------------------------------------------------------------------- /testProject/ugly.php: -------------------------------------------------------------------------------- 1 | ugly=$ugly; 7 | } 8 | 9 | public function getUgly() 10 | { 11 | return $this->ugly; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 2 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /testProject/ugly 1.php: -------------------------------------------------------------------------------- 1 | ugly=$ugly; 8 | } 9 | 10 | public function getUgly() 11 | { 12 | return $this->ugly; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": true 5 | }, 6 | "include": [ 7 | "**/*.js", 8 | "**/*.cjs", 9 | "**/*.mjs", 10 | "**/*.ts", 11 | "**/*.mts", 12 | ], 13 | "exclude": [ 14 | "node_modules", 15 | "out", 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/PHPFmtError.ts: -------------------------------------------------------------------------------- 1 | export class PHPFmtError extends Error { 2 | public constructor(message: string) { 3 | super(`phpfmt: ${message}`); 4 | 5 | Object.setPrototypeOf(this, new.target.prototype); 6 | } 7 | } 8 | 9 | export class PHPFmtSkipError extends PHPFmtError { 10 | public constructor() { 11 | super(PHPFmtSkipError.name); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "isBackground": true, 10 | "presentation": { 11 | "reveal": "never", 12 | "group": "watchers" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import antfu from '@antfu/eslint-config'; 2 | import configPrettier from 'eslint-config-prettier'; 3 | import pluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; 4 | 5 | export default antfu( 6 | { 7 | imports: { 8 | overrides: { 9 | 'import/consistent-type-specifier-style': 'off' 10 | } 11 | }, 12 | jsonc: false, 13 | test: { 14 | overrides: { 15 | 'test/consistent-test-it': 'off' 16 | } 17 | }, 18 | ignores: ['src/meta.ts'] 19 | }, 20 | configPrettier, 21 | pluginPrettierRecommended 22 | ); 23 | -------------------------------------------------------------------------------- /scripts/copy.mts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs/promises'; 2 | import path from 'node:path'; 3 | import process from 'node:process'; 4 | import { dirname } from 'dirname-filename-esm'; 5 | import phpfmt from 'phpfmt'; 6 | 7 | const __dirname = dirname(import.meta); 8 | 9 | const pkgPath = path.join(__dirname, '..'); 10 | const distPath = path.join(pkgPath, 'dist'); 11 | const destPath = path.join(distPath, phpfmt.v2.pharName); 12 | 13 | try { 14 | await fs.mkdir(distPath, { recursive: true }); 15 | await fs.copyFile(phpfmt.v2.pharPath, destPath); 16 | } catch (err) { 17 | console.error(err); 18 | process.exit(1); 19 | } 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "module": "commonjs", 5 | "lib": [ 6 | "es2020" 7 | ], 8 | "outDir": "out", 9 | "rootDir": ".", 10 | "strict": true, 11 | "moduleResolution": "node", 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "removeComments": true, 15 | "sourceMap": true, 16 | "esModuleInterop": true, 17 | "allowSyntheticDefaultImports": true, 18 | "useUnknownInCatchVariables": false, 19 | "skipLibCheck": true 20 | }, 21 | "exclude": [ 22 | "node_modules", 23 | ".vscode-test", 24 | "testProject", 25 | "scripts", 26 | "*.config.ts" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /test/suite/index.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'node:path'; 2 | import Mocha from 'mocha'; 3 | import { globSync } from 'tinyglobby'; 4 | 5 | export function run( 6 | testsRoot: string, 7 | cb: (error: any, failures?: number) => void 8 | ): void { 9 | // Create the mocha test 10 | const mocha = new Mocha({ 11 | ui: 'tdd' 12 | }); 13 | 14 | const files = globSync('**/**.test.js', { cwd: testsRoot }); 15 | 16 | // Add files to the test suite 17 | files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); 18 | 19 | try { 20 | // Run the mocha test 21 | mocha.run(failures => { 22 | cb(null, failures); 23 | }); 24 | } catch (err) { 25 | console.error(err); 26 | cb(err); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import type { ObjectEncodingOptions } from 'node:fs'; 2 | import childProcess, { type ExecOptions } from 'node:child_process'; 3 | 4 | export async function exec( 5 | command: string, 6 | options?: (ObjectEncodingOptions & ExecOptions) | null 7 | ): Promise<{ 8 | stdout: string; 9 | stderr: string; 10 | code: number | null; 11 | }> { 12 | return await new Promise((resolve, reject) => { 13 | const child = childProcess.exec( 14 | command, 15 | options, 16 | (error, stdout, stderr) => { 17 | if (error != null) { 18 | reject(error); 19 | } else { 20 | resolve({ 21 | stdout: String(stdout), 22 | stderr: String(stderr), 23 | code: child.exitCode 24 | }); 25 | } 26 | } 27 | ); 28 | 29 | child.on('error', reject); 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /test/runTest.ts: -------------------------------------------------------------------------------- 1 | import assert from 'node:assert'; 2 | import path from 'node:path'; 3 | import { runTests } from '@vscode/test-electron'; 4 | import readPkgUp from 'read-pkg-up'; 5 | 6 | async function run(): Promise { 7 | const { path: pkgPath } = (await readPkgUp({ cwd: __dirname })) ?? {}; 8 | 9 | assert.ok(pkgPath); 10 | const extensionDevelopmentPath = path.dirname(pkgPath); 11 | const extensionTestsPath = path.join(__dirname, 'suite'); 12 | const testWorkspace = path.join(extensionDevelopmentPath, 'testProject'); 13 | 14 | await runTests({ 15 | extensionDevelopmentPath, 16 | extensionTestsPath, 17 | launchArgs: [testWorkspace] 18 | .concat(['--skip-welcome']) 19 | .concat(['--disable-extensions']) 20 | .concat(['--skip-release-notes']) 21 | .concat(['--enable-proposed-api']) 22 | }); 23 | } 24 | 25 | void run(); 26 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | import type * as vscode from 'vscode'; 2 | import { PHPFmt } from './PHPFmt'; 3 | import { PHPFmtProvider } from './PHPFmtProvider'; 4 | import { Widget } from './Widget'; 5 | 6 | export function activate(context: vscode.ExtensionContext): void { 7 | const widget = new Widget(); 8 | const phpfmt = new PHPFmt(widget); 9 | 10 | const provider = new PHPFmtProvider(widget, phpfmt); 11 | 12 | context.subscriptions.push( 13 | provider.registerOnDidChangeConfiguration(), 14 | provider.registerFormatCommand(), 15 | provider.registerListTransformationsCommand(), 16 | ...provider.registerToggleTransformationsCommand(), 17 | ...provider.registerToggleBooleanCommand(), 18 | provider.registerToggleIndentWithSpaceCommand(), 19 | provider.registerDocumentFormattingEditProvider(), 20 | provider.registerDocumentRangeFormattingEditProvider(), 21 | ...provider.registerStatusBarItem() 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Launch Extension", 6 | "type": "extensionHost", 7 | "request": "launch", 8 | "runtimeExecutable": "${execPath}", 9 | "args": [ 10 | "${workspaceRoot}/testProject", 11 | "--extensions-dir=${workspaceRoot}/.", 12 | "--extensionDevelopmentPath=${workspaceRoot}" 13 | ], 14 | "sourceMaps": true, 15 | "outFiles": ["${workspaceRoot}/out/src/**/*.js"], 16 | "preLaunchTask": "${defaultBuildTask}" 17 | }, 18 | { 19 | "name": "Launch Tests", 20 | "type": "extensionHost", 21 | "request": "launch", 22 | "runtimeExecutable": "${execPath}", 23 | "args": [ 24 | "${workspaceRoot}/testProject", 25 | "--extensions-dir=${workspaceRoot}/.", 26 | "--extensionDevelopmentPath=${workspaceRoot}", 27 | "--extensionTestsPath=${workspaceRoot}/out/test" 28 | ], 29 | "sourceMaps": true, 30 | "outFiles": ["${workspaceRoot}/out/test/**/*.js"] 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | schedule: 8 | - cron: "*/30 * * * *" 9 | 10 | jobs: 11 | release: 12 | runs-on: ubuntu-latest 13 | permissions: 14 | # Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository. 15 | contents: write 16 | 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v3 20 | 21 | - name: Use PNPM 22 | uses: pnpm/action-setup@v3 23 | 24 | - name: Setup PHP 25 | uses: shivammathur/setup-php@v2 26 | with: 27 | php-version: 8.3 28 | coverage: none 29 | tools: composer 30 | 31 | - name: Use Node.js 32 | uses: actions/setup-node@v3 33 | with: 34 | node-version: '22.x' 35 | cache: 'pnpm' 36 | registry-url: 'https://registry.npmjs.org' 37 | 38 | - name: Install Dependencies 39 | run: | 40 | pnpm i 41 | 42 | - name: Build 43 | run: pnpm build 44 | 45 | - name: Run release script 46 | run: npx tsx ./scripts/release.mts 47 | env: 48 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 49 | VSCE_TOKEN: ${{ secrets.VSCE_TOKEN }} 50 | OVSX_TOKEN: ${{ secrets.OVSX_TOKEN }} 51 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 52 | -------------------------------------------------------------------------------- /THIRDPARTY.md: -------------------------------------------------------------------------------- 1 | phpfmt 2 | 3 | Copyright (c) 2015, phpfmt and its authors 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | 12 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 15 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | matrix: 10 | os: [macos-latest, windows-latest] 11 | php-version: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] 12 | name: Test on ${{ matrix.os }} & PHP ${{ matrix.php-version }} 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v3 16 | 17 | - name: Use PNPM 18 | uses: pnpm/action-setup@v3 19 | 20 | - name: Setup PHP 21 | uses: shivammathur/setup-php@v2 22 | with: 23 | php-version: ${{ matrix.php-version }} 24 | coverage: none 25 | tools: composer 26 | 27 | - name: Use Node.js 28 | uses: actions/setup-node@v3 29 | with: 30 | node-version: '22.x' 31 | cache: 'pnpm' 32 | 33 | - name: Start Xvfb 34 | run: /usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & echo "Started xvfb" 35 | shell: bash 36 | if: ${{ success() && matrix.os == 'ubuntu-latest' }} 37 | 38 | - name: Install Dependencies 39 | run: | 40 | pnpm i 41 | 42 | - name: Run Lint 43 | run: pnpm lint 44 | if: ${{ matrix.os == 'macos-latest' && matrix.php-version == '7.0' }} 45 | 46 | - name: Run Tests 47 | uses: nick-fields/retry@v2 48 | with: 49 | timeout_minutes: 10 50 | max_attempts: 3 51 | command: pnpm test 52 | env: 53 | DISPLAY: ":99.0" 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, Kokororin 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /test/suite/extension.test.ts: -------------------------------------------------------------------------------- 1 | import assert from 'node:assert'; 2 | import readPkgUp from 'read-pkg-up'; 3 | import { glob } from 'tinyglobby'; 4 | import * as vscode from 'vscode'; 5 | 6 | const { packageJson: pkg } = readPkgUp.sync({ cwd: __dirname }) ?? {}; 7 | assert.ok(pkg != null, 'Failed to read package.json'); 8 | 9 | suite('PHPFmt Test', () => { 10 | const extension = vscode.extensions.getExtension( 11 | `${pkg.author?.name}.${pkg.name}` 12 | ); 13 | 14 | test('can activate', async () => { 15 | assert.ok(extension != null); 16 | await extension.activate(); 17 | }); 18 | 19 | test('can format with command', async () => { 20 | if (vscode.workspace.workspaceFolders == null) { 21 | assert.fail(); 22 | } 23 | 24 | const workspaceFolder = vscode.workspace.workspaceFolders[0].uri.fsPath; 25 | const phpFiles = await glob(['**/*.php'], { 26 | cwd: workspaceFolder, 27 | absolute: true 28 | }); 29 | 30 | for (const filePath of phpFiles) { 31 | const doc = await vscode.workspace.openTextDocument(filePath); 32 | await vscode.window.showTextDocument(doc); 33 | 34 | const text = doc.getText(); 35 | try { 36 | await vscode.commands.executeCommand('editor.action.formatDocument'); 37 | assert.notEqual(doc.getText(), text); 38 | } catch { 39 | assert.fail(`Failed to format doc: ${filePath}`); 40 | } 41 | } 42 | }); 43 | 44 | test('should register commands', async () => { 45 | const commands = await vscode.commands.getCommands(true); 46 | const foundCommands = commands.filter(value => value.startsWith('phpfmt.')); 47 | assert.equal(foundCommands.length, pkg.contributes.commands.length); 48 | }); 49 | 50 | test('should commands work', () => { 51 | const commands = pkg.contributes.commands as Array<{ 52 | command: string; 53 | title: string; 54 | when?: string; 55 | }>; 56 | commands 57 | .filter(value => !value.when) 58 | .forEach(command => { 59 | void vscode.commands.executeCommand(command.command); 60 | }); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /src/Transformation.ts: -------------------------------------------------------------------------------- 1 | import os from 'node:os'; 2 | import mem from 'mem'; 3 | import phpfmt, { type PHPFmt as IPHPFmt } from 'phpfmt'; 4 | import { exec } from './utils'; 5 | 6 | export interface TransformationItem { 7 | key: string; 8 | description: string; 9 | } 10 | 11 | export class Transformation { 12 | public constructor( 13 | private readonly phpBin: string, 14 | private readonly fmt: IPHPFmt 15 | ) { 16 | this.getTransformations = mem(this.getTransformations, { 17 | cacheKey: this.getCacheKey 18 | }); 19 | this.getPasses = mem(this.getPasses, { 20 | cacheKey: this.getCacheKey 21 | }); 22 | this.isExists = mem(this.isExists, { 23 | cacheKey: this.getCacheKey 24 | }); 25 | } 26 | 27 | private get baseCmd(): string { 28 | return `${this.phpBin} -d "error_reporting=E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED" "${this.fmt.pharPath}"`; 29 | } 30 | 31 | private readonly getCacheKey = (args: any[]): string => { 32 | return JSON.stringify([this.fmt.pharPath, args]); 33 | }; 34 | 35 | public async getTransformations(): Promise { 36 | try { 37 | const { stdout } = await exec(`${this.baseCmd} --list-simple`); 38 | 39 | return stdout 40 | .trim() 41 | .split(os.EOL) 42 | .map(v => { 43 | const splited = v.split(' '); 44 | 45 | return { 46 | key: splited[0], 47 | description: splited 48 | .filter((value, index) => value && index > 0) 49 | .join(' ') 50 | .trim() 51 | }; 52 | }); 53 | } catch { 54 | return []; 55 | } 56 | } 57 | 58 | public async getExample( 59 | transformationItem: TransformationItem 60 | ): Promise { 61 | try { 62 | const { stdout } = await exec( 63 | `${this.baseCmd} --help-pass ${transformationItem.key}` 64 | ); 65 | 66 | return stdout; 67 | } catch { 68 | return ''; 69 | } 70 | } 71 | 72 | public getPasses(): string[] { 73 | return phpfmt.parser.getPasses(this.fmt, phpfmt.parser.MODE_REGEX); 74 | } 75 | 76 | public isExists(name: string): boolean { 77 | return this.getPasses().includes(name); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/Widget.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import * as meta from './meta'; 3 | 4 | export enum PHPFmtStatus { 5 | Ready = 'check-all', 6 | Success = 'check', 7 | Ignore = 'x', 8 | Warn = 'warning', 9 | Error = 'alert', 10 | Disabled = 'circle-slash' 11 | } 12 | 13 | export type LogLevel = 'INFO' | 'WARN' | 'ERROR' | 'NONE'; 14 | 15 | export class Widget { 16 | private logLevel: LogLevel = 'INFO'; 17 | private readonly outputChannel: vscode.OutputChannel; 18 | private readonly statusBarItem: vscode.StatusBarItem; 19 | 20 | public constructor() { 21 | this.outputChannel = vscode.window.createOutputChannel('phpfmt'); 22 | this.statusBarItem = vscode.window.createStatusBarItem( 23 | vscode.StatusBarAlignment.Right, 24 | -1 25 | ); 26 | this.statusBarItem.text = 'phpfmt'; 27 | this.statusBarItem.command = meta.commands.openOutput; 28 | this.toggleStatusBarItem(vscode.window.activeTextEditor); 29 | } 30 | 31 | public toggleStatusBarItem(editor: vscode.TextEditor | undefined): void { 32 | if (typeof editor === 'undefined') { 33 | return; 34 | } 35 | if (editor.document.languageId === 'php') { 36 | this.statusBarItem.show(); 37 | this.updateStatusBarItem(PHPFmtStatus.Ready); 38 | } else { 39 | this.statusBarItem.hide(); 40 | } 41 | } 42 | 43 | public updateStatusBarItem(result: PHPFmtStatus): void { 44 | this.statusBarItem.text = `$(${result.toString()}) phpfmt`; 45 | switch (result) { 46 | case PHPFmtStatus.Ignore: 47 | case PHPFmtStatus.Warn: 48 | this.statusBarItem.backgroundColor = new vscode.ThemeColor( 49 | 'statusBarItem.warningBackground' 50 | ); 51 | break; 52 | case PHPFmtStatus.Error: 53 | this.statusBarItem.backgroundColor = new vscode.ThemeColor( 54 | 'statusBarItem.errorBackground' 55 | ); 56 | break; 57 | default: 58 | this.statusBarItem.backgroundColor = new vscode.ThemeColor( 59 | 'statusBarItem.fourgroundBackground' 60 | ); 61 | break; 62 | } 63 | this.statusBarItem.show(); 64 | } 65 | 66 | public getOutputChannel(): vscode.OutputChannel { 67 | return this.outputChannel; 68 | } 69 | 70 | public setOutputLevel(logLevel: LogLevel): void { 71 | this.logLevel = logLevel; 72 | } 73 | 74 | private logMessage(message: string, logLevel: LogLevel): void { 75 | const now = new Date().toLocaleString(); 76 | this.outputChannel.appendLine(`${now} [${logLevel}] ${message}`); 77 | } 78 | 79 | private logObject(data: unknown): void { 80 | const message = JSON.stringify(data, null, 2); 81 | 82 | this.outputChannel.appendLine(message); 83 | } 84 | 85 | public logInfo(message: string, data?: unknown): vscode.OutputChannel { 86 | if (['NONE', 'WARN', 'ERROR'].includes(this.logLevel)) { 87 | return this.outputChannel; 88 | } 89 | this.logMessage(message, 'INFO'); 90 | if (data) { 91 | this.logObject(data); 92 | } 93 | return this.outputChannel; 94 | } 95 | 96 | public logWarning(message: string, data?: unknown): vscode.OutputChannel { 97 | if (['NONE', 'ERROR'].includes(this.logLevel)) { 98 | return this.outputChannel; 99 | } 100 | this.logMessage(message, 'WARN'); 101 | if (data) { 102 | this.logObject(data); 103 | } 104 | return this.outputChannel; 105 | } 106 | 107 | public logError(message: string, error?: unknown): vscode.OutputChannel { 108 | if (['NONE'].includes(this.logLevel)) { 109 | return this.outputChannel; 110 | } 111 | this.logMessage(message, 'ERROR'); 112 | if (typeof error === 'string') { 113 | this.outputChannel.appendLine(error); 114 | } else if (error instanceof Error) { 115 | if (error.message) { 116 | this.logMessage(error.message, 'ERROR'); 117 | } 118 | // if (error?.stack) { 119 | // this.outputChannel.appendLine(error.stack); 120 | // } 121 | } else if (error) { 122 | this.logObject(error); 123 | } 124 | return this.outputChannel; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /scripts/docs.mts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs/promises'; 2 | import os from 'node:os'; 3 | import path from 'node:path'; 4 | import process from 'node:process'; 5 | import { consola } from 'consola'; 6 | import { dirname } from 'dirname-filename-esm'; 7 | import { $ } from 'execa'; 8 | import { got } from 'got'; 9 | import JSON5 from 'json5'; 10 | import { markdownTable } from 'markdown-table'; 11 | import phpfmt from 'phpfmt'; 12 | 13 | const __dirname = dirname(import.meta); 14 | 15 | const pkgJsonPath = path.join(__dirname, '../package.json'); 16 | const readmePath: string = path.join(__dirname, '../README.md'); 17 | 18 | const pkg = JSON.parse(String(await fs.readFile(pkgJsonPath))); 19 | const configuration = pkg.contributes.configuration; 20 | 21 | try { 22 | // check php first 23 | await $`php -v`; 24 | 25 | consola.info('Downloading phpfmt.sublime-settings...'); 26 | const phpfmtSettingsRaw = await got 27 | .get( 28 | 'https://raw.githubusercontent.com/driade/phpfmt8/refs/heads/master/phpfmt.sublime-settings' 29 | ) 30 | .text(); 31 | const phpfmtSettings = JSON5.parse(phpfmtSettingsRaw); 32 | for (const [key, value] of Object.entries(phpfmtSettings)) { 33 | if (key === 'php_bin') { 34 | continue; 35 | } 36 | if (configuration.properties[`phpfmt.${key}`]) { 37 | configuration.properties[`phpfmt.${key}`].default = value; 38 | } 39 | } 40 | 41 | const configTable: string[][] = [['Key', 'Type', 'Description', 'Default']]; 42 | 43 | for (const configKey of Object.keys(configuration.properties)) { 44 | const configValue = configuration.properties[configKey]; 45 | const row: string[] = [configKey]; 46 | 47 | if (typeof configValue.type === 'string') { 48 | row.push(`\`${configValue.type}\``); 49 | } else if (Array.isArray(configValue.type)) { 50 | row.push(`\`${configValue.type.join(' \\| ')}\``); 51 | } 52 | row.push(configValue.description); 53 | 54 | if (typeof configValue.default === 'string') { 55 | row.push(`"${configValue.default}"`); 56 | } else if (typeof configValue.default === 'number') { 57 | row.push(configValue.default); 58 | } else if ( 59 | Array.isArray(configValue.default) || 60 | typeof configValue.default === 'boolean' 61 | ) { 62 | row.push(JSON.stringify(configValue.default)); 63 | } else { 64 | throw new TypeError('uncovered type'); 65 | } 66 | configTable.push(row); 67 | } 68 | 69 | let readmeContent = String(await fs.readFile(readmePath)); 70 | readmeContent = readmeContent.replace( 71 | /([\s\S]*)/, 72 | () => { 73 | return `${os.EOL}${markdownTable( 74 | configTable, 75 | { alignDelimiters: false } 76 | )}${os.EOL}`; 77 | } 78 | ); 79 | 80 | const { Transformation } = await import('../src/Transformation'); 81 | const transformation = new Transformation('php', phpfmt.v2); 82 | 83 | consola.info('Generating transformations and passes...'); 84 | const transformations = await transformation.getTransformations(); 85 | const transformationTable: string[][] = [ 86 | ['Key', 'Description'], 87 | ...transformations.map(o => [o.key, o.description]) 88 | ]; 89 | 90 | readmeContent = readmeContent.replace( 91 | /([\s\S]*)/, 92 | () => { 93 | return `${os.EOL}${markdownTable( 94 | transformationTable, 95 | { alignDelimiters: false } 96 | )}${os.EOL}`; 97 | } 98 | ); 99 | 100 | const passes = transformation.getPasses(); 101 | 102 | const enums = passes.map(pass => { 103 | const p = transformations.find(t => t.key === pass); 104 | return { 105 | enum: pass, 106 | description: p?.description ?? 'Core pass' 107 | }; 108 | }); 109 | 110 | pkg.contributes.configuration.properties['phpfmt.passes'].items.enum = 111 | enums.map(o => o.enum); 112 | pkg.contributes.configuration.properties[ 113 | 'phpfmt.passes' 114 | ].items.enumDescriptions = enums.map(o => o.description); 115 | pkg.contributes.configuration.properties['phpfmt.exclude'].items.enum = 116 | enums.map(o => o.enum); 117 | pkg.contributes.configuration.properties[ 118 | 'phpfmt.exclude' 119 | ].items.enumDescriptions = enums.map(o => o.description); 120 | 121 | consola.info('Generating docs...'); 122 | await fs.writeFile(readmePath, readmeContent); 123 | consola.info('Updating package.json...'); 124 | await fs.writeFile(pkgJsonPath, JSON.stringify(pkg, null, 2) + os.EOL); 125 | } catch (err) { 126 | console.error(err); 127 | process.exit(1); 128 | } 129 | -------------------------------------------------------------------------------- /scripts/release.mts: -------------------------------------------------------------------------------- 1 | /* eslint no-console: error */ 2 | import fs from 'node:fs/promises'; 3 | import os from 'node:os'; 4 | import path from 'node:path'; 5 | import process from 'node:process'; 6 | import { Octokit } from '@octokit/rest'; 7 | import { consola } from 'consola'; 8 | import debug from 'debug'; 9 | import { dirname } from 'dirname-filename-esm'; 10 | import { $ } from 'execa'; 11 | import * as fflate from 'fflate'; 12 | import { got } from 'got'; 13 | import isInCi from 'is-in-ci'; 14 | import md5 from 'md5'; 15 | import phpfmt from 'phpfmt'; 16 | import * as semver from 'semver'; 17 | import { simpleGit } from 'simple-git'; 18 | 19 | const __dirname = dirname(import.meta); 20 | 21 | debug.enable('simple-git,simple-git:*'); 22 | 23 | const pkgJsonPath = path.join(__dirname, '../package.json'); 24 | const changelogPath = path.join(__dirname, '../CHANGELOG.md'); 25 | 26 | try { 27 | const pkg = JSON.parse(String(await fs.readFile(pkgJsonPath))); 28 | 29 | const { stdout: versionListOut } = await $({ 30 | preferLocal: true 31 | })`vsce show ${pkg.publisher}.${pkg.name} --json`; 32 | const versionList = JSON.parse(String(versionListOut)); 33 | const latestVersion = versionList.versions[0].version; 34 | 35 | const pharUrl = phpfmt.v2.installUrl; 36 | const pharVersionUrl = phpfmt.v2.installUrl.replace( 37 | phpfmt.v2.pharName, 38 | 'version.txt' 39 | ); 40 | 41 | consola.info(`Download url: ${pharUrl}`); 42 | 43 | consola.info('Downloading vsix...'); 44 | const currentVsix = await got( 45 | `https://${pkg.publisher}.gallery.vsassets.io/_apis/public/gallery/publisher/${pkg.publisher}/extension/${pkg.name}/${latestVersion}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage` 46 | ).buffer(); 47 | 48 | if (currentVsix.byteLength < 10000) { 49 | throw new Error('Download vsix failed'); 50 | } 51 | 52 | const zipData = await new Promise((resolve, reject) => { 53 | fflate.unzip(new Uint8Array(currentVsix), (err, data) => { 54 | if (err) { 55 | reject(err); 56 | } else { 57 | resolve(data); 58 | } 59 | }); 60 | }); 61 | 62 | const entryPath = `extension/dist/${phpfmt.v2.pharName}`; 63 | if (!(entryPath in zipData)) { 64 | throw new Error('Not found phar in vsix'); 65 | } 66 | const manifestPath = `extension/package.json`; 67 | if (!(manifestPath in zipData)) { 68 | throw new Error('Not found manifest in vsix'); 69 | } 70 | 71 | const manifest = JSON.parse(new TextDecoder().decode(zipData[manifestPath])); 72 | 73 | const currentPharData = new TextDecoder().decode(zipData[entryPath]); 74 | const currentMd5 = md5(currentPharData); 75 | consola.info(`Current md5: ${currentMd5}`); 76 | 77 | consola.info('Downloading latest phar...'); 78 | const latestPharData = await got(pharUrl).text(); 79 | const latestPharVersion = await got(pharVersionUrl).text(); 80 | consola.info(`Latest phar version: ${latestPharVersion}`); 81 | 82 | const latestMd5 = md5(latestPharData); 83 | consola.info(`Latest md5: ${latestMd5}`); 84 | 85 | if (currentMd5 === latestMd5) { 86 | consola.info('Md5 is same'); 87 | process.exit(0); 88 | } 89 | 90 | const newVersion = semver.inc(manifest.version, 'patch'); 91 | consola.info(`New version: ${newVersion}`); 92 | 93 | let changelogData = String(await fs.readFile(changelogPath)); 94 | changelogData = `### ${newVersion} 95 | 96 | - Upgrade ${phpfmt.v2.pharName} [(V${latestPharVersion})](https://github.com/driade/phpfmt8/releases/tag/v${latestPharVersion}) 97 | 98 | ${changelogData}`; 99 | await fs.writeFile(changelogPath, changelogData); 100 | 101 | pkg.version = newVersion; 102 | await fs.writeFile(pkgJsonPath, JSON.stringify(pkg, null, 2) + os.EOL); 103 | 104 | await fs.writeFile(phpfmt.v2.pharPath, latestPharData); 105 | 106 | if (!isInCi) { 107 | consola.warn('Not in CI, skip git push'); 108 | process.exit(0); 109 | } 110 | 111 | if (process.env.VSCE_TOKEN) { 112 | // Publish to VSCE 113 | try { 114 | await $({ 115 | stdio: 'inherit', 116 | preferLocal: true 117 | })`vsce publish -p ${process.env.VSCE_TOKEN} --no-dependencies`; 118 | } catch (err) { 119 | consola.error(err); 120 | process.exit(0); 121 | } 122 | } 123 | 124 | const git = simpleGit({ 125 | config: [ 126 | 'credential.https://github.com/.helper="! f() { echo username=x-access-token; echo password=$GITHUB_TOKEN; };f"' 127 | ] 128 | }); 129 | await git 130 | .addConfig('user.name', 'github-actions[bot]') 131 | .addConfig( 132 | 'user.email', 133 | '41898282+github-actions[bot]@users.noreply.github.com' 134 | ) 135 | .add('.') 136 | .commit(`release: ${newVersion}`) 137 | .addTag(`v${newVersion}`) 138 | .push() 139 | .pushTags(); 140 | 141 | if (process.env.GITHUB_TOKEN) { 142 | const octokit = new Octokit({ 143 | auth: process.env.GITHUB_TOKEN 144 | }); 145 | try { 146 | await octokit.rest.repos.createRelease({ 147 | owner: pkg.author, 148 | repo: pkg.name, 149 | tag_name: `v${newVersion}`, 150 | body: `Please refer to [CHANGELOG.md](https://github.com/${pkg.author}/${pkg.name}/blob/master/CHANGELOG.md) for details.`, 151 | draft: false, 152 | prerelease: false 153 | }); 154 | } catch (err) { 155 | consola.error(err); 156 | } 157 | } 158 | 159 | if (process.env.NODE_AUTH_TOKEN) { 160 | // Publish to NPM 161 | try { 162 | await $({ 163 | stdio: 'inherit', 164 | env: { 165 | NODE_AUTH_TOKEN: process.env.NODE_AUTH_TOKEN 166 | } 167 | })`npm publish --ignore-scripts`; 168 | } catch (err) { 169 | consola.error(err); 170 | } 171 | } 172 | 173 | if (process.env.OVSX_TOKEN) { 174 | // Publish to OVSX 175 | try { 176 | await $({ 177 | stdio: 'inherit', 178 | preferLocal: true 179 | })`ovsx publish -p ${process.env.OVSX_TOKEN} --no-dependencies`; 180 | } catch (err) { 181 | consola.error(err); 182 | } 183 | } 184 | } catch (err) { 185 | consola.error(err); 186 | process.exit(1); 187 | } 188 | -------------------------------------------------------------------------------- /src/PHPFmt.ts: -------------------------------------------------------------------------------- 1 | import type { SnakeCase } from 'type-fest'; 2 | import type * as meta from './meta'; 3 | import fs from 'node:fs/promises'; 4 | import os from 'node:os'; 5 | import path from 'node:path'; 6 | import { compare } from 'compare-versions'; 7 | import detectIndent from 'detect-indent'; 8 | import findUp from 'find-up'; 9 | import phpfmt, { type PHPFmt as IPHPFmt } from 'phpfmt'; 10 | import * as vscode from 'vscode'; 11 | import { PHPFmtError, PHPFmtSkipError } from './PHPFmtError'; 12 | import { Transformation } from './Transformation'; 13 | import { exec } from './utils'; 14 | import { PHPFmtStatus, type Widget } from './Widget'; 15 | 16 | export type PHPFmtConfig = { 17 | [K in keyof meta.ConfigShorthandTypeMap as SnakeCase]: meta.ConfigShorthandTypeMap[K]; 18 | }; 19 | 20 | export class PHPFmt { 21 | private config: PHPFmtConfig; 22 | private transformation: Transformation; 23 | private readonly args: string[] = []; 24 | 25 | public constructor(private readonly widget: Widget) { 26 | this.config = this.getConfig(); 27 | this.transformation = new Transformation( 28 | this.config.php_bin, 29 | this.getFmt() 30 | ); 31 | this.loadSettings(); 32 | } 33 | 34 | private getConfig(): PHPFmtConfig { 35 | return vscode.workspace.getConfiguration( 36 | 'phpfmt' 37 | ) as unknown as PHPFmtConfig; 38 | } 39 | 40 | public loadSettings(): void { 41 | this.config = this.getConfig(); 42 | this.transformation = new Transformation( 43 | this.config.php_bin, 44 | this.getFmt() 45 | ); 46 | 47 | this.args.length = 0; 48 | 49 | if (this.config.custom_arguments !== '') { 50 | this.args.push(this.config.custom_arguments); 51 | return; 52 | } 53 | 54 | if (this.config.psr1) { 55 | this.args.push('--psr1'); 56 | } 57 | 58 | if (this.config.psr1_naming) { 59 | this.args.push('--psr1-naming'); 60 | } 61 | 62 | if (this.config.psr2) { 63 | this.args.push('--psr2'); 64 | } 65 | 66 | if (this.config.wp) { 67 | this.args.push('--wp'); 68 | } 69 | 70 | if (!this.config.detect_indent) { 71 | const spaces = this.config.indent_with_space; 72 | if (spaces === true) { 73 | this.args.push('--indent_with_space'); 74 | } else if (typeof spaces === 'number' && spaces > 0) { 75 | this.args.push(`--indent_with_space=${spaces}`); 76 | } 77 | } 78 | 79 | if (this.config.enable_auto_align) { 80 | this.args.push('--enable_auto_align'); 81 | } 82 | 83 | if (this.config.visibility_order) { 84 | this.args.push('--visibility_order'); 85 | } 86 | 87 | const passes = this.config.passes; 88 | if (passes.length > 0) { 89 | this.args.push(`--passes=${passes.join(',')}`); 90 | } 91 | 92 | const exclude = this.config.exclude; 93 | if (exclude.length > 0) { 94 | this.args.push(`--exclude=${exclude.join(',')}`); 95 | } 96 | 97 | if (this.config.smart_linebreak_after_curly) { 98 | this.args.push('--smart_linebreak_after_curly'); 99 | } 100 | 101 | if (this.config.yoda) { 102 | this.args.push('--yoda'); 103 | } 104 | 105 | if (this.config.cakephp) { 106 | this.args.push('--cakephp'); 107 | } 108 | } 109 | 110 | public getFmt(): IPHPFmt { 111 | return this.config.use_old_phpfmt ? phpfmt.v1 : phpfmt.v2; 112 | } 113 | 114 | public getPharPath(): string { 115 | return this.getFmt().pharPath; 116 | } 117 | 118 | public getTransformation(): Transformation { 119 | return this.transformation; 120 | } 121 | 122 | private getArgs(fileName: string): string[] { 123 | const args = this.args.slice(0); 124 | args.push(`"${fileName}"`); 125 | return args; 126 | } 127 | 128 | public async format(text: string): Promise { 129 | const passes = [...this.config.passes, ...this.config.exclude]; 130 | const transformations = await this.transformation.getTransformations(); 131 | if (passes.length > 0) { 132 | const invalidPasses: string[] = []; 133 | for (const pass of passes) { 134 | if ( 135 | !transformations.some( 136 | transformation => transformation.key === pass 137 | ) && 138 | !this.transformation.isExists(pass) 139 | ) { 140 | invalidPasses.push(pass); 141 | } 142 | } 143 | 144 | if (invalidPasses.length > 0) { 145 | throw new PHPFmtError( 146 | `passes or exclude invalid: ${invalidPasses.join(', ')}` 147 | ); 148 | } 149 | } 150 | 151 | if (this.config.detect_indent) { 152 | const indentInfo = detectIndent(text); 153 | if (!indentInfo.type) { 154 | // fallback to default 155 | this.args.push('--indent_with_space'); 156 | } else if (indentInfo.type === 'space') { 157 | this.args.push(`--indent_with_space=${indentInfo.amount}`); 158 | } 159 | } else { 160 | if (this.config.indent_with_space !== 4 && this.config.psr2) { 161 | throw new PHPFmtError( 162 | 'For PSR2, code MUST use 4 spaces for indenting, not tabs.' 163 | ); 164 | } 165 | } 166 | 167 | let fileName: string | undefined; 168 | let iniPath: string | undefined; 169 | const execOptions = { cwd: '' }; 170 | if (vscode.window.activeTextEditor != null) { 171 | fileName = vscode.window.activeTextEditor.document.fileName; 172 | execOptions.cwd = path.dirname(fileName); 173 | 174 | const workspaceFolders = vscode.workspace.workspaceFolders; 175 | if (workspaceFolders != null) { 176 | iniPath = await findUp('.php.tools.ini', { 177 | cwd: execOptions.cwd 178 | }); 179 | const origIniPath = iniPath; 180 | 181 | const workspaceFolder = workspaceFolders.find(folder => 182 | iniPath?.startsWith(folder.uri.fsPath) 183 | ); 184 | iniPath = workspaceFolder != null ? origIniPath : undefined; 185 | } 186 | } 187 | 188 | try { 189 | const { stdout, stderr, code } = await exec( 190 | `${this.config.php_bin} -v`, 191 | execOptions 192 | ); 193 | if (code !== 0) { 194 | this.widget.logError('getting php version failed', stderr); 195 | throw new PHPFmtError(`"php -v" returns non-zero code`); 196 | } 197 | const match = /PHP ([\d.]+)/i.exec(stdout); 198 | if (match == null) { 199 | throw new PHPFmtError('Failed to parse php version'); 200 | } 201 | const phpVersion = match[1]; 202 | 203 | if (this.config.use_old_phpfmt) { 204 | if ( 205 | compare(phpVersion, '5.6.0', '<') || 206 | compare(phpVersion, '8.0.0', '>') 207 | ) { 208 | throw new PHPFmtError('PHP version < 5.6 or > 8.0'); 209 | } 210 | } else { 211 | if (compare(phpVersion, '5.6.0', '<')) { 212 | throw new PHPFmtError('PHP version < 5.6'); 213 | } 214 | } 215 | } catch (err) { 216 | if (err instanceof PHPFmtError) { 217 | throw err; 218 | } else { 219 | this.widget.logError('getting php version failed', err); 220 | throw new PHPFmtError(`Error getting php version`); 221 | } 222 | } 223 | 224 | const tmpDir = os.tmpdir(); 225 | 226 | let tmpRandomFileName = `${tmpDir}/temp-${Math.random() 227 | .toString(36) 228 | .replace(/[^a-z]+/g, '') 229 | .substring(0, 10)}`; 230 | 231 | if (fileName) { 232 | const basename = path.basename(fileName); 233 | const ignore = this.config.ignore; 234 | if (ignore.length > 0) { 235 | for (const ignoreItem of ignore) { 236 | if (basename.match(ignoreItem) != null) { 237 | this.widget.logInfo( 238 | `Ignored file ${basename} by match of ${ignoreItem}` 239 | ); 240 | this.widget.updateStatusBarItem(PHPFmtStatus.Ignore); 241 | return ''; 242 | } 243 | } 244 | } 245 | tmpRandomFileName += `-${basename}`; 246 | } else { 247 | tmpRandomFileName += '.php'; 248 | } 249 | 250 | const tmpFileName = path.normalize(tmpRandomFileName); 251 | 252 | try { 253 | await fs.writeFile(tmpFileName, text); 254 | } catch (err) { 255 | this.widget.logError('Create tmp file failed', err); 256 | throw new PHPFmtError(`Cannot create tmp file in "${tmpDir}"`); 257 | } 258 | 259 | const hasAutoSemicolon = 260 | this.config.passes.includes('AutoSemicolon') || 261 | this.config.exclude.includes('AutoSemicolon'); 262 | 263 | if (!hasAutoSemicolon) { 264 | // test whether the php file has syntax error 265 | try { 266 | await exec(`${this.config.php_bin} -l "${tmpFileName}"`, execOptions); 267 | } catch (err) { 268 | this.widget.logError('PHP lint failed', err); 269 | vscode.window.setStatusBarMessage( 270 | 'phpfmt: Format failed - syntax errors found', 271 | 4500 272 | ); 273 | throw new PHPFmtSkipError(); 274 | } 275 | } else { 276 | this.widget.logInfo('Skipping PHP lint because AutoSemicolon is active'); 277 | } 278 | 279 | const args = this.getArgs(tmpFileName); 280 | args.unshift(`"${this.getPharPath()}"`); 281 | 282 | let formatCmd: string; 283 | if (!iniPath) { 284 | formatCmd = `${this.config.php_bin} ${args.join(' ')}`; 285 | } else { 286 | this.widget.logInfo(`Using config file: ${iniPath}`); 287 | formatCmd = `${this.config.php_bin} ${ 288 | args[0] 289 | } --config=${iniPath} ${args.pop()}`; 290 | } 291 | 292 | this.widget.logInfo(`Executing command: ${formatCmd}`); 293 | 294 | try { 295 | await exec(formatCmd, execOptions); 296 | } catch (err) { 297 | this.widget.logError('Execute command failed', err).show(); 298 | throw new PHPFmtError('Execute phpfmt failed'); 299 | } 300 | 301 | const formatted = await fs.readFile(tmpFileName, 'utf-8'); 302 | try { 303 | await fs.unlink(tmpFileName); 304 | } catch (err) { 305 | this.widget.logError('Remove temp file failed', err); 306 | } 307 | 308 | return formatted; 309 | } 310 | } 311 | -------------------------------------------------------------------------------- /src/PHPFmtProvider.ts: -------------------------------------------------------------------------------- 1 | import type { PHPFmt } from './PHPFmt'; 2 | import type { Transformation } from './Transformation'; 3 | import * as vscode from 'vscode'; 4 | import * as meta from './meta'; 5 | import { PHPFmtSkipError } from './PHPFmtError'; 6 | import { PHPFmtStatus, type Widget } from './Widget'; 7 | 8 | export class PHPFmtProvider { 9 | private readonly documentSelector: vscode.DocumentSelector; 10 | private transformation: Transformation; 11 | private config: vscode.WorkspaceConfiguration; 12 | 13 | public constructor( 14 | private readonly widget: Widget, 15 | private readonly phpfmt: PHPFmt 16 | ) { 17 | this.config = vscode.workspace.getConfiguration('phpfmt'); 18 | this.documentSelector = [ 19 | { language: 'php', scheme: 'file' }, 20 | { language: 'php', scheme: 'untitled' } 21 | ]; 22 | this.transformation = this.phpfmt.getTransformation(); 23 | } 24 | 25 | public registerOnDidChangeConfiguration(): vscode.Disposable { 26 | return vscode.workspace.onDidChangeConfiguration(() => { 27 | this.config = vscode.workspace.getConfiguration('phpfmt'); 28 | this.phpfmt.loadSettings(); 29 | this.transformation = this.phpfmt.getTransformation(); 30 | this.widget.logInfo(`settings reloaded`); 31 | }); 32 | } 33 | 34 | public registerFormatCommand(): vscode.Disposable { 35 | return vscode.commands.registerTextEditorCommand( 36 | meta.commands.format, 37 | textEditor => { 38 | if (textEditor.document.languageId === 'php') { 39 | void vscode.commands.executeCommand('editor.action.formatDocument'); 40 | } 41 | } 42 | ); 43 | } 44 | 45 | private async getTransformationItems(): Promise { 46 | const transformationItems = await this.transformation.getTransformations(); 47 | const items = transformationItems.map(o => ({ 48 | label: o.key, 49 | description: o.description 50 | })); 51 | return items; 52 | } 53 | 54 | public registerListTransformationsCommand(): vscode.Disposable { 55 | return vscode.commands.registerCommand( 56 | meta.commands.listTransformations, 57 | async () => { 58 | const items = await this.getTransformationItems(); 59 | const result = await vscode.window.showQuickPick(items); 60 | 61 | if (typeof result !== 'undefined') { 62 | this.widget.logInfo('Getting transformation output'); 63 | const output = await this.transformation.getExample({ 64 | key: result.label, 65 | description: result.description ?? '' 66 | }); 67 | 68 | this.widget.getOutputChannel().appendLine(output); 69 | this.widget.getOutputChannel().show(); 70 | } 71 | } 72 | ); 73 | } 74 | 75 | private async showUpdateConfigQuickPick( 76 | section: string, 77 | value: T 78 | ): Promise { 79 | const targetResult = await vscode.window.showQuickPick( 80 | ['Global', 'Workspace'], 81 | { 82 | placeHolder: 'Where to update settings.json?' 83 | } 84 | ); 85 | let target: vscode.ConfigurationTarget; 86 | 87 | if (targetResult === 'Global') { 88 | target = vscode.ConfigurationTarget.Global; 89 | } else { 90 | target = vscode.ConfigurationTarget.Workspace; 91 | } 92 | 93 | try { 94 | await this.config.update(section, value, target); 95 | await vscode.window.showInformationMessage( 96 | 'Configuration updated successfully!' 97 | ); 98 | } catch { 99 | await vscode.window.showErrorMessage('Configuration updated failed!'); 100 | } 101 | } 102 | 103 | public registerToggleTransformationsCommand(): vscode.Disposable[] { 104 | const commands = [ 105 | { 106 | command: meta.commands.toggleAdditionalTransformations, 107 | key: 'passes' 108 | }, 109 | { 110 | command: meta.commands.toggleExcludedTransformations, 111 | key: 'exclude' 112 | } 113 | ]; 114 | 115 | return commands.map(command => 116 | vscode.commands.registerCommand(command.command, async () => { 117 | const items = await this.getTransformationItems(); 118 | items.unshift({ 119 | label: 'All', 120 | description: 'Choose all of following' 121 | }); 122 | 123 | const result = await vscode.window.showQuickPick(items); 124 | 125 | if (typeof result !== 'undefined') { 126 | let value = this.config.get(command.key); 127 | if (result.label === 'All') { 128 | value = items.filter(o => o.label !== 'All').map(o => o.label); 129 | } else { 130 | const enabled = value?.includes(result.label); 131 | const enableResult = await vscode.window.showQuickPick([ 132 | { 133 | label: 'Enable', 134 | description: enabled ? 'Current' : '' 135 | }, 136 | { 137 | label: 'Disable', 138 | description: !enabled ? 'Current' : '' 139 | } 140 | ]); 141 | if (typeof enableResult !== 'undefined') { 142 | if (enableResult.label === 'Enable' && !enabled) { 143 | value?.push(result.label); 144 | } else if (enableResult.label === 'Disable' && enabled) { 145 | value = value?.filter(v => v !== result.label); 146 | } 147 | } 148 | } 149 | 150 | await this.showUpdateConfigQuickPick(command.key, value); 151 | } 152 | }) 153 | ); 154 | } 155 | 156 | public registerToggleBooleanCommand(): vscode.Disposable[] { 157 | const commands = [ 158 | { 159 | command: meta.commands.togglePSR1Naming, 160 | key: 'psr1_naming' 161 | }, 162 | { 163 | command: meta.commands.togglePSR1, 164 | key: 'psr1' 165 | }, 166 | { 167 | command: meta.commands.togglePSR2, 168 | key: 'psr2' 169 | }, 170 | { 171 | command: meta.commands.toggleAutoAlign, 172 | key: 'enable_auto_align' 173 | } 174 | ]; 175 | 176 | return commands.map(command => 177 | vscode.commands.registerCommand(command.command, async () => { 178 | const value = this.config.get(command.key); 179 | const result = await vscode.window.showQuickPick([ 180 | { 181 | label: 'Enable', 182 | description: value ? 'Current' : '' 183 | }, 184 | { 185 | label: 'Disable', 186 | description: !value ? 'Current' : '' 187 | } 188 | ]); 189 | 190 | if (typeof result !== 'undefined') { 191 | await this.showUpdateConfigQuickPick( 192 | command.key, 193 | result.label === 'Enable' 194 | ); 195 | } 196 | }) 197 | ); 198 | } 199 | 200 | public registerToggleIndentWithSpaceCommand(): vscode.Disposable { 201 | return vscode.commands.registerCommand( 202 | meta.commands.toggleIndentWithSpace, 203 | async () => { 204 | const result = await vscode.window.showQuickPick([ 205 | 'tabs', 206 | '2', 207 | '4', 208 | '6', 209 | '8' 210 | ]); 211 | 212 | if (typeof result !== 'undefined') { 213 | const value = result === 'tabs' ? false : Number(result); 214 | 215 | await this.showUpdateConfigQuickPick('indent_with_space', value); 216 | } 217 | } 218 | ); 219 | } 220 | 221 | public registerDocumentFormattingEditProvider(): vscode.Disposable { 222 | return vscode.languages.registerDocumentFormattingEditProvider( 223 | this.documentSelector, 224 | { 225 | provideDocumentFormattingEdits: async document => { 226 | try { 227 | const originalText = document.getText(); 228 | const lastLine = document.lineAt(document.lineCount - 1); 229 | const range = new vscode.Range( 230 | new vscode.Position(0, 0), 231 | lastLine.range.end 232 | ); 233 | 234 | const text = await this.phpfmt.format(originalText); 235 | this.widget.updateStatusBarItem(PHPFmtStatus.Success); 236 | if (text && text !== originalText) { 237 | return [new vscode.TextEdit(range, text)]; 238 | } 239 | } catch (err) { 240 | this.widget.updateStatusBarItem(PHPFmtStatus.Error); 241 | if (!(err instanceof PHPFmtSkipError) && err instanceof Error) { 242 | void vscode.window.showErrorMessage(err.message); 243 | this.widget.logError('Format failed', err); 244 | } 245 | } 246 | return []; 247 | } 248 | } 249 | ); 250 | } 251 | 252 | public registerDocumentRangeFormattingEditProvider(): vscode.Disposable { 253 | return vscode.languages.registerDocumentRangeFormattingEditProvider( 254 | this.documentSelector, 255 | { 256 | provideDocumentRangeFormattingEdits: async (document, range) => { 257 | try { 258 | let originalText = document.getText(range); 259 | if (originalText.replace(/\s+/g, '').length === 0) { 260 | return []; 261 | } 262 | 263 | let hasModified = false; 264 | if (originalText.search(/^\s*<\?php/i) === -1) { 265 | originalText = ` { 293 | this.widget.toggleStatusBarItem(editor); 294 | }), 295 | vscode.commands.registerCommand(meta.commands.openOutput, () => { 296 | this.widget.getOutputChannel().show(); 297 | }) 298 | ]; 299 | } 300 | } 301 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # phpfmt for Visual Studio Code 2 | 3 | [![Version](https://img.shields.io/visual-studio-marketplace/v/kokororin.vscode-phpfmt)](https://marketplace.visualstudio.com/items?itemName=kokororin.vscode-phpfmt) 4 | [![Visual Studio Marketplace](https://img.shields.io/visual-studio-marketplace/i/kokororin.vscode-phpfmt)](https://marketplace.visualstudio.com/items?itemName=kokororin.vscode-phpfmt) 5 | 6 | The missing phpfmt extension for Visual Studio Code. 7 | 8 | ## Installation 9 | 10 | Open command palette `F1` and select `Extensions: Install Extension`, then search for phpfmt. 11 | 12 | **Note**: PHP 5.6 or newer is required in the machine to run this plugin. 13 | 14 | 15 | ## Usage 16 | 17 | `F1` -> `phpfmt: Format This File` 18 | 19 | or keyboard shortcut `Ctrl + Shift + I` which is Visual Studio Code default formatter shortcut 20 | 21 | or right mouse context menu `Format Document` or `Format Selection` 22 | 23 | ### Format On Save 24 | 25 | Respects `editor.formatOnSave` setting. 26 | 27 | You can turn off format-on-save on a per-language basis by scoping the setting: 28 | 29 | ```json5 30 | // Set the default 31 | "editor.formatOnSave": false, 32 | // Enable per-language 33 | "[php]": { 34 | "editor.formatOnSave": true 35 | } 36 | ``` 37 | 38 | ## Q&A 39 | 40 | Q: How to use `phpfmt.php_bin` with spaces such as `C:\Program Files\php\php.exe` ? 41 | A: Wrap your path with quotes like: 42 | 43 | ```json 44 | { 45 | "phpfmt.php_bin": "\"C:\\Program Files\\php\\php.exe\"" 46 | } 47 | ``` 48 | 49 | It is recommended to add the directory of the `php.exe` to the PATH environment variable on Windows. 50 | If it still not working, refer to [#1](https://github.com/kokororin/vscode-phpfmt/issues/1) and [Stack Overflow Related](https://stackoverflow.com/a/45765854). 51 | 52 | 53 | Q: How use tabs instead of spaces with PSR2 enabled ? 54 | A: For [PSR2](https://www.php-fig.org/psr/psr-2/), code MUST use 4 spaces for indenting, not tabs. But if you like PSR2, and do not like 4 spaces for indentation, add following configuration: 55 | 56 | ```json 57 | { 58 | "phpfmt.passes": [ 59 | "PSR2KeywordsLowerCase", 60 | "PSR2LnAfterNamespace", 61 | "PSR2CurlyOpenNextLine", 62 | "PSR2ModifierVisibilityStaticOrder", 63 | "PSR2SingleEmptyLineAndStripClosingTag", 64 | "ReindentSwitchBlocks" 65 | ], 66 | "phpfmt.exclude": [ 67 | "ReindentComments", 68 | "StripNewlineWithinClassBody" 69 | ], 70 | "phpfmt.psr2": false 71 | } 72 | ``` 73 | 74 | Q: Is fmt.phar (phpfmt itself) still maintained ? 75 | ~~A: Since phpfmt has no maintainers, only Serious bugs will be fixed.~~ 76 | A: We now use `fmt.stub.php` from driade's [phpfmt8](https://github.com/driade/phpfmt8) which is very updated. 77 | 78 | ## Configuration 79 | 80 | 81 | | Key | Type | Description | Default | 82 | | - | - | - | - | 83 | | phpfmt.php_bin | `string` | php executable path | "php" | 84 | | phpfmt.use_old_phpfmt | `boolean` | use old fmt.phar which supports 5.6 | false | 85 | | phpfmt.detect_indent | `boolean` | auto detecting indent type and size (will ignore indent_with_space) | false | 86 | | phpfmt.psr1 | `boolean` | activate PSR1 style | false | 87 | | phpfmt.psr1_naming | `boolean` | activate PSR1 style - Section 3 and 4.3 - Class and method names case. | false | 88 | | phpfmt.psr2 | `boolean` | activate PSR2 style | true | 89 | | phpfmt.wp | `boolean` | activate WP style | false | 90 | | phpfmt.indent_with_space | `integer \| boolean` | use spaces instead of tabs for indentation. Default 4 | 4 | 91 | | phpfmt.enable_auto_align | `boolean` | enable auto align of ST_EQUAL and T_DOUBLE_ARROW | false | 92 | | phpfmt.visibility_order | `boolean` | fixes visibiliy order for method in classes - PSR-2 4.2 | false | 93 | | phpfmt.ignore | `array` | ignore file names whose names contain any pattern that could be matched with `.match` JS string method | [] | 94 | | phpfmt.passes | `array` | call specific compiler pass | ["AlignDoubleArrow","AlignPHPCode","SpaceAfterExclamationMark","AlignConstVisibilityEquals","AutoSemicolon","ConvertOpenTagWithEcho","AlignEquals","MergeNamespaceWithOpenTag","RemoveSemicolonAfterCurly","RestoreComments","ShortArray","ExtraCommaInArray","AlignDoubleSlashComments","IndentTernaryConditions","IndentPipeOperator"] | 95 | | phpfmt.exclude | `array` | disable specific passes | [] | 96 | | phpfmt.smart_linebreak_after_curly | `boolean` | convert multistatement blocks into multiline blocks | false | 97 | | phpfmt.yoda | `boolean` | yoda-style comparisons | false | 98 | | phpfmt.cakephp | `boolean` | Apply CakePHP coding style | false | 99 | | phpfmt.custom_arguments | `string` | provide custom arguments to overwrite default arguments generated by config | "" | 100 | 101 | 102 | ## Supported Transformations 103 | 104 | `F1` -> `phpfmt: List Transformations` to get the example of each 105 | transformation. 106 | 107 | 108 | | Key | Description | 109 | | - | - | 110 | | SmartLnAfterCurlyOpen | Add line break when implicit curly block is added. | 111 | | AddMissingParentheses | Add extra parentheses in new instantiations. | 112 | | AliasToMaster | Replace function aliases to their masters - only basic syntax alias. | 113 | | AlignConstVisibilityEquals | Vertically align "=" of visibility and const blocks. | 114 | | AlignDoubleArrow | Vertically align T_DOUBLE_ARROW (=>). | 115 | | AlignComments | Vertically align "//" comments. | 116 | | AlignDoubleSlashComments | Vertically align "//" comments. | 117 | | AlignEquals | Vertically align "=". | 118 | | AlignSuperEquals | Vertically align "=", ".=", "&=", ">>=", etc. | 119 | | AlignGroupDoubleArrow | Vertically align T_DOUBLE_ARROW (=>) by line groups. | 120 | | AlignPHPCode | Align PHP code within HTML block. | 121 | | AlignTypehint | Vertically align function type hints. | 122 | | AllmanStyleBraces | Transform all curly braces into Allman-style. | 123 | | AutoPreincrement | Automatically convert postincrement to preincrement. | 124 | | AutoSemicolon | Add semicolons in statements ends. | 125 | | CakePHPStyle | Applies CakePHP Coding Style | 126 | | ClassToSelf | "self" is preferred within class, trait or interface. | 127 | | ClassToStatic | "static" is preferred within class, trait or interface. | 128 | | ConvertOpenTagWithEcho | Convert from " implode()). | 136 | | LeftWordWrap | Word wrap at 80 columns - left justify. | 137 | | LongArray | Convert short to long arrays. | 138 | | MergeElseIf | Merge if with else. | 139 | | SplitElseIf | Merge if with else. | 140 | | MergeNamespaceWithOpenTag | Ensure there is no more than one linebreak before namespace | 141 | | MildAutoPreincrement | Automatically convert postincrement to preincrement. (Deprecated pass. Use AutoPreincrement instead). | 142 | | NewLineBeforeReturn | Add an empty line before T_RETURN. | 143 | | OrganizeClass | Organize class, interface and trait structure. | 144 | | OrderAndRemoveUseClauses | Order use block and remove unused imports. | 145 | | OnlyOrderUseClauses | Order use block - do not remove unused imports. | 146 | | OrderMethod | Organize class, interface and trait structure. | 147 | | OrderMethodAndVisibility | Organize class, interface and trait structure. | 148 | | PHPDocTypesToFunctionTypehint | Read variable types from PHPDoc blocks and add them in function signatures. | 149 | | PrettyPrintDocBlocks | Prettify Doc Blocks | 150 | | PSR2EmptyFunction | Merges in the same line of function header the body of empty functions. | 151 | | PSR2MultilineFunctionParams | Break function parameters into multiple lines. | 152 | | ReindentAndAlignObjOps | Align object operators. | 153 | | ReindentSwitchBlocks | Reindent one level deeper the content of switch blocks. | 154 | | ReindentEnumBlocks | Reindent one level deeper the content of enum blocks. | 155 | | RemoveIncludeParentheses | Remove parentheses from include declarations. | 156 | | RemoveSemicolonAfterCurly | Remove semicolon after closing curly brace. | 157 | | RemoveUseLeadingSlash | Remove leading slash in T_USE imports. | 158 | | ReplaceBooleanAndOr | Convert from "and"/"or" to "&&"/"||". Danger! This pass leads to behavior change. | 159 | | ReplaceIsNull | Replace is_null($a) with null === $a. | 160 | | RestoreComments | Revert any formatting of comments content. | 161 | | ReturnNull | Simplify empty returns. | 162 | | ShortArray | Convert old array into new array. (array() -> []) | 163 | | SortUseNameSpace | Organize use clauses by length and alphabetic order. | 164 | | SpaceAroundControlStructures | Add space around control structures. | 165 | | SpaceAroundExclamationMark | Add spaces around exclamation mark. | 166 | | SpaceBetweenMethods | Put space between methods. | 167 | | StrictBehavior | Activate strict option in array_search, base64_decode, in_array, array_keys, mb_detect_encoding. Danger! This pass leads to behavior change. | 168 | | StrictComparison | All comparisons are converted to strict. Danger! This pass leads to behavior change. | 169 | | StripExtraCommaInArray | Remove trailing commas within array blocks | 170 | | StripNewlineAfterClassOpen | Strip empty lines after class opening curly brace. | 171 | | StripNewlineAfterCurlyOpen | Strip empty lines after opening curly brace. | 172 | | StripNewlineWithinClassBody | Strip empty lines after class opening curly brace. | 173 | | StripSpaces | Remove all empty spaces | 174 | | StripSpaceWithinControlStructures | Strip empty lines within control structures. | 175 | | TightConcat | Ensure string concatenation does not have spaces, except when close to numbers. | 176 | | TrimSpaceBeforeSemicolon | Remove empty lines before semi-colon. | 177 | | UpgradeToPreg | Upgrade ereg_* calls to preg_* | 178 | | WordWrap | Word wrap at 80 columns. | 179 | | WrongConstructorName | Update old constructor names into new ones. http://php.net/manual/en/language.oop5.decon.php | 180 | | YodaComparisons | Execute Yoda Comparisons. | 181 | | SpaceAfterExclamationMark | Add space after exclamation mark. | 182 | | SpaceAroundParentheses | Add spaces inside parentheses. | 183 | | IndentPipeOperator | Applies indentation to the pipe operator. | 184 | 185 | 186 | ## Contribute 187 | 188 | ### Running extension 189 | 190 | - Open this repository inside Visual Studio Code 191 | - Debug sidebar 192 | - `Launch Extension` 193 | 194 | ### Running tests 195 | 196 | - Open this repository inside Visual Studio Code 197 | - Debug sidebar 198 | - `Launch Tests` 199 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### 1.2.55 2 | 3 | - Upgrade fmt.stub.php [(V1059.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1059.0.0) 4 | 5 | ### 1.2.54 6 | 7 | - Upgrade fmt.stub.php [(V1058.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1058.0.0) 8 | 9 | ### 1.2.53 10 | 11 | - Upgrade fmt.stub.php [(V1054.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1054.0.0) 12 | 13 | ### 1.2.49 14 | 15 | - Upgrade fmt.stub.php [(V1053.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1053.0.0) 16 | 17 | ### 1.2.48 18 | 19 | - Upgrade fmt.stub.php [(V1052.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1052.0.0) 20 | 21 | ### 1.2.47 22 | 23 | - Upgrade fmt.stub.php [(V1051.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1051.0.0) 24 | 25 | ### 1.2.46 26 | 27 | - Upgrade fmt.stub.php [(V1050.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1050.0.0) 28 | 29 | ### 1.2.45 30 | 31 | - Upgrade fmt.stub.php [(V1049.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1049.0.0) 32 | 33 | ### 1.2.44 34 | 35 | - Upgrade fmt.stub.php [(V1049.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1049.0.0) 36 | 37 | ### 1.2.43 38 | 39 | - Upgrade fmt.stub.php [(V1049.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1049.0.0) 40 | 41 | ### 1.2.42 42 | 43 | - Upgrade fmt.stub.php [(V1049.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1049.0.0) 44 | 45 | ### 1.2.41 46 | 47 | - Upgrade fmt.stub.php [(V1049.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1049.0.0) 48 | 49 | ### 1.2.40 50 | 51 | - Upgrade fmt.stub.php [(V1048.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1048.0.0) 52 | 53 | ### 1.2.39 54 | 55 | - Upgrade fmt.stub.php [(V1047.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1047.0.0) 56 | 57 | ### 1.2.38 58 | 59 | - Upgrade fmt.stub.php [(V1046.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1046.0.0) 60 | 61 | ### 1.2.37 62 | 63 | - Upgrade fmt.stub.php [(V1045.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1045.0.0) 64 | 65 | ### 1.2.36 66 | 67 | - Upgrade fmt.stub.php [(V1043.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1043.0.0) 68 | 69 | ### 1.2.35 70 | 71 | - Upgrade fmt.stub.php [(V1043.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1043.0.0) 72 | 73 | ### 1.2.34 74 | 75 | - Upgrade fmt.stub.php [(V1042.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1042.0.0) 76 | 77 | ### 1.2.33 78 | 79 | - Upgrade fmt.stub.php [(V1041.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1041.0.0) 80 | 81 | ### 1.2.32 82 | 83 | - Default configuration synchronized from `phpfmt.sublime-settings` [(#161)](https://github.com/kokororin/vscode-phpfmt/issues/161) 84 | 85 | ### 1.2.31 86 | 87 | - Upgrade fmt.stub.php [(V1040.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1040.0.0) 88 | 89 | ### 1.2.30 90 | 91 | - Upgrade fmt.stub.php [(V1039.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1039.0.0) 92 | 93 | ### 1.2.29 94 | 95 | - Upgrade fmt.stub.php [(V1038.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1038.0.0) 96 | 97 | ### 1.2.28 98 | 99 | - Upgrade fmt.stub.php [(V1037.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1037.0.0) 100 | 101 | ### 1.2.27 102 | 103 | - Upgrade fmt.stub.php [(V1035.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1035.0.0) 104 | 105 | ### 1.2.26 106 | 107 | - Upgrade fmt.stub.php [(V1035.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1035.0.0) 108 | 109 | ### 1.2.25 110 | 111 | - Upgrade fmt.stub.php [(Verror code: 525)](https://github.com/driade/phpfmt8/releases/tag/verror code: 525) 112 | 113 | ### 1.2.24 114 | 115 | - Upgrade fmt.stub.php [(V1035.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1035.0.0) 116 | 117 | ### 1.2.23 118 | 119 | - Remove PHP 8.4 check 120 | 121 | ### 1.2.22 122 | 123 | - Upgrade fmt.stub.php [(V1034.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1034.0.0) 124 | 125 | ### 1.2.21 126 | 127 | - Upgrade fmt.stub.php [(V1033.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1033.0.0) 128 | 129 | ### 1.2.20 130 | 131 | - Upgrade fmt.stub.php [(V1033.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1033.0.0) 132 | 133 | ### 1.2.19 134 | 135 | - Upgrade fmt.stub.php [(V1032.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1032.0.0) 136 | 137 | ### 1.2.18 138 | 139 | - Upgrade fmt.stub.php [(V1031.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1031.0.0) 140 | 141 | ### 1.2.17 142 | 143 | - Fix some passes cannot be configured [(#156)](https://github.com/kokororin/vscode-phpfmt/issues/156) 144 | 145 | ### 1.2.16 146 | 147 | - Upgrade fmt.stub.php [(V1029.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1029.0.0) 148 | 149 | ### 1.2.15 150 | 151 | - Upgrade fmt.stub.php [(V1029.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1029.0.0) 152 | 153 | ### 1.2.14 154 | 155 | - Upgrade fmt.stub.php [(V1029.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1029.0.0) 156 | 157 | ### 1.2.13 158 | 159 | - Upgrade fmt.stub.php [(V1027.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1027.0.0) 160 | 161 | ### 1.2.12 162 | 163 | - Upgrade fmt.stub.php [(V1026.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1026.0.0) 164 | 165 | ### 1.2.11 166 | 167 | - Upgrade fmt.stub.php [(V1025.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1025.0.0) 168 | 169 | ### 1.2.10 170 | 171 | - Upgrade fmt.stub.php [(V1024.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1024.0.0) 172 | 173 | ### 1.2.10 174 | 175 | - Upgrade fmt.stub.php [(V1023.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1023.0.0) 176 | 177 | ### 1.2.9 178 | 179 | - Upgrade fmt.stub.php [(V1023.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1023.0.0) 180 | 181 | ### 1.2.8 182 | 183 | - Upgrade fmt.stub.php [(V1023.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1023.0.0) 184 | 185 | ### 1.2.7 186 | 187 | - Upgrade fmt.stub.php [(V1023.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1023.0.0) 188 | 189 | ### 1.2.6 190 | 191 | - Upgrade fmt.stub.php [(V1023.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1023.0.0) 192 | 193 | ### 1.2.5 194 | 195 | - Upgrade fmt.stub.php [(V1023.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1023.0.0) 196 | 197 | ### 1.2.4 198 | 199 | - Upgrade fmt.stub.php [(V1023.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1023.0.0) 200 | 201 | ### 1.2.3 202 | 203 | - Upgrade fmt.stub.php [(V1023.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1023.0.0) 204 | 205 | ### 1.2.2 206 | 207 | - Upgrade fmt.stub.php [(V1023.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1023.0.0) 208 | 209 | ### 1.2.1 210 | 211 | - Upgrade fmt.stub.php [(V1023.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1023.0.0) 212 | 213 | ### 1.2.9 214 | 215 | - Upgrade fmt.stub.php [(V1023.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1023.0.0) 216 | 217 | ### 1.2.0 218 | 219 | - Switch package manager to PNPM 220 | 221 | ### 1.1.40 222 | 223 | - Fix lint php files with spaces failed 224 | 225 | ### 1.1.39 226 | 227 | - Upgrade fmt.stub.php [(V1021.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1021.0.0) 228 | 229 | ### 1.1.38 230 | 231 | - Upgrade fmt.stub.php [(V1020.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1020.0.0) 232 | 233 | ### 1.1.37 234 | 235 | - Upgrade fmt.stub.php [(V1010.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1010.0.0) 236 | 237 | ### 1.1.36 238 | 239 | - Supports php 8.3 240 | 241 | ### 1.1.35 242 | 243 | - Fix php version bug [(#135)](https://github.com/kokororin/vscode-phpfmt/issues/135) 244 | 245 | ### 1.1.34 246 | 247 | - Upgrade fmt.stub.php [(V1010.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1010.0.0) 248 | 249 | ### 1.1.33 250 | 251 | - Upgrade fmt.stub.php [(V1009.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1009.0.0) 252 | 253 | ### 1.1.32 254 | 255 | - Upgrade fmt.stub.php [(V1008.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1008.0.0) 256 | 257 | ### 1.1.31 258 | 259 | - Upgrade fmt.stub.php [(V1007.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1007.0.0) 260 | 261 | ### 1.1.30 262 | 263 | - Upgrade fmt.stub.php [(V1007.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1007.0.0) 264 | 265 | ### 1.1.29 266 | 267 | - Upgrade fmt.stub.php [(V1006.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1006.0.0) 268 | 269 | ### 1.1.28 270 | 271 | - Upgrade fmt.stub.php [(V1005.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1005.0.0) 272 | 273 | ### 1.1.27 274 | 275 | - Upgrade fmt.stub.php [(V1004.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1004.0.0) 276 | 277 | ### 1.1.26 278 | 279 | - Upgrade fmt.stub.php [(V1003.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1003.0.0) 280 | 281 | ### 1.1.25 282 | 283 | - Upgrade fmt.stub.php [(V1002.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1002.0.0) 284 | 285 | ### 1.1.24 286 | 287 | - Upgrade fmt.stub.php [(V1001.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1001.0.0) 288 | 289 | ### 1.1.23 290 | 291 | - Upgrade fmt.stub.php [(V1000.0.0)](https://github.com/driade/phpfmt8/releases/tag/v1000.0.0) 292 | 293 | ### 1.1.22 294 | 295 | - Supports PHP 5.6 296 | 297 | ### 1.1.21 298 | 299 | - Upgrade fmt.stub.php [(V998.0.0)](https://github.com/driade/phpfmt8/releases/tag/v998.0.0) 300 | 301 | ### 1.1.20 302 | 303 | - Just bump version 304 | 305 | ### 1.1.19 306 | 307 | - Remove command `upgradeFmt` 308 | - Add format status to StatusBar 309 | 310 | ### 1.1.18 311 | 312 | - Upgrade fmt.stub.php [(V996.0.0)](https://github.com/driade/phpfmt8/releases/tag/v996.0.0) 313 | 314 | ### 1.1.17 315 | 316 | - Upgrade fmt.stub.php [(V995.0.0)](https://github.com/driade/phpfmt8/releases/tag/v995.0.0) 317 | 318 | ### 1.1.16 319 | 320 | - Upgrade fmt.stub.php [(V993.0.0)](https://github.com/driade/phpfmt8/releases/tag/v993.0.0) 321 | 322 | ### 1.1.15 323 | 324 | - Upgrade fmt.stub.php [(V992.0.0)](https://github.com/driade/phpfmt8/releases/tag/v992.0.0) 325 | 326 | ### 1.1.13 327 | 328 | - Upgrade fmt.stub.php [(V891.0.0)](https://github.com/driade/phpfmt8/releases/tag/v891.0.0) 329 | 330 | ### 1.1.12 331 | 332 | - Upgrade fmt 333 | 334 | ### 1.1.11 335 | 336 | - Add upgrade logs 337 | 338 | ### 1.1.10 339 | 340 | - Add option `wp` 341 | 342 | ### 1.1.9 343 | 344 | - Add command `upgradeFmt` 345 | 346 | ### 1.1.8 347 | 348 | - Option `indent_with_space` supports values 2-8 [(#108)](https://github.com/kokororin/vscode-phpfmt/issues/108) 349 | - Add core passes descriptions 350 | 351 | ### 1.1.7 352 | 353 | - Fix php version bug [(#107)](https://github.com/kokororin/vscode-phpfmt/issues/107) 354 | 355 | ### 1.1.6 356 | 357 | - Fix core passes not allowed 358 | - Add option `use_old_phpfmt` 359 | - Add configuration enums to `passes` and `exclude` 360 | 361 | ### 1.1.5 362 | 363 | - Check passes exists [(#104)](https://github.com/kokororin/vscode-phpfmt/issues/104) 364 | 365 | ### 1.1.4 366 | 367 | - Add command `toggleAdditionalTransformations` 368 | - Add command `toggleExcludedTransformations` 369 | - Add command `togglePSR1Naming` 370 | - Add command `togglePSR1` 371 | - Add command `togglePSR2` 372 | - Add command `toggleAutoAlign` 373 | - Add command `toggleIndentWithSpace` 374 | 375 | ### 1.1.3 376 | 377 | - Just bump version 378 | 379 | ### 1.1.2 380 | 381 | - Update fmt.phar [(#27)](https://github.com/driade/phpfmt8/issues/27) 382 | 383 | ### 1.1.1 384 | 385 | - Update fmt.phar [(PR #101)](https://github.com/kokororin/vscode-phpfmt/pull/101) 386 | 387 | ### 1.0.31 388 | - Update fmt.phar to 19.8.0 389 | - Fix warnings for PHP 7 390 | 391 | ### 1.0.30 392 | - Missing quotes for Windows [(#37)](https://github.com/kokororin/vscode-phpfmt/issues/37) 393 | - Update error messages 394 | 395 | ### 1.0.29 396 | - Update fmt.phar to 19.7.0 397 | - Support `.phpfmt.ini` in workspace 398 | 399 | ### 1.0.28 400 | - Update fmt.phar to 19.6.10 ([#34](https://github.com/kokororin/vscode-phpfmt/issues/34), [#35](https://github.com/kokororin/vscode-phpfmt/issues/35)) 401 | 402 | ### 1.0.27 403 | - Update fmt.phar to 19.6.9 404 | 405 | ### 1.0.26 406 | - Fix path with spaces [(#31)](https://github.com/kokororin/vscode-phpfmt/issues/31) 407 | 408 | ### 1.0.25 409 | - Fix `pjson` not found 410 | 411 | ### 1.0.24 412 | - Add StatusBarItem for output 413 | - Add command `List Transformations` 414 | 415 | ### 1.0.23 416 | - Add warnings for PSR2 417 | 418 | ### 1.0.22 419 | - Fix [(#27)](https://github.com/kokororin/vscode-phpfmt/issues/27) 420 | 421 | ### 1.0.21 422 | - Update fmt.phar to 19.6.7 423 | - Fix tabs issue 424 | 425 | ### 1.0.20 426 | - Visual Studio Live Share support [(PR #25)](https://github.com/kokororin/vscode-phpfmt/pull/25) 427 | 428 | ### 1.0.19 429 | - Support PHP version managers [(PR #24)](https://github.com/kokororin/vscode-phpfmt/pull/24) 430 | 431 | ### 1.0.18 432 | - Update fmt.phar to 19.6.7 433 | 434 | ### 1.0.17 435 | - Use new phpfmt 19.6.6 436 | 437 | ### 1.0.16 438 | - Remove option `format_on_save` 439 | 440 | ### 1.0.15 441 | - Output debug to console instead of Developer Tools 442 | 443 | ### 1.0.14 444 | - Fix config handled unexpectedly 445 | - Add option `debug_mode` 446 | 447 | ### 1.0.13 448 | - Support `Format Selection` 449 | 450 | ### 1.0.12 451 | - Fix `PHP_VERSION_ID` not correct 452 | 453 | ### 1.0.11 454 | - Update PHP Formatter (phpF v19.7.5) 455 | 456 | ### 1.0.10 457 | - Add option `detect_indent` and `exclude` 458 | - `indent_with_space` accept false 459 | 460 | ### 1.0.9 461 | - Add option `cakephp` and `custom_arguments` 462 | 463 | ### 1.0.8 464 | - Option `php_bin` defaults to `php` 465 | 466 | ### 1.0.7 467 | - Typescriptify 468 | 469 | ### 1.0.6 470 | - Compile with babel 471 | 472 | ### 1.0.4 - 1.0.5 473 | - Add option `format_on_save` 474 | 475 | ### 1.0.3 476 | - Reload configuration on changed 477 | 478 | ### 1.0.2 479 | - Add more phpfmt modes 480 | - Check syntax error in php file 481 | - Check php version 482 | 483 | ### 1.0.1 484 | - First version 485 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-phpfmt", 3 | "displayName": "phpfmt - PHP formatter", 4 | "version": "1.2.55", 5 | "description": "Integrates phpfmt into VS Code", 6 | "main": "./dist/extension", 7 | "scripts": { 8 | "build": "nr clean && tsc && tsdown && tsx scripts/copy.mts", 9 | "build:docs": "tsx scripts/docs.mts", 10 | "type:gen": "vscode-ext-gen --output src/meta.ts --scope phpfmt", 11 | "prebuild": "nr type:gen && nr build:docs", 12 | "watch": "tsdown --watch", 13 | "clean": "rimraf out", 14 | "postinstall": "node ./node_modules/phpfmt/v2/install", 15 | "pretest": "nr build", 16 | "test": "node ./out/test/runTest.js", 17 | "format": "prettier --write .", 18 | "lint": "eslint --fix src test scripts", 19 | "prepublishOnly": "nr build && vsce publish --no-dependencies" 20 | }, 21 | "keywords": [ 22 | "phpfmt", 23 | "vscode" 24 | ], 25 | "icon": "icon.png", 26 | "publisher": "kokororin", 27 | "author": "kokororin", 28 | "license": "BSD-3-Clause", 29 | "repository": { 30 | "type": "git", 31 | "url": "git+https://github.com/kokororin/vscode-phpfmt.git" 32 | }, 33 | "bugs": { 34 | "url": "https://github.com/kokororin/vscode-phpfmt/issues" 35 | }, 36 | "homepage": "https://github.com/kokororin/vscode-phpfmt#readme", 37 | "engines": { 38 | "vscode": "^1.96.0" 39 | }, 40 | "categories": [ 41 | "Formatters", 42 | "Linters", 43 | "Other" 44 | ], 45 | "activationEvents": [ 46 | "onLanguage:php" 47 | ], 48 | "contributes": { 49 | "commands": [ 50 | { 51 | "command": "phpfmt.format", 52 | "title": "phpfmt: Format This File", 53 | "when": "!inOutput && editorFocus && editorLangId == php" 54 | }, 55 | { 56 | "command": "phpfmt.listTransformations", 57 | "title": "phpfmt: List Transformations" 58 | }, 59 | { 60 | "command": "phpfmt.toggleAdditionalTransformations", 61 | "title": "phpfmt: Toggle Additional Transformations" 62 | }, 63 | { 64 | "command": "phpfmt.toggleExcludedTransformations", 65 | "title": "phpfmt: Toggle Excluded Transformations" 66 | }, 67 | { 68 | "command": "phpfmt.togglePSR1Naming", 69 | "title": "phpfmt: Toggle PSR1 Naming" 70 | }, 71 | { 72 | "command": "phpfmt.togglePSR1", 73 | "title": "phpfmt: Toggle PSR1" 74 | }, 75 | { 76 | "command": "phpfmt.togglePSR2", 77 | "title": "phpfmt: Toggle PSR2" 78 | }, 79 | { 80 | "command": "phpfmt.toggleAutoAlign", 81 | "title": "phpfmt: Toggle Auto Align" 82 | }, 83 | { 84 | "command": "phpfmt.toggleIndentWithSpace", 85 | "title": "phpfmt: Toggle Indent With Space" 86 | }, 87 | { 88 | "command": "phpfmt.openOutput", 89 | "title": "phpfmt: Open Output" 90 | } 91 | ], 92 | "configuration": { 93 | "title": "phpfmt", 94 | "type": "object", 95 | "properties": { 96 | "phpfmt.php_bin": { 97 | "type": "string", 98 | "default": "php", 99 | "description": "php executable path" 100 | }, 101 | "phpfmt.use_old_phpfmt": { 102 | "type": "boolean", 103 | "default": false, 104 | "description": "use old fmt.phar which supports 5.6" 105 | }, 106 | "phpfmt.detect_indent": { 107 | "type": "boolean", 108 | "default": false, 109 | "description": "auto detecting indent type and size (will ignore indent_with_space)" 110 | }, 111 | "phpfmt.psr1": { 112 | "type": "boolean", 113 | "default": false, 114 | "description": "activate PSR1 style" 115 | }, 116 | "phpfmt.psr1_naming": { 117 | "type": "boolean", 118 | "default": false, 119 | "description": "activate PSR1 style - Section 3 and 4.3 - Class and method names case." 120 | }, 121 | "phpfmt.psr2": { 122 | "type": "boolean", 123 | "default": true, 124 | "description": "activate PSR2 style" 125 | }, 126 | "phpfmt.wp": { 127 | "type": "boolean", 128 | "default": false, 129 | "description": "activate WP style" 130 | }, 131 | "phpfmt.indent_with_space": { 132 | "type": [ 133 | "integer", 134 | "boolean" 135 | ], 136 | "default": 4, 137 | "description": "use spaces instead of tabs for indentation. Default 4", 138 | "enum": [ 139 | false, 140 | 2, 141 | 3, 142 | 4, 143 | 5, 144 | 6, 145 | 7, 146 | 8 147 | ], 148 | "enumDescriptions": [ 149 | "Indent with tabs", 150 | "Indent with 2 spaces", 151 | "Indent with 3 spaces", 152 | "Indent with 4 spaces", 153 | "Indent with 5 spaces", 154 | "Indent with 6 spaces", 155 | "Indent with 7 spaces", 156 | "Indent with 8 spaces" 157 | ] 158 | }, 159 | "phpfmt.enable_auto_align": { 160 | "type": "boolean", 161 | "default": false, 162 | "description": "enable auto align of ST_EQUAL and T_DOUBLE_ARROW" 163 | }, 164 | "phpfmt.visibility_order": { 165 | "type": "boolean", 166 | "default": false, 167 | "description": "fixes visibiliy order for method in classes - PSR-2 4.2" 168 | }, 169 | "phpfmt.ignore": { 170 | "type": "array", 171 | "default": [], 172 | "description": "ignore file names whose names contain any pattern that could be matched with `.match` JS string method", 173 | "items": { 174 | "type": "string" 175 | } 176 | }, 177 | "phpfmt.passes": { 178 | "type": "array", 179 | "default": [ 180 | "AlignDoubleArrow", 181 | "AlignPHPCode", 182 | "SpaceAfterExclamationMark", 183 | "AlignConstVisibilityEquals", 184 | "AutoSemicolon", 185 | "ConvertOpenTagWithEcho", 186 | "AlignEquals", 187 | "MergeNamespaceWithOpenTag", 188 | "RemoveSemicolonAfterCurly", 189 | "RestoreComments", 190 | "ShortArray", 191 | "ExtraCommaInArray", 192 | "AlignDoubleSlashComments", 193 | "IndentTernaryConditions", 194 | "IndentPipeOperator" 195 | ], 196 | "description": "call specific compiler pass", 197 | "items": { 198 | "type": "string", 199 | "enum": [ 200 | "AddMissingCurlyBraces", 201 | "AutoImportPass", 202 | "ConstructorPass", 203 | "EliminateDuplicatedEmptyLines", 204 | "ExtraCommaInArray", 205 | "LeftAlignComment", 206 | "MergeCurlyCloseAndDoWhile", 207 | "MergeDoubleArrowAndArray", 208 | "MergeParenCloseWithCurlyOpen", 209 | "NormalizeIsNotEquals", 210 | "NormalizeLnAndLtrimLines", 211 | "SmartLnAfterCurlyOpen", 212 | "MatchNewLineAndCurlys", 213 | "Reindent", 214 | "ReindentColonBlocks", 215 | "ReindentComments", 216 | "ReindentEqual", 217 | "ReindentObjOps", 218 | "ResizeSpaces", 219 | "RTrim", 220 | "SettersAndGettersPass", 221 | "SplitCurlyCloseAndTokens", 222 | "StripExtraCommaInList", 223 | "TwoCommandsInSameLine", 224 | "PSR1BOMMark", 225 | "PSR1ClassConstants", 226 | "PSR1ClassNames", 227 | "PSR1MethodNames", 228 | "PSR1OpenTags", 229 | "PSR2AlignObjOp", 230 | "PSR2CurlyOpenNextLine", 231 | "PSR2IndentWithSpace", 232 | "PSR2KeywordsLowerCase", 233 | "PSR2LnAfterNamespace", 234 | "PSR2ModifierVisibilityStaticOrder", 235 | "PSR2SingleEmptyLineAndStripClosingTag", 236 | "AddMissingParentheses", 237 | "AliasToMaster", 238 | "AlignConstVisibilityEquals", 239 | "AlignDoubleArrow", 240 | "AlignComments", 241 | "AlignEquals", 242 | "AlignSuperEquals", 243 | "AlignPHPCode", 244 | "AlignTypehint", 245 | "AllmanStyleBraces", 246 | "AutoPreincrement", 247 | "AutoSemicolon", 248 | "CakePHPStyle", 249 | "ClassToSelf", 250 | "ConvertOpenTagWithEcho", 251 | "DocBlockToComment", 252 | "DoubleToSingleQuote", 253 | "EchoToPrint", 254 | "EncapsulateNamespaces", 255 | "GeneratePHPDoc", 256 | "IndentTernaryConditions", 257 | "LeftWordWrap", 258 | "LongArray", 259 | "MergeElseIf", 260 | "SplitElseIf", 261 | "MergeNamespaceWithOpenTag", 262 | "NewLineBeforeReturn", 263 | "NoSpaceAfterPHPDocBlocks", 264 | "OrganizeClass", 265 | "OrderAndRemoveUseClauses", 266 | "PHPDocTypesToFunctionTypehint", 267 | "PrettyPrintDocBlocks", 268 | "PSR2EmptyFunction", 269 | "PSR2MultilineFunctionParams", 270 | "ReindentAndAlignObjOps", 271 | "ReindentSwitchBlocks", 272 | "ReindentEnumBlocks", 273 | "RemoveIncludeParentheses", 274 | "RemoveSemicolonAfterCurly", 275 | "RemoveUseLeadingSlash", 276 | "ReplaceBooleanAndOr", 277 | "ReplaceIsNull", 278 | "RestoreComments", 279 | "ReturnNull", 280 | "ShortArray", 281 | "SortUseNameSpace", 282 | "SpaceAroundControlStructures", 283 | "SpaceAroundExclamationMark", 284 | "SpaceBetweenMethods", 285 | "StrictBehavior", 286 | "StrictComparison", 287 | "StripExtraCommaInArray", 288 | "StripNewlineAfterClassOpen", 289 | "StripNewlineAfterCurlyOpen", 290 | "StripNewlineWithinClassBody", 291 | "StripSpaces", 292 | "StripSpaceWithinControlStructures", 293 | "TightConcat", 294 | "TrimSpaceBeforeSemicolon", 295 | "UpgradeToPreg", 296 | "WordWrap", 297 | "WrongConstructorName", 298 | "YodaComparisons", 299 | "SpaceAfterExclamationMark", 300 | "SpaceAroundParentheses", 301 | "IndentPipeOperator", 302 | "WPResizeSpaces", 303 | "AlignDoubleSlashComments", 304 | "AlignGroupDoubleArrow", 305 | "ClassToStatic", 306 | "JoinToImplode", 307 | "MildAutoPreincrement", 308 | "OnlyOrderUseClauses", 309 | "OrderMethod", 310 | "OrderMethodAndVisibility" 311 | ], 312 | "enumDescriptions": [ 313 | "Core pass", 314 | "Core pass", 315 | "Core pass", 316 | "Core pass", 317 | "Core pass", 318 | "Core pass", 319 | "Core pass", 320 | "Core pass", 321 | "Core pass", 322 | "Core pass", 323 | "Core pass", 324 | "Add line break when implicit curly block is added.", 325 | "Core pass", 326 | "Core pass", 327 | "Core pass", 328 | "Core pass", 329 | "Core pass", 330 | "Core pass", 331 | "Core pass", 332 | "Core pass", 333 | "Core pass", 334 | "Core pass", 335 | "Core pass", 336 | "Core pass", 337 | "Core pass", 338 | "Core pass", 339 | "Core pass", 340 | "Core pass", 341 | "Core pass", 342 | "Core pass", 343 | "Core pass", 344 | "Core pass", 345 | "Core pass", 346 | "Core pass", 347 | "Core pass", 348 | "Core pass", 349 | "Add extra parentheses in new instantiations.", 350 | "Replace function aliases to their masters - only basic syntax alias.", 351 | "Vertically align \"=\" of visibility and const blocks.", 352 | "Vertically align T_DOUBLE_ARROW (=>).", 353 | "Vertically align \"//\" comments.", 354 | "Vertically align \"=\".", 355 | "Vertically align \"=\", \".=\", \"&=\", \">>=\", etc.", 356 | "Align PHP code within HTML block.", 357 | "Vertically align function type hints.", 358 | "Transform all curly braces into Allman-style.", 359 | "Automatically convert postincrement to preincrement.", 360 | "Add semicolons in statements ends.", 361 | "Applies CakePHP Coding Style", 362 | "\"self\" is preferred within class, trait or interface.", 363 | "Convert from \" [])", 394 | "Organize use clauses by length and alphabetic order.", 395 | "Add space around control structures.", 396 | "Add spaces around exclamation mark.", 397 | "Put space between methods.", 398 | "Activate strict option in array_search, base64_decode, in_array, array_keys, mb_detect_encoding. Danger! This pass leads to behavior change.", 399 | "All comparisons are converted to strict. Danger! This pass leads to behavior change.", 400 | "Remove trailing commas within array blocks", 401 | "Strip empty lines after class opening curly brace.", 402 | "Strip empty lines after opening curly brace.", 403 | "Strip empty lines after class opening curly brace.", 404 | "Remove all empty spaces", 405 | "Strip empty lines within control structures.", 406 | "Ensure string concatenation does not have spaces, except when close to numbers.", 407 | "Remove empty lines before semi-colon.", 408 | "Upgrade ereg_* calls to preg_*", 409 | "Word wrap at 80 columns.", 410 | "Update old constructor names into new ones. http://php.net/manual/en/language.oop5.decon.php", 411 | "Execute Yoda Comparisons.", 412 | "Add space after exclamation mark.", 413 | "Add spaces inside parentheses.", 414 | "Applies indentation to the pipe operator.", 415 | "Core pass", 416 | "Vertically align \"//\" comments.", 417 | "Vertically align T_DOUBLE_ARROW (=>) by line groups.", 418 | "\"static\" is preferred within class, trait or interface.", 419 | "Replace implode() alias (join() -> implode()).", 420 | "Automatically convert postincrement to preincrement. (Deprecated pass. Use AutoPreincrement instead).", 421 | "Order use block - do not remove unused imports.", 422 | "Organize class, interface and trait structure.", 423 | "Organize class, interface and trait structure." 424 | ] 425 | } 426 | }, 427 | "phpfmt.exclude": { 428 | "type": "array", 429 | "default": [], 430 | "description": "disable specific passes", 431 | "items": { 432 | "type": "string", 433 | "enum": [ 434 | "AddMissingCurlyBraces", 435 | "AutoImportPass", 436 | "ConstructorPass", 437 | "EliminateDuplicatedEmptyLines", 438 | "ExtraCommaInArray", 439 | "LeftAlignComment", 440 | "MergeCurlyCloseAndDoWhile", 441 | "MergeDoubleArrowAndArray", 442 | "MergeParenCloseWithCurlyOpen", 443 | "NormalizeIsNotEquals", 444 | "NormalizeLnAndLtrimLines", 445 | "SmartLnAfterCurlyOpen", 446 | "MatchNewLineAndCurlys", 447 | "Reindent", 448 | "ReindentColonBlocks", 449 | "ReindentComments", 450 | "ReindentEqual", 451 | "ReindentObjOps", 452 | "ResizeSpaces", 453 | "RTrim", 454 | "SettersAndGettersPass", 455 | "SplitCurlyCloseAndTokens", 456 | "StripExtraCommaInList", 457 | "TwoCommandsInSameLine", 458 | "PSR1BOMMark", 459 | "PSR1ClassConstants", 460 | "PSR1ClassNames", 461 | "PSR1MethodNames", 462 | "PSR1OpenTags", 463 | "PSR2AlignObjOp", 464 | "PSR2CurlyOpenNextLine", 465 | "PSR2IndentWithSpace", 466 | "PSR2KeywordsLowerCase", 467 | "PSR2LnAfterNamespace", 468 | "PSR2ModifierVisibilityStaticOrder", 469 | "PSR2SingleEmptyLineAndStripClosingTag", 470 | "AddMissingParentheses", 471 | "AliasToMaster", 472 | "AlignConstVisibilityEquals", 473 | "AlignDoubleArrow", 474 | "AlignComments", 475 | "AlignEquals", 476 | "AlignSuperEquals", 477 | "AlignPHPCode", 478 | "AlignTypehint", 479 | "AllmanStyleBraces", 480 | "AutoPreincrement", 481 | "AutoSemicolon", 482 | "CakePHPStyle", 483 | "ClassToSelf", 484 | "ConvertOpenTagWithEcho", 485 | "DocBlockToComment", 486 | "DoubleToSingleQuote", 487 | "EchoToPrint", 488 | "EncapsulateNamespaces", 489 | "GeneratePHPDoc", 490 | "IndentTernaryConditions", 491 | "LeftWordWrap", 492 | "LongArray", 493 | "MergeElseIf", 494 | "SplitElseIf", 495 | "MergeNamespaceWithOpenTag", 496 | "NewLineBeforeReturn", 497 | "NoSpaceAfterPHPDocBlocks", 498 | "OrganizeClass", 499 | "OrderAndRemoveUseClauses", 500 | "PHPDocTypesToFunctionTypehint", 501 | "PrettyPrintDocBlocks", 502 | "PSR2EmptyFunction", 503 | "PSR2MultilineFunctionParams", 504 | "ReindentAndAlignObjOps", 505 | "ReindentSwitchBlocks", 506 | "ReindentEnumBlocks", 507 | "RemoveIncludeParentheses", 508 | "RemoveSemicolonAfterCurly", 509 | "RemoveUseLeadingSlash", 510 | "ReplaceBooleanAndOr", 511 | "ReplaceIsNull", 512 | "RestoreComments", 513 | "ReturnNull", 514 | "ShortArray", 515 | "SortUseNameSpace", 516 | "SpaceAroundControlStructures", 517 | "SpaceAroundExclamationMark", 518 | "SpaceBetweenMethods", 519 | "StrictBehavior", 520 | "StrictComparison", 521 | "StripExtraCommaInArray", 522 | "StripNewlineAfterClassOpen", 523 | "StripNewlineAfterCurlyOpen", 524 | "StripNewlineWithinClassBody", 525 | "StripSpaces", 526 | "StripSpaceWithinControlStructures", 527 | "TightConcat", 528 | "TrimSpaceBeforeSemicolon", 529 | "UpgradeToPreg", 530 | "WordWrap", 531 | "WrongConstructorName", 532 | "YodaComparisons", 533 | "SpaceAfterExclamationMark", 534 | "SpaceAroundParentheses", 535 | "IndentPipeOperator", 536 | "WPResizeSpaces", 537 | "AlignDoubleSlashComments", 538 | "AlignGroupDoubleArrow", 539 | "ClassToStatic", 540 | "JoinToImplode", 541 | "MildAutoPreincrement", 542 | "OnlyOrderUseClauses", 543 | "OrderMethod", 544 | "OrderMethodAndVisibility" 545 | ], 546 | "enumDescriptions": [ 547 | "Core pass", 548 | "Core pass", 549 | "Core pass", 550 | "Core pass", 551 | "Core pass", 552 | "Core pass", 553 | "Core pass", 554 | "Core pass", 555 | "Core pass", 556 | "Core pass", 557 | "Core pass", 558 | "Add line break when implicit curly block is added.", 559 | "Core pass", 560 | "Core pass", 561 | "Core pass", 562 | "Core pass", 563 | "Core pass", 564 | "Core pass", 565 | "Core pass", 566 | "Core pass", 567 | "Core pass", 568 | "Core pass", 569 | "Core pass", 570 | "Core pass", 571 | "Core pass", 572 | "Core pass", 573 | "Core pass", 574 | "Core pass", 575 | "Core pass", 576 | "Core pass", 577 | "Core pass", 578 | "Core pass", 579 | "Core pass", 580 | "Core pass", 581 | "Core pass", 582 | "Core pass", 583 | "Add extra parentheses in new instantiations.", 584 | "Replace function aliases to their masters - only basic syntax alias.", 585 | "Vertically align \"=\" of visibility and const blocks.", 586 | "Vertically align T_DOUBLE_ARROW (=>).", 587 | "Vertically align \"//\" comments.", 588 | "Vertically align \"=\".", 589 | "Vertically align \"=\", \".=\", \"&=\", \">>=\", etc.", 590 | "Align PHP code within HTML block.", 591 | "Vertically align function type hints.", 592 | "Transform all curly braces into Allman-style.", 593 | "Automatically convert postincrement to preincrement.", 594 | "Add semicolons in statements ends.", 595 | "Applies CakePHP Coding Style", 596 | "\"self\" is preferred within class, trait or interface.", 597 | "Convert from \" [])", 628 | "Organize use clauses by length and alphabetic order.", 629 | "Add space around control structures.", 630 | "Add spaces around exclamation mark.", 631 | "Put space between methods.", 632 | "Activate strict option in array_search, base64_decode, in_array, array_keys, mb_detect_encoding. Danger! This pass leads to behavior change.", 633 | "All comparisons are converted to strict. Danger! This pass leads to behavior change.", 634 | "Remove trailing commas within array blocks", 635 | "Strip empty lines after class opening curly brace.", 636 | "Strip empty lines after opening curly brace.", 637 | "Strip empty lines after class opening curly brace.", 638 | "Remove all empty spaces", 639 | "Strip empty lines within control structures.", 640 | "Ensure string concatenation does not have spaces, except when close to numbers.", 641 | "Remove empty lines before semi-colon.", 642 | "Upgrade ereg_* calls to preg_*", 643 | "Word wrap at 80 columns.", 644 | "Update old constructor names into new ones. http://php.net/manual/en/language.oop5.decon.php", 645 | "Execute Yoda Comparisons.", 646 | "Add space after exclamation mark.", 647 | "Add spaces inside parentheses.", 648 | "Applies indentation to the pipe operator.", 649 | "Core pass", 650 | "Vertically align \"//\" comments.", 651 | "Vertically align T_DOUBLE_ARROW (=>) by line groups.", 652 | "\"static\" is preferred within class, trait or interface.", 653 | "Replace implode() alias (join() -> implode()).", 654 | "Automatically convert postincrement to preincrement. (Deprecated pass. Use AutoPreincrement instead).", 655 | "Order use block - do not remove unused imports.", 656 | "Organize class, interface and trait structure.", 657 | "Organize class, interface and trait structure." 658 | ] 659 | } 660 | }, 661 | "phpfmt.smart_linebreak_after_curly": { 662 | "type": "boolean", 663 | "default": false, 664 | "description": "convert multistatement blocks into multiline blocks" 665 | }, 666 | "phpfmt.yoda": { 667 | "type": "boolean", 668 | "default": false, 669 | "description": "yoda-style comparisons" 670 | }, 671 | "phpfmt.cakephp": { 672 | "type": "boolean", 673 | "default": false, 674 | "description": "Apply CakePHP coding style" 675 | }, 676 | "phpfmt.custom_arguments": { 677 | "type": "string", 678 | "default": "", 679 | "description": "provide custom arguments to overwrite default arguments generated by config" 680 | } 681 | } 682 | } 683 | }, 684 | "devDependencies": { 685 | "@antfu/eslint-config": "^5.0.0", 686 | "@antfu/ni": "^23.2.0", 687 | "@kokororin/prettierrc": "^0.1.1", 688 | "@octokit/rest": "^21.1.0", 689 | "@types/debug": "^4.1.12", 690 | "@types/got": "^9.6.12", 691 | "@types/md5": "^2.3.5", 692 | "@types/mocha": "^10.0.6", 693 | "@types/node": "^22.0.0", 694 | "@types/semver": "^7.5.8", 695 | "@types/vscode": "^1.96.0", 696 | "@vscode/test-electron": "^2.4.1", 697 | "@vscode/vsce": "^3.2.1", 698 | "consola": "^3.4.0", 699 | "debug": "^4.3.4", 700 | "dirname-filename-esm": "^1.1.2", 701 | "eslint": "^9.20.0", 702 | "eslint-config-prettier": "^10.1.8", 703 | "eslint-plugin-prettier": "^5.5.3", 704 | "execa": "^9.5.2", 705 | "fflate": "^0.8.2", 706 | "got": "^14.4.5", 707 | "is-in-ci": "^1.0.0", 708 | "json5": "^2.2.3", 709 | "markdown-table": "^3.0.4", 710 | "md5": "^2.3.0", 711 | "mocha": "^10.3.0", 712 | "ovsx": "^0.10.1", 713 | "prettier": "^3.4.2", 714 | "read-pkg-up": "^7.0.1", 715 | "rimraf": "^6.0.1", 716 | "semver": "^7.6.0", 717 | "simple-git": "^3.22.0", 718 | "tinyglobby": "^0.2.14", 719 | "tsdown": "^0.13.1", 720 | "tsx": "^4.19.1", 721 | "type-fest": "^4.41.0", 722 | "typescript": "~5.5.0", 723 | "vscode-ext-gen": "^1.0.2" 724 | }, 725 | "dependencies": { 726 | "compare-versions": "^6.1.0", 727 | "detect-indent": "^6.0.0", 728 | "find-up": "^5.0.0", 729 | "mem": "^8.1.1", 730 | "phpfmt": "^0.0.10" 731 | }, 732 | "packageManager": "pnpm@10.15.1" 733 | } 734 | -------------------------------------------------------------------------------- /src/meta.ts: -------------------------------------------------------------------------------- 1 | // This file is generated by `vscode-ext-gen`. Do not modify manually. 2 | // @see https://github.com/antfu/vscode-ext-gen 3 | 4 | // Meta info 5 | export const publisher = "kokororin" 6 | export const name = "vscode-phpfmt" 7 | export const version = "1.2.54" 8 | export const displayName = "phpfmt - PHP formatter" 9 | export const description = "Integrates phpfmt into VS Code" 10 | export const extensionId = `${publisher}.${name}` 11 | 12 | /** 13 | * Type union of all commands 14 | */ 15 | export type CommandKey = 16 | | "phpfmt.format" 17 | | "phpfmt.listTransformations" 18 | | "phpfmt.toggleAdditionalTransformations" 19 | | "phpfmt.toggleExcludedTransformations" 20 | | "phpfmt.togglePSR1Naming" 21 | | "phpfmt.togglePSR1" 22 | | "phpfmt.togglePSR2" 23 | | "phpfmt.toggleAutoAlign" 24 | | "phpfmt.toggleIndentWithSpace" 25 | | "phpfmt.openOutput" 26 | 27 | /** 28 | * Commands map registed by `kokororin.vscode-phpfmt` 29 | */ 30 | export const commands = { 31 | /** 32 | * phpfmt: Format This File 33 | * @value `phpfmt.format` 34 | */ 35 | format: "phpfmt.format", 36 | /** 37 | * phpfmt: List Transformations 38 | * @value `phpfmt.listTransformations` 39 | */ 40 | listTransformations: "phpfmt.listTransformations", 41 | /** 42 | * phpfmt: Toggle Additional Transformations 43 | * @value `phpfmt.toggleAdditionalTransformations` 44 | */ 45 | toggleAdditionalTransformations: "phpfmt.toggleAdditionalTransformations", 46 | /** 47 | * phpfmt: Toggle Excluded Transformations 48 | * @value `phpfmt.toggleExcludedTransformations` 49 | */ 50 | toggleExcludedTransformations: "phpfmt.toggleExcludedTransformations", 51 | /** 52 | * phpfmt: Toggle PSR1 Naming 53 | * @value `phpfmt.togglePSR1Naming` 54 | */ 55 | togglePSR1Naming: "phpfmt.togglePSR1Naming", 56 | /** 57 | * phpfmt: Toggle PSR1 58 | * @value `phpfmt.togglePSR1` 59 | */ 60 | togglePSR1: "phpfmt.togglePSR1", 61 | /** 62 | * phpfmt: Toggle PSR2 63 | * @value `phpfmt.togglePSR2` 64 | */ 65 | togglePSR2: "phpfmt.togglePSR2", 66 | /** 67 | * phpfmt: Toggle Auto Align 68 | * @value `phpfmt.toggleAutoAlign` 69 | */ 70 | toggleAutoAlign: "phpfmt.toggleAutoAlign", 71 | /** 72 | * phpfmt: Toggle Indent With Space 73 | * @value `phpfmt.toggleIndentWithSpace` 74 | */ 75 | toggleIndentWithSpace: "phpfmt.toggleIndentWithSpace", 76 | /** 77 | * phpfmt: Open Output 78 | * @value `phpfmt.openOutput` 79 | */ 80 | openOutput: "phpfmt.openOutput", 81 | } satisfies Record 82 | 83 | /** 84 | * Type union of all configs 85 | */ 86 | export type ConfigKey = 87 | | "phpfmt.php_bin" 88 | | "phpfmt.use_old_phpfmt" 89 | | "phpfmt.detect_indent" 90 | | "phpfmt.psr1" 91 | | "phpfmt.psr1_naming" 92 | | "phpfmt.psr2" 93 | | "phpfmt.wp" 94 | | "phpfmt.indent_with_space" 95 | | "phpfmt.enable_auto_align" 96 | | "phpfmt.visibility_order" 97 | | "phpfmt.ignore" 98 | | "phpfmt.passes" 99 | | "phpfmt.exclude" 100 | | "phpfmt.smart_linebreak_after_curly" 101 | | "phpfmt.yoda" 102 | | "phpfmt.cakephp" 103 | | "phpfmt.custom_arguments" 104 | 105 | export interface ConfigKeyTypeMap { 106 | "phpfmt.php_bin": string, 107 | "phpfmt.use_old_phpfmt": boolean, 108 | "phpfmt.detect_indent": boolean, 109 | "phpfmt.psr1": boolean, 110 | "phpfmt.psr1_naming": boolean, 111 | "phpfmt.psr2": boolean, 112 | "phpfmt.wp": boolean, 113 | "phpfmt.indent_with_space": (unknown | boolean), 114 | "phpfmt.enable_auto_align": boolean, 115 | "phpfmt.visibility_order": boolean, 116 | "phpfmt.ignore": string[], 117 | "phpfmt.passes": ("AddMissingCurlyBraces" | "AutoImportPass" | "ConstructorPass" | "EliminateDuplicatedEmptyLines" | "ExtraCommaInArray" | "LeftAlignComment" | "MergeCurlyCloseAndDoWhile" | "MergeDoubleArrowAndArray" | "MergeParenCloseWithCurlyOpen" | "NormalizeIsNotEquals" | "NormalizeLnAndLtrimLines" | "SmartLnAfterCurlyOpen" | "MatchNewLineAndCurlys" | "Reindent" | "ReindentColonBlocks" | "ReindentComments" | "ReindentEqual" | "ReindentObjOps" | "ResizeSpaces" | "RTrim" | "SettersAndGettersPass" | "SplitCurlyCloseAndTokens" | "StripExtraCommaInList" | "TwoCommandsInSameLine" | "PSR1BOMMark" | "PSR1ClassConstants" | "PSR1ClassNames" | "PSR1MethodNames" | "PSR1OpenTags" | "PSR2AlignObjOp" | "PSR2CurlyOpenNextLine" | "PSR2IndentWithSpace" | "PSR2KeywordsLowerCase" | "PSR2LnAfterNamespace" | "PSR2ModifierVisibilityStaticOrder" | "PSR2SingleEmptyLineAndStripClosingTag" | "AddMissingParentheses" | "AliasToMaster" | "AlignConstVisibilityEquals" | "AlignDoubleArrow" | "AlignComments" | "AlignEquals" | "AlignSuperEquals" | "AlignPHPCode" | "AlignTypehint" | "AllmanStyleBraces" | "AutoPreincrement" | "AutoSemicolon" | "CakePHPStyle" | "ClassToSelf" | "ConvertOpenTagWithEcho" | "DocBlockToComment" | "DoubleToSingleQuote" | "EchoToPrint" | "EncapsulateNamespaces" | "GeneratePHPDoc" | "IndentTernaryConditions" | "LeftWordWrap" | "LongArray" | "MergeElseIf" | "SplitElseIf" | "MergeNamespaceWithOpenTag" | "NewLineBeforeReturn" | "NoSpaceAfterPHPDocBlocks" | "OrganizeClass" | "OrderAndRemoveUseClauses" | "PHPDocTypesToFunctionTypehint" | "PrettyPrintDocBlocks" | "PSR2EmptyFunction" | "PSR2MultilineFunctionParams" | "ReindentAndAlignObjOps" | "ReindentSwitchBlocks" | "ReindentEnumBlocks" | "RemoveIncludeParentheses" | "RemoveSemicolonAfterCurly" | "RemoveUseLeadingSlash" | "ReplaceBooleanAndOr" | "ReplaceIsNull" | "RestoreComments" | "ReturnNull" | "ShortArray" | "SortUseNameSpace" | "SpaceAroundControlStructures" | "SpaceAroundExclamationMark" | "SpaceBetweenMethods" | "StrictBehavior" | "StrictComparison" | "StripExtraCommaInArray" | "StripNewlineAfterClassOpen" | "StripNewlineAfterCurlyOpen" | "StripNewlineWithinClassBody" | "StripSpaces" | "StripSpaceWithinControlStructures" | "TightConcat" | "TrimSpaceBeforeSemicolon" | "UpgradeToPreg" | "WordWrap" | "WrongConstructorName" | "YodaComparisons" | "SpaceAfterExclamationMark" | "SpaceAroundParentheses" | "IndentPipeOperator" | "WPResizeSpaces" | "AlignDoubleSlashComments" | "AlignGroupDoubleArrow" | "ClassToStatic" | "JoinToImplode" | "MildAutoPreincrement" | "OnlyOrderUseClauses" | "OrderMethod" | "OrderMethodAndVisibility")[], 118 | "phpfmt.exclude": ("AddMissingCurlyBraces" | "AutoImportPass" | "ConstructorPass" | "EliminateDuplicatedEmptyLines" | "ExtraCommaInArray" | "LeftAlignComment" | "MergeCurlyCloseAndDoWhile" | "MergeDoubleArrowAndArray" | "MergeParenCloseWithCurlyOpen" | "NormalizeIsNotEquals" | "NormalizeLnAndLtrimLines" | "SmartLnAfterCurlyOpen" | "MatchNewLineAndCurlys" | "Reindent" | "ReindentColonBlocks" | "ReindentComments" | "ReindentEqual" | "ReindentObjOps" | "ResizeSpaces" | "RTrim" | "SettersAndGettersPass" | "SplitCurlyCloseAndTokens" | "StripExtraCommaInList" | "TwoCommandsInSameLine" | "PSR1BOMMark" | "PSR1ClassConstants" | "PSR1ClassNames" | "PSR1MethodNames" | "PSR1OpenTags" | "PSR2AlignObjOp" | "PSR2CurlyOpenNextLine" | "PSR2IndentWithSpace" | "PSR2KeywordsLowerCase" | "PSR2LnAfterNamespace" | "PSR2ModifierVisibilityStaticOrder" | "PSR2SingleEmptyLineAndStripClosingTag" | "AddMissingParentheses" | "AliasToMaster" | "AlignConstVisibilityEquals" | "AlignDoubleArrow" | "AlignComments" | "AlignEquals" | "AlignSuperEquals" | "AlignPHPCode" | "AlignTypehint" | "AllmanStyleBraces" | "AutoPreincrement" | "AutoSemicolon" | "CakePHPStyle" | "ClassToSelf" | "ConvertOpenTagWithEcho" | "DocBlockToComment" | "DoubleToSingleQuote" | "EchoToPrint" | "EncapsulateNamespaces" | "GeneratePHPDoc" | "IndentTernaryConditions" | "LeftWordWrap" | "LongArray" | "MergeElseIf" | "SplitElseIf" | "MergeNamespaceWithOpenTag" | "NewLineBeforeReturn" | "NoSpaceAfterPHPDocBlocks" | "OrganizeClass" | "OrderAndRemoveUseClauses" | "PHPDocTypesToFunctionTypehint" | "PrettyPrintDocBlocks" | "PSR2EmptyFunction" | "PSR2MultilineFunctionParams" | "ReindentAndAlignObjOps" | "ReindentSwitchBlocks" | "ReindentEnumBlocks" | "RemoveIncludeParentheses" | "RemoveSemicolonAfterCurly" | "RemoveUseLeadingSlash" | "ReplaceBooleanAndOr" | "ReplaceIsNull" | "RestoreComments" | "ReturnNull" | "ShortArray" | "SortUseNameSpace" | "SpaceAroundControlStructures" | "SpaceAroundExclamationMark" | "SpaceBetweenMethods" | "StrictBehavior" | "StrictComparison" | "StripExtraCommaInArray" | "StripNewlineAfterClassOpen" | "StripNewlineAfterCurlyOpen" | "StripNewlineWithinClassBody" | "StripSpaces" | "StripSpaceWithinControlStructures" | "TightConcat" | "TrimSpaceBeforeSemicolon" | "UpgradeToPreg" | "WordWrap" | "WrongConstructorName" | "YodaComparisons" | "SpaceAfterExclamationMark" | "SpaceAroundParentheses" | "IndentPipeOperator" | "WPResizeSpaces" | "AlignDoubleSlashComments" | "AlignGroupDoubleArrow" | "ClassToStatic" | "JoinToImplode" | "MildAutoPreincrement" | "OnlyOrderUseClauses" | "OrderMethod" | "OrderMethodAndVisibility")[], 119 | "phpfmt.smart_linebreak_after_curly": boolean, 120 | "phpfmt.yoda": boolean, 121 | "phpfmt.cakephp": boolean, 122 | "phpfmt.custom_arguments": string, 123 | } 124 | 125 | export interface ConfigShorthandMap { 126 | phpBin: "phpfmt.php_bin", 127 | useOldPhpfmt: "phpfmt.use_old_phpfmt", 128 | detectIndent: "phpfmt.detect_indent", 129 | psr1: "phpfmt.psr1", 130 | psr1Naming: "phpfmt.psr1_naming", 131 | psr2: "phpfmt.psr2", 132 | wp: "phpfmt.wp", 133 | indentWithSpace: "phpfmt.indent_with_space", 134 | enableAutoAlign: "phpfmt.enable_auto_align", 135 | visibilityOrder: "phpfmt.visibility_order", 136 | ignore: "phpfmt.ignore", 137 | passes: "phpfmt.passes", 138 | exclude: "phpfmt.exclude", 139 | smartLinebreakAfterCurly: "phpfmt.smart_linebreak_after_curly", 140 | yoda: "phpfmt.yoda", 141 | cakephp: "phpfmt.cakephp", 142 | customArguments: "phpfmt.custom_arguments", 143 | } 144 | 145 | export interface ConfigShorthandTypeMap { 146 | phpBin: string, 147 | useOldPhpfmt: boolean, 148 | detectIndent: boolean, 149 | psr1: boolean, 150 | psr1Naming: boolean, 151 | psr2: boolean, 152 | wp: boolean, 153 | indentWithSpace: (unknown | boolean), 154 | enableAutoAlign: boolean, 155 | visibilityOrder: boolean, 156 | ignore: string[], 157 | passes: ("AddMissingCurlyBraces" | "AutoImportPass" | "ConstructorPass" | "EliminateDuplicatedEmptyLines" | "ExtraCommaInArray" | "LeftAlignComment" | "MergeCurlyCloseAndDoWhile" | "MergeDoubleArrowAndArray" | "MergeParenCloseWithCurlyOpen" | "NormalizeIsNotEquals" | "NormalizeLnAndLtrimLines" | "SmartLnAfterCurlyOpen" | "MatchNewLineAndCurlys" | "Reindent" | "ReindentColonBlocks" | "ReindentComments" | "ReindentEqual" | "ReindentObjOps" | "ResizeSpaces" | "RTrim" | "SettersAndGettersPass" | "SplitCurlyCloseAndTokens" | "StripExtraCommaInList" | "TwoCommandsInSameLine" | "PSR1BOMMark" | "PSR1ClassConstants" | "PSR1ClassNames" | "PSR1MethodNames" | "PSR1OpenTags" | "PSR2AlignObjOp" | "PSR2CurlyOpenNextLine" | "PSR2IndentWithSpace" | "PSR2KeywordsLowerCase" | "PSR2LnAfterNamespace" | "PSR2ModifierVisibilityStaticOrder" | "PSR2SingleEmptyLineAndStripClosingTag" | "AddMissingParentheses" | "AliasToMaster" | "AlignConstVisibilityEquals" | "AlignDoubleArrow" | "AlignComments" | "AlignEquals" | "AlignSuperEquals" | "AlignPHPCode" | "AlignTypehint" | "AllmanStyleBraces" | "AutoPreincrement" | "AutoSemicolon" | "CakePHPStyle" | "ClassToSelf" | "ConvertOpenTagWithEcho" | "DocBlockToComment" | "DoubleToSingleQuote" | "EchoToPrint" | "EncapsulateNamespaces" | "GeneratePHPDoc" | "IndentTernaryConditions" | "LeftWordWrap" | "LongArray" | "MergeElseIf" | "SplitElseIf" | "MergeNamespaceWithOpenTag" | "NewLineBeforeReturn" | "NoSpaceAfterPHPDocBlocks" | "OrganizeClass" | "OrderAndRemoveUseClauses" | "PHPDocTypesToFunctionTypehint" | "PrettyPrintDocBlocks" | "PSR2EmptyFunction" | "PSR2MultilineFunctionParams" | "ReindentAndAlignObjOps" | "ReindentSwitchBlocks" | "ReindentEnumBlocks" | "RemoveIncludeParentheses" | "RemoveSemicolonAfterCurly" | "RemoveUseLeadingSlash" | "ReplaceBooleanAndOr" | "ReplaceIsNull" | "RestoreComments" | "ReturnNull" | "ShortArray" | "SortUseNameSpace" | "SpaceAroundControlStructures" | "SpaceAroundExclamationMark" | "SpaceBetweenMethods" | "StrictBehavior" | "StrictComparison" | "StripExtraCommaInArray" | "StripNewlineAfterClassOpen" | "StripNewlineAfterCurlyOpen" | "StripNewlineWithinClassBody" | "StripSpaces" | "StripSpaceWithinControlStructures" | "TightConcat" | "TrimSpaceBeforeSemicolon" | "UpgradeToPreg" | "WordWrap" | "WrongConstructorName" | "YodaComparisons" | "SpaceAfterExclamationMark" | "SpaceAroundParentheses" | "IndentPipeOperator" | "WPResizeSpaces" | "AlignDoubleSlashComments" | "AlignGroupDoubleArrow" | "ClassToStatic" | "JoinToImplode" | "MildAutoPreincrement" | "OnlyOrderUseClauses" | "OrderMethod" | "OrderMethodAndVisibility")[], 158 | exclude: ("AddMissingCurlyBraces" | "AutoImportPass" | "ConstructorPass" | "EliminateDuplicatedEmptyLines" | "ExtraCommaInArray" | "LeftAlignComment" | "MergeCurlyCloseAndDoWhile" | "MergeDoubleArrowAndArray" | "MergeParenCloseWithCurlyOpen" | "NormalizeIsNotEquals" | "NormalizeLnAndLtrimLines" | "SmartLnAfterCurlyOpen" | "MatchNewLineAndCurlys" | "Reindent" | "ReindentColonBlocks" | "ReindentComments" | "ReindentEqual" | "ReindentObjOps" | "ResizeSpaces" | "RTrim" | "SettersAndGettersPass" | "SplitCurlyCloseAndTokens" | "StripExtraCommaInList" | "TwoCommandsInSameLine" | "PSR1BOMMark" | "PSR1ClassConstants" | "PSR1ClassNames" | "PSR1MethodNames" | "PSR1OpenTags" | "PSR2AlignObjOp" | "PSR2CurlyOpenNextLine" | "PSR2IndentWithSpace" | "PSR2KeywordsLowerCase" | "PSR2LnAfterNamespace" | "PSR2ModifierVisibilityStaticOrder" | "PSR2SingleEmptyLineAndStripClosingTag" | "AddMissingParentheses" | "AliasToMaster" | "AlignConstVisibilityEquals" | "AlignDoubleArrow" | "AlignComments" | "AlignEquals" | "AlignSuperEquals" | "AlignPHPCode" | "AlignTypehint" | "AllmanStyleBraces" | "AutoPreincrement" | "AutoSemicolon" | "CakePHPStyle" | "ClassToSelf" | "ConvertOpenTagWithEcho" | "DocBlockToComment" | "DoubleToSingleQuote" | "EchoToPrint" | "EncapsulateNamespaces" | "GeneratePHPDoc" | "IndentTernaryConditions" | "LeftWordWrap" | "LongArray" | "MergeElseIf" | "SplitElseIf" | "MergeNamespaceWithOpenTag" | "NewLineBeforeReturn" | "NoSpaceAfterPHPDocBlocks" | "OrganizeClass" | "OrderAndRemoveUseClauses" | "PHPDocTypesToFunctionTypehint" | "PrettyPrintDocBlocks" | "PSR2EmptyFunction" | "PSR2MultilineFunctionParams" | "ReindentAndAlignObjOps" | "ReindentSwitchBlocks" | "ReindentEnumBlocks" | "RemoveIncludeParentheses" | "RemoveSemicolonAfterCurly" | "RemoveUseLeadingSlash" | "ReplaceBooleanAndOr" | "ReplaceIsNull" | "RestoreComments" | "ReturnNull" | "ShortArray" | "SortUseNameSpace" | "SpaceAroundControlStructures" | "SpaceAroundExclamationMark" | "SpaceBetweenMethods" | "StrictBehavior" | "StrictComparison" | "StripExtraCommaInArray" | "StripNewlineAfterClassOpen" | "StripNewlineAfterCurlyOpen" | "StripNewlineWithinClassBody" | "StripSpaces" | "StripSpaceWithinControlStructures" | "TightConcat" | "TrimSpaceBeforeSemicolon" | "UpgradeToPreg" | "WordWrap" | "WrongConstructorName" | "YodaComparisons" | "SpaceAfterExclamationMark" | "SpaceAroundParentheses" | "IndentPipeOperator" | "WPResizeSpaces" | "AlignDoubleSlashComments" | "AlignGroupDoubleArrow" | "ClassToStatic" | "JoinToImplode" | "MildAutoPreincrement" | "OnlyOrderUseClauses" | "OrderMethod" | "OrderMethodAndVisibility")[], 159 | smartLinebreakAfterCurly: boolean, 160 | yoda: boolean, 161 | cakephp: boolean, 162 | customArguments: string, 163 | } 164 | 165 | export interface ConfigItem { 166 | key: T, 167 | default: ConfigKeyTypeMap[T], 168 | } 169 | 170 | 171 | /** 172 | * Configs map registered by `kokororin.vscode-phpfmt` 173 | */ 174 | export const configs = { 175 | /** 176 | * php executable path 177 | * @key `phpfmt.php_bin` 178 | * @default `"php"` 179 | * @type `string` 180 | */ 181 | phpBin: { 182 | key: "phpfmt.php_bin", 183 | default: "php", 184 | } as ConfigItem<"phpfmt.php_bin">, 185 | /** 186 | * use old fmt.phar which supports 5.6 187 | * @key `phpfmt.use_old_phpfmt` 188 | * @default `false` 189 | * @type `boolean` 190 | */ 191 | useOldPhpfmt: { 192 | key: "phpfmt.use_old_phpfmt", 193 | default: false, 194 | } as ConfigItem<"phpfmt.use_old_phpfmt">, 195 | /** 196 | * auto detecting indent type and size (will ignore indent_with_space) 197 | * @key `phpfmt.detect_indent` 198 | * @default `false` 199 | * @type `boolean` 200 | */ 201 | detectIndent: { 202 | key: "phpfmt.detect_indent", 203 | default: false, 204 | } as ConfigItem<"phpfmt.detect_indent">, 205 | /** 206 | * activate PSR1 style 207 | * @key `phpfmt.psr1` 208 | * @default `false` 209 | * @type `boolean` 210 | */ 211 | psr1: { 212 | key: "phpfmt.psr1", 213 | default: false, 214 | } as ConfigItem<"phpfmt.psr1">, 215 | /** 216 | * activate PSR1 style - Section 3 and 4.3 - Class and method names case. 217 | * @key `phpfmt.psr1_naming` 218 | * @default `false` 219 | * @type `boolean` 220 | */ 221 | psr1Naming: { 222 | key: "phpfmt.psr1_naming", 223 | default: false, 224 | } as ConfigItem<"phpfmt.psr1_naming">, 225 | /** 226 | * activate PSR2 style 227 | * @key `phpfmt.psr2` 228 | * @default `true` 229 | * @type `boolean` 230 | */ 231 | psr2: { 232 | key: "phpfmt.psr2", 233 | default: true, 234 | } as ConfigItem<"phpfmt.psr2">, 235 | /** 236 | * activate WP style 237 | * @key `phpfmt.wp` 238 | * @default `false` 239 | * @type `boolean` 240 | */ 241 | wp: { 242 | key: "phpfmt.wp", 243 | default: false, 244 | } as ConfigItem<"phpfmt.wp">, 245 | /** 246 | * use spaces instead of tabs for indentation. Default 4 247 | * @key `phpfmt.indent_with_space` 248 | * @default `4` 249 | * @type `integer,boolean` 250 | */ 251 | indentWithSpace: { 252 | key: "phpfmt.indent_with_space", 253 | default: 4, 254 | } as ConfigItem<"phpfmt.indent_with_space">, 255 | /** 256 | * enable auto align of ST_EQUAL and T_DOUBLE_ARROW 257 | * @key `phpfmt.enable_auto_align` 258 | * @default `false` 259 | * @type `boolean` 260 | */ 261 | enableAutoAlign: { 262 | key: "phpfmt.enable_auto_align", 263 | default: false, 264 | } as ConfigItem<"phpfmt.enable_auto_align">, 265 | /** 266 | * fixes visibiliy order for method in classes - PSR-2 4.2 267 | * @key `phpfmt.visibility_order` 268 | * @default `false` 269 | * @type `boolean` 270 | */ 271 | visibilityOrder: { 272 | key: "phpfmt.visibility_order", 273 | default: false, 274 | } as ConfigItem<"phpfmt.visibility_order">, 275 | /** 276 | * ignore file names whose names contain any pattern that could be matched with `.match` JS string method 277 | * @key `phpfmt.ignore` 278 | * @default `[]` 279 | * @type `array` 280 | */ 281 | ignore: { 282 | key: "phpfmt.ignore", 283 | default: [], 284 | } as ConfigItem<"phpfmt.ignore">, 285 | /** 286 | * call specific compiler pass 287 | * @key `phpfmt.passes` 288 | * @default `["AlignDoubleArrow","AlignPHPCode","SpaceAfterExclamationMark","AlignConstVisibilityEquals","AutoSemicolon","ConvertOpenTagWithEcho","AlignEquals","MergeNamespaceWithOpenTag","RemoveSemicolonAfterCurly","RestoreComments","ShortArray","ExtraCommaInArray","AlignDoubleSlashComments","IndentTernaryConditions","IndentPipeOperator"]` 289 | * @type `array` 290 | */ 291 | passes: { 292 | key: "phpfmt.passes", 293 | default: ["AlignDoubleArrow","AlignPHPCode","SpaceAfterExclamationMark","AlignConstVisibilityEquals","AutoSemicolon","ConvertOpenTagWithEcho","AlignEquals","MergeNamespaceWithOpenTag","RemoveSemicolonAfterCurly","RestoreComments","ShortArray","ExtraCommaInArray","AlignDoubleSlashComments","IndentTernaryConditions","IndentPipeOperator"], 294 | } as ConfigItem<"phpfmt.passes">, 295 | /** 296 | * disable specific passes 297 | * @key `phpfmt.exclude` 298 | * @default `[]` 299 | * @type `array` 300 | */ 301 | exclude: { 302 | key: "phpfmt.exclude", 303 | default: [], 304 | } as ConfigItem<"phpfmt.exclude">, 305 | /** 306 | * convert multistatement blocks into multiline blocks 307 | * @key `phpfmt.smart_linebreak_after_curly` 308 | * @default `false` 309 | * @type `boolean` 310 | */ 311 | smartLinebreakAfterCurly: { 312 | key: "phpfmt.smart_linebreak_after_curly", 313 | default: false, 314 | } as ConfigItem<"phpfmt.smart_linebreak_after_curly">, 315 | /** 316 | * yoda-style comparisons 317 | * @key `phpfmt.yoda` 318 | * @default `false` 319 | * @type `boolean` 320 | */ 321 | yoda: { 322 | key: "phpfmt.yoda", 323 | default: false, 324 | } as ConfigItem<"phpfmt.yoda">, 325 | /** 326 | * Apply CakePHP coding style 327 | * @key `phpfmt.cakephp` 328 | * @default `false` 329 | * @type `boolean` 330 | */ 331 | cakephp: { 332 | key: "phpfmt.cakephp", 333 | default: false, 334 | } as ConfigItem<"phpfmt.cakephp">, 335 | /** 336 | * provide custom arguments to overwrite default arguments generated by config 337 | * @key `phpfmt.custom_arguments` 338 | * @default `""` 339 | * @type `string` 340 | */ 341 | customArguments: { 342 | key: "phpfmt.custom_arguments", 343 | default: "", 344 | } as ConfigItem<"phpfmt.custom_arguments">, 345 | } 346 | 347 | export interface ScopedConfigKeyTypeMap { 348 | "php_bin": string, 349 | "use_old_phpfmt": boolean, 350 | "detect_indent": boolean, 351 | "psr1": boolean, 352 | "psr1_naming": boolean, 353 | "psr2": boolean, 354 | "wp": boolean, 355 | "indent_with_space": (unknown | boolean), 356 | "enable_auto_align": boolean, 357 | "visibility_order": boolean, 358 | "ignore": string[], 359 | "passes": ("AddMissingCurlyBraces" | "AutoImportPass" | "ConstructorPass" | "EliminateDuplicatedEmptyLines" | "ExtraCommaInArray" | "LeftAlignComment" | "MergeCurlyCloseAndDoWhile" | "MergeDoubleArrowAndArray" | "MergeParenCloseWithCurlyOpen" | "NormalizeIsNotEquals" | "NormalizeLnAndLtrimLines" | "SmartLnAfterCurlyOpen" | "MatchNewLineAndCurlys" | "Reindent" | "ReindentColonBlocks" | "ReindentComments" | "ReindentEqual" | "ReindentObjOps" | "ResizeSpaces" | "RTrim" | "SettersAndGettersPass" | "SplitCurlyCloseAndTokens" | "StripExtraCommaInList" | "TwoCommandsInSameLine" | "PSR1BOMMark" | "PSR1ClassConstants" | "PSR1ClassNames" | "PSR1MethodNames" | "PSR1OpenTags" | "PSR2AlignObjOp" | "PSR2CurlyOpenNextLine" | "PSR2IndentWithSpace" | "PSR2KeywordsLowerCase" | "PSR2LnAfterNamespace" | "PSR2ModifierVisibilityStaticOrder" | "PSR2SingleEmptyLineAndStripClosingTag" | "AddMissingParentheses" | "AliasToMaster" | "AlignConstVisibilityEquals" | "AlignDoubleArrow" | "AlignComments" | "AlignEquals" | "AlignSuperEquals" | "AlignPHPCode" | "AlignTypehint" | "AllmanStyleBraces" | "AutoPreincrement" | "AutoSemicolon" | "CakePHPStyle" | "ClassToSelf" | "ConvertOpenTagWithEcho" | "DocBlockToComment" | "DoubleToSingleQuote" | "EchoToPrint" | "EncapsulateNamespaces" | "GeneratePHPDoc" | "IndentTernaryConditions" | "LeftWordWrap" | "LongArray" | "MergeElseIf" | "SplitElseIf" | "MergeNamespaceWithOpenTag" | "NewLineBeforeReturn" | "NoSpaceAfterPHPDocBlocks" | "OrganizeClass" | "OrderAndRemoveUseClauses" | "PHPDocTypesToFunctionTypehint" | "PrettyPrintDocBlocks" | "PSR2EmptyFunction" | "PSR2MultilineFunctionParams" | "ReindentAndAlignObjOps" | "ReindentSwitchBlocks" | "ReindentEnumBlocks" | "RemoveIncludeParentheses" | "RemoveSemicolonAfterCurly" | "RemoveUseLeadingSlash" | "ReplaceBooleanAndOr" | "ReplaceIsNull" | "RestoreComments" | "ReturnNull" | "ShortArray" | "SortUseNameSpace" | "SpaceAroundControlStructures" | "SpaceAroundExclamationMark" | "SpaceBetweenMethods" | "StrictBehavior" | "StrictComparison" | "StripExtraCommaInArray" | "StripNewlineAfterClassOpen" | "StripNewlineAfterCurlyOpen" | "StripNewlineWithinClassBody" | "StripSpaces" | "StripSpaceWithinControlStructures" | "TightConcat" | "TrimSpaceBeforeSemicolon" | "UpgradeToPreg" | "WordWrap" | "WrongConstructorName" | "YodaComparisons" | "SpaceAfterExclamationMark" | "SpaceAroundParentheses" | "IndentPipeOperator" | "WPResizeSpaces" | "AlignDoubleSlashComments" | "AlignGroupDoubleArrow" | "ClassToStatic" | "JoinToImplode" | "MildAutoPreincrement" | "OnlyOrderUseClauses" | "OrderMethod" | "OrderMethodAndVisibility")[], 360 | "exclude": ("AddMissingCurlyBraces" | "AutoImportPass" | "ConstructorPass" | "EliminateDuplicatedEmptyLines" | "ExtraCommaInArray" | "LeftAlignComment" | "MergeCurlyCloseAndDoWhile" | "MergeDoubleArrowAndArray" | "MergeParenCloseWithCurlyOpen" | "NormalizeIsNotEquals" | "NormalizeLnAndLtrimLines" | "SmartLnAfterCurlyOpen" | "MatchNewLineAndCurlys" | "Reindent" | "ReindentColonBlocks" | "ReindentComments" | "ReindentEqual" | "ReindentObjOps" | "ResizeSpaces" | "RTrim" | "SettersAndGettersPass" | "SplitCurlyCloseAndTokens" | "StripExtraCommaInList" | "TwoCommandsInSameLine" | "PSR1BOMMark" | "PSR1ClassConstants" | "PSR1ClassNames" | "PSR1MethodNames" | "PSR1OpenTags" | "PSR2AlignObjOp" | "PSR2CurlyOpenNextLine" | "PSR2IndentWithSpace" | "PSR2KeywordsLowerCase" | "PSR2LnAfterNamespace" | "PSR2ModifierVisibilityStaticOrder" | "PSR2SingleEmptyLineAndStripClosingTag" | "AddMissingParentheses" | "AliasToMaster" | "AlignConstVisibilityEquals" | "AlignDoubleArrow" | "AlignComments" | "AlignEquals" | "AlignSuperEquals" | "AlignPHPCode" | "AlignTypehint" | "AllmanStyleBraces" | "AutoPreincrement" | "AutoSemicolon" | "CakePHPStyle" | "ClassToSelf" | "ConvertOpenTagWithEcho" | "DocBlockToComment" | "DoubleToSingleQuote" | "EchoToPrint" | "EncapsulateNamespaces" | "GeneratePHPDoc" | "IndentTernaryConditions" | "LeftWordWrap" | "LongArray" | "MergeElseIf" | "SplitElseIf" | "MergeNamespaceWithOpenTag" | "NewLineBeforeReturn" | "NoSpaceAfterPHPDocBlocks" | "OrganizeClass" | "OrderAndRemoveUseClauses" | "PHPDocTypesToFunctionTypehint" | "PrettyPrintDocBlocks" | "PSR2EmptyFunction" | "PSR2MultilineFunctionParams" | "ReindentAndAlignObjOps" | "ReindentSwitchBlocks" | "ReindentEnumBlocks" | "RemoveIncludeParentheses" | "RemoveSemicolonAfterCurly" | "RemoveUseLeadingSlash" | "ReplaceBooleanAndOr" | "ReplaceIsNull" | "RestoreComments" | "ReturnNull" | "ShortArray" | "SortUseNameSpace" | "SpaceAroundControlStructures" | "SpaceAroundExclamationMark" | "SpaceBetweenMethods" | "StrictBehavior" | "StrictComparison" | "StripExtraCommaInArray" | "StripNewlineAfterClassOpen" | "StripNewlineAfterCurlyOpen" | "StripNewlineWithinClassBody" | "StripSpaces" | "StripSpaceWithinControlStructures" | "TightConcat" | "TrimSpaceBeforeSemicolon" | "UpgradeToPreg" | "WordWrap" | "WrongConstructorName" | "YodaComparisons" | "SpaceAfterExclamationMark" | "SpaceAroundParentheses" | "IndentPipeOperator" | "WPResizeSpaces" | "AlignDoubleSlashComments" | "AlignGroupDoubleArrow" | "ClassToStatic" | "JoinToImplode" | "MildAutoPreincrement" | "OnlyOrderUseClauses" | "OrderMethod" | "OrderMethodAndVisibility")[], 361 | "smart_linebreak_after_curly": boolean, 362 | "yoda": boolean, 363 | "cakephp": boolean, 364 | "custom_arguments": string, 365 | } 366 | 367 | export const scopedConfigs = { 368 | scope: "phpfmt", 369 | defaults: { 370 | "php_bin": "php", 371 | "use_old_phpfmt": false, 372 | "detect_indent": false, 373 | "psr1": false, 374 | "psr1_naming": false, 375 | "psr2": true, 376 | "wp": false, 377 | "indent_with_space": 4, 378 | "enable_auto_align": false, 379 | "visibility_order": false, 380 | "ignore": [], 381 | "passes": ["AlignDoubleArrow","AlignPHPCode","SpaceAfterExclamationMark","AlignConstVisibilityEquals","AutoSemicolon","ConvertOpenTagWithEcho","AlignEquals","MergeNamespaceWithOpenTag","RemoveSemicolonAfterCurly","RestoreComments","ShortArray","ExtraCommaInArray","AlignDoubleSlashComments","IndentTernaryConditions","IndentPipeOperator"], 382 | "exclude": [], 383 | "smart_linebreak_after_curly": false, 384 | "yoda": false, 385 | "cakephp": false, 386 | "custom_arguments": "", 387 | } satisfies ScopedConfigKeyTypeMap, 388 | } 389 | 390 | export interface NestedConfigs { 391 | "phpfmt": { 392 | "php_bin": string, 393 | "use_old_phpfmt": boolean, 394 | "detect_indent": boolean, 395 | "psr1": boolean, 396 | "psr1_naming": boolean, 397 | "psr2": boolean, 398 | "wp": boolean, 399 | "indent_with_space": (unknown | boolean), 400 | "enable_auto_align": boolean, 401 | "visibility_order": boolean, 402 | "ignore": string[], 403 | "passes": ("AddMissingCurlyBraces" | "AutoImportPass" | "ConstructorPass" | "EliminateDuplicatedEmptyLines" | "ExtraCommaInArray" | "LeftAlignComment" | "MergeCurlyCloseAndDoWhile" | "MergeDoubleArrowAndArray" | "MergeParenCloseWithCurlyOpen" | "NormalizeIsNotEquals" | "NormalizeLnAndLtrimLines" | "SmartLnAfterCurlyOpen" | "MatchNewLineAndCurlys" | "Reindent" | "ReindentColonBlocks" | "ReindentComments" | "ReindentEqual" | "ReindentObjOps" | "ResizeSpaces" | "RTrim" | "SettersAndGettersPass" | "SplitCurlyCloseAndTokens" | "StripExtraCommaInList" | "TwoCommandsInSameLine" | "PSR1BOMMark" | "PSR1ClassConstants" | "PSR1ClassNames" | "PSR1MethodNames" | "PSR1OpenTags" | "PSR2AlignObjOp" | "PSR2CurlyOpenNextLine" | "PSR2IndentWithSpace" | "PSR2KeywordsLowerCase" | "PSR2LnAfterNamespace" | "PSR2ModifierVisibilityStaticOrder" | "PSR2SingleEmptyLineAndStripClosingTag" | "AddMissingParentheses" | "AliasToMaster" | "AlignConstVisibilityEquals" | "AlignDoubleArrow" | "AlignComments" | "AlignEquals" | "AlignSuperEquals" | "AlignPHPCode" | "AlignTypehint" | "AllmanStyleBraces" | "AutoPreincrement" | "AutoSemicolon" | "CakePHPStyle" | "ClassToSelf" | "ConvertOpenTagWithEcho" | "DocBlockToComment" | "DoubleToSingleQuote" | "EchoToPrint" | "EncapsulateNamespaces" | "GeneratePHPDoc" | "IndentTernaryConditions" | "LeftWordWrap" | "LongArray" | "MergeElseIf" | "SplitElseIf" | "MergeNamespaceWithOpenTag" | "NewLineBeforeReturn" | "NoSpaceAfterPHPDocBlocks" | "OrganizeClass" | "OrderAndRemoveUseClauses" | "PHPDocTypesToFunctionTypehint" | "PrettyPrintDocBlocks" | "PSR2EmptyFunction" | "PSR2MultilineFunctionParams" | "ReindentAndAlignObjOps" | "ReindentSwitchBlocks" | "ReindentEnumBlocks" | "RemoveIncludeParentheses" | "RemoveSemicolonAfterCurly" | "RemoveUseLeadingSlash" | "ReplaceBooleanAndOr" | "ReplaceIsNull" | "RestoreComments" | "ReturnNull" | "ShortArray" | "SortUseNameSpace" | "SpaceAroundControlStructures" | "SpaceAroundExclamationMark" | "SpaceBetweenMethods" | "StrictBehavior" | "StrictComparison" | "StripExtraCommaInArray" | "StripNewlineAfterClassOpen" | "StripNewlineAfterCurlyOpen" | "StripNewlineWithinClassBody" | "StripSpaces" | "StripSpaceWithinControlStructures" | "TightConcat" | "TrimSpaceBeforeSemicolon" | "UpgradeToPreg" | "WordWrap" | "WrongConstructorName" | "YodaComparisons" | "SpaceAfterExclamationMark" | "SpaceAroundParentheses" | "IndentPipeOperator" | "WPResizeSpaces" | "AlignDoubleSlashComments" | "AlignGroupDoubleArrow" | "ClassToStatic" | "JoinToImplode" | "MildAutoPreincrement" | "OnlyOrderUseClauses" | "OrderMethod" | "OrderMethodAndVisibility")[], 404 | "exclude": ("AddMissingCurlyBraces" | "AutoImportPass" | "ConstructorPass" | "EliminateDuplicatedEmptyLines" | "ExtraCommaInArray" | "LeftAlignComment" | "MergeCurlyCloseAndDoWhile" | "MergeDoubleArrowAndArray" | "MergeParenCloseWithCurlyOpen" | "NormalizeIsNotEquals" | "NormalizeLnAndLtrimLines" | "SmartLnAfterCurlyOpen" | "MatchNewLineAndCurlys" | "Reindent" | "ReindentColonBlocks" | "ReindentComments" | "ReindentEqual" | "ReindentObjOps" | "ResizeSpaces" | "RTrim" | "SettersAndGettersPass" | "SplitCurlyCloseAndTokens" | "StripExtraCommaInList" | "TwoCommandsInSameLine" | "PSR1BOMMark" | "PSR1ClassConstants" | "PSR1ClassNames" | "PSR1MethodNames" | "PSR1OpenTags" | "PSR2AlignObjOp" | "PSR2CurlyOpenNextLine" | "PSR2IndentWithSpace" | "PSR2KeywordsLowerCase" | "PSR2LnAfterNamespace" | "PSR2ModifierVisibilityStaticOrder" | "PSR2SingleEmptyLineAndStripClosingTag" | "AddMissingParentheses" | "AliasToMaster" | "AlignConstVisibilityEquals" | "AlignDoubleArrow" | "AlignComments" | "AlignEquals" | "AlignSuperEquals" | "AlignPHPCode" | "AlignTypehint" | "AllmanStyleBraces" | "AutoPreincrement" | "AutoSemicolon" | "CakePHPStyle" | "ClassToSelf" | "ConvertOpenTagWithEcho" | "DocBlockToComment" | "DoubleToSingleQuote" | "EchoToPrint" | "EncapsulateNamespaces" | "GeneratePHPDoc" | "IndentTernaryConditions" | "LeftWordWrap" | "LongArray" | "MergeElseIf" | "SplitElseIf" | "MergeNamespaceWithOpenTag" | "NewLineBeforeReturn" | "NoSpaceAfterPHPDocBlocks" | "OrganizeClass" | "OrderAndRemoveUseClauses" | "PHPDocTypesToFunctionTypehint" | "PrettyPrintDocBlocks" | "PSR2EmptyFunction" | "PSR2MultilineFunctionParams" | "ReindentAndAlignObjOps" | "ReindentSwitchBlocks" | "ReindentEnumBlocks" | "RemoveIncludeParentheses" | "RemoveSemicolonAfterCurly" | "RemoveUseLeadingSlash" | "ReplaceBooleanAndOr" | "ReplaceIsNull" | "RestoreComments" | "ReturnNull" | "ShortArray" | "SortUseNameSpace" | "SpaceAroundControlStructures" | "SpaceAroundExclamationMark" | "SpaceBetweenMethods" | "StrictBehavior" | "StrictComparison" | "StripExtraCommaInArray" | "StripNewlineAfterClassOpen" | "StripNewlineAfterCurlyOpen" | "StripNewlineWithinClassBody" | "StripSpaces" | "StripSpaceWithinControlStructures" | "TightConcat" | "TrimSpaceBeforeSemicolon" | "UpgradeToPreg" | "WordWrap" | "WrongConstructorName" | "YodaComparisons" | "SpaceAfterExclamationMark" | "SpaceAroundParentheses" | "IndentPipeOperator" | "WPResizeSpaces" | "AlignDoubleSlashComments" | "AlignGroupDoubleArrow" | "ClassToStatic" | "JoinToImplode" | "MildAutoPreincrement" | "OnlyOrderUseClauses" | "OrderMethod" | "OrderMethodAndVisibility")[], 405 | "smart_linebreak_after_curly": boolean, 406 | "yoda": boolean, 407 | "cakephp": boolean, 408 | "custom_arguments": string, 409 | }, 410 | } 411 | 412 | export interface NestedScopedConfigs { 413 | "php_bin": string, 414 | "use_old_phpfmt": boolean, 415 | "detect_indent": boolean, 416 | "psr1": boolean, 417 | "psr1_naming": boolean, 418 | "psr2": boolean, 419 | "wp": boolean, 420 | "indent_with_space": (unknown | boolean), 421 | "enable_auto_align": boolean, 422 | "visibility_order": boolean, 423 | "ignore": string[], 424 | "passes": ("AddMissingCurlyBraces" | "AutoImportPass" | "ConstructorPass" | "EliminateDuplicatedEmptyLines" | "ExtraCommaInArray" | "LeftAlignComment" | "MergeCurlyCloseAndDoWhile" | "MergeDoubleArrowAndArray" | "MergeParenCloseWithCurlyOpen" | "NormalizeIsNotEquals" | "NormalizeLnAndLtrimLines" | "SmartLnAfterCurlyOpen" | "MatchNewLineAndCurlys" | "Reindent" | "ReindentColonBlocks" | "ReindentComments" | "ReindentEqual" | "ReindentObjOps" | "ResizeSpaces" | "RTrim" | "SettersAndGettersPass" | "SplitCurlyCloseAndTokens" | "StripExtraCommaInList" | "TwoCommandsInSameLine" | "PSR1BOMMark" | "PSR1ClassConstants" | "PSR1ClassNames" | "PSR1MethodNames" | "PSR1OpenTags" | "PSR2AlignObjOp" | "PSR2CurlyOpenNextLine" | "PSR2IndentWithSpace" | "PSR2KeywordsLowerCase" | "PSR2LnAfterNamespace" | "PSR2ModifierVisibilityStaticOrder" | "PSR2SingleEmptyLineAndStripClosingTag" | "AddMissingParentheses" | "AliasToMaster" | "AlignConstVisibilityEquals" | "AlignDoubleArrow" | "AlignComments" | "AlignEquals" | "AlignSuperEquals" | "AlignPHPCode" | "AlignTypehint" | "AllmanStyleBraces" | "AutoPreincrement" | "AutoSemicolon" | "CakePHPStyle" | "ClassToSelf" | "ConvertOpenTagWithEcho" | "DocBlockToComment" | "DoubleToSingleQuote" | "EchoToPrint" | "EncapsulateNamespaces" | "GeneratePHPDoc" | "IndentTernaryConditions" | "LeftWordWrap" | "LongArray" | "MergeElseIf" | "SplitElseIf" | "MergeNamespaceWithOpenTag" | "NewLineBeforeReturn" | "NoSpaceAfterPHPDocBlocks" | "OrganizeClass" | "OrderAndRemoveUseClauses" | "PHPDocTypesToFunctionTypehint" | "PrettyPrintDocBlocks" | "PSR2EmptyFunction" | "PSR2MultilineFunctionParams" | "ReindentAndAlignObjOps" | "ReindentSwitchBlocks" | "ReindentEnumBlocks" | "RemoveIncludeParentheses" | "RemoveSemicolonAfterCurly" | "RemoveUseLeadingSlash" | "ReplaceBooleanAndOr" | "ReplaceIsNull" | "RestoreComments" | "ReturnNull" | "ShortArray" | "SortUseNameSpace" | "SpaceAroundControlStructures" | "SpaceAroundExclamationMark" | "SpaceBetweenMethods" | "StrictBehavior" | "StrictComparison" | "StripExtraCommaInArray" | "StripNewlineAfterClassOpen" | "StripNewlineAfterCurlyOpen" | "StripNewlineWithinClassBody" | "StripSpaces" | "StripSpaceWithinControlStructures" | "TightConcat" | "TrimSpaceBeforeSemicolon" | "UpgradeToPreg" | "WordWrap" | "WrongConstructorName" | "YodaComparisons" | "SpaceAfterExclamationMark" | "SpaceAroundParentheses" | "IndentPipeOperator" | "WPResizeSpaces" | "AlignDoubleSlashComments" | "AlignGroupDoubleArrow" | "ClassToStatic" | "JoinToImplode" | "MildAutoPreincrement" | "OnlyOrderUseClauses" | "OrderMethod" | "OrderMethodAndVisibility")[], 425 | "exclude": ("AddMissingCurlyBraces" | "AutoImportPass" | "ConstructorPass" | "EliminateDuplicatedEmptyLines" | "ExtraCommaInArray" | "LeftAlignComment" | "MergeCurlyCloseAndDoWhile" | "MergeDoubleArrowAndArray" | "MergeParenCloseWithCurlyOpen" | "NormalizeIsNotEquals" | "NormalizeLnAndLtrimLines" | "SmartLnAfterCurlyOpen" | "MatchNewLineAndCurlys" | "Reindent" | "ReindentColonBlocks" | "ReindentComments" | "ReindentEqual" | "ReindentObjOps" | "ResizeSpaces" | "RTrim" | "SettersAndGettersPass" | "SplitCurlyCloseAndTokens" | "StripExtraCommaInList" | "TwoCommandsInSameLine" | "PSR1BOMMark" | "PSR1ClassConstants" | "PSR1ClassNames" | "PSR1MethodNames" | "PSR1OpenTags" | "PSR2AlignObjOp" | "PSR2CurlyOpenNextLine" | "PSR2IndentWithSpace" | "PSR2KeywordsLowerCase" | "PSR2LnAfterNamespace" | "PSR2ModifierVisibilityStaticOrder" | "PSR2SingleEmptyLineAndStripClosingTag" | "AddMissingParentheses" | "AliasToMaster" | "AlignConstVisibilityEquals" | "AlignDoubleArrow" | "AlignComments" | "AlignEquals" | "AlignSuperEquals" | "AlignPHPCode" | "AlignTypehint" | "AllmanStyleBraces" | "AutoPreincrement" | "AutoSemicolon" | "CakePHPStyle" | "ClassToSelf" | "ConvertOpenTagWithEcho" | "DocBlockToComment" | "DoubleToSingleQuote" | "EchoToPrint" | "EncapsulateNamespaces" | "GeneratePHPDoc" | "IndentTernaryConditions" | "LeftWordWrap" | "LongArray" | "MergeElseIf" | "SplitElseIf" | "MergeNamespaceWithOpenTag" | "NewLineBeforeReturn" | "NoSpaceAfterPHPDocBlocks" | "OrganizeClass" | "OrderAndRemoveUseClauses" | "PHPDocTypesToFunctionTypehint" | "PrettyPrintDocBlocks" | "PSR2EmptyFunction" | "PSR2MultilineFunctionParams" | "ReindentAndAlignObjOps" | "ReindentSwitchBlocks" | "ReindentEnumBlocks" | "RemoveIncludeParentheses" | "RemoveSemicolonAfterCurly" | "RemoveUseLeadingSlash" | "ReplaceBooleanAndOr" | "ReplaceIsNull" | "RestoreComments" | "ReturnNull" | "ShortArray" | "SortUseNameSpace" | "SpaceAroundControlStructures" | "SpaceAroundExclamationMark" | "SpaceBetweenMethods" | "StrictBehavior" | "StrictComparison" | "StripExtraCommaInArray" | "StripNewlineAfterClassOpen" | "StripNewlineAfterCurlyOpen" | "StripNewlineWithinClassBody" | "StripSpaces" | "StripSpaceWithinControlStructures" | "TightConcat" | "TrimSpaceBeforeSemicolon" | "UpgradeToPreg" | "WordWrap" | "WrongConstructorName" | "YodaComparisons" | "SpaceAfterExclamationMark" | "SpaceAroundParentheses" | "IndentPipeOperator" | "WPResizeSpaces" | "AlignDoubleSlashComments" | "AlignGroupDoubleArrow" | "ClassToStatic" | "JoinToImplode" | "MildAutoPreincrement" | "OnlyOrderUseClauses" | "OrderMethod" | "OrderMethodAndVisibility")[], 426 | "smart_linebreak_after_curly": boolean, 427 | "yoda": boolean, 428 | "cakephp": boolean, 429 | "custom_arguments": string, 430 | } 431 | 432 | --------------------------------------------------------------------------------