Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 123 additions & 32 deletions extension.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
"use strict";
const vscode = require("vscode");
const { commands, workspace, window, languages, Range, Position } = vscode;
const {
commands,
workspace,
window,
languages,
Range,
Position
} = vscode;
const path = require("path");
const fs = require("fs");
const os = require("os");
const cp = require("child_process");
Expand All @@ -26,28 +34,60 @@ class PHPCBF {
process.platform == "win32" ? "php-cbf.bat" : "phpcbf"
);

/**
* relative paths?
*/
this.configSearch = config.get("configSearch", false);

// ${workspaceRoot} is deprecated
if (this.executablePath.startsWith("${workspaceRoot}")) {
this.addRootPath("${workspaceRoot}");
}
if (this.executablePath.startsWith("${workspaceFolder}")) {
this.addRootPath("${workspaceFolder}");
}
if (this.executablePath.startsWith(".")) {
this.addRootPath(".");
}
if (this.executablePath.startsWith("~")) {
this.executablePath = this.executablePath.replace(
/^~\//,
os.homedir() + "/"
);
}

const resolvePath = (key) => {
const addRootPath = (prefix) => {
const resources = [];
if (workspace.workspaceFolders) {
for (let wsFolder of workspace.workspaceFolders) {
resources.push(wsFolder.uri);
}
} else {
const editor = window.activeTextEditor;
if (editor) {
resources.push(editor.document.uri);
}
}
for (let resource of resources) {
if (resource.scheme == "file") {
const folder = workspace.getWorkspaceFolder(resource);
if (folder) {
const rootPath = folder.uri.fsPath;
let tmpPath = this[key].replace(prefix, rootPath);
fs.exists(tmpPath, exists => {
if (exists) {
this[key] = tmpPath;
}
});
}
}
}
}
if (this[key].startsWith("${workspaceRoot}")) {
addRootPath("${workspaceRoot}");
}
if (this[key].startsWith("${workspaceFolder}")) {
addRootPath("${workspaceFolder}");
}
if (this[key].startsWith(".")) {
addRootPath(".");
}
if (this[key].startsWith("~")) {
this[key] = this[key].replace(/^~\//, os.homedir() + "/");
}
}

this.executablePath = config.get(
"executablePath",
process.platform == "win32" ? "php-cbf.bat" : "phpcbf"
);
resolvePath('executablePath');

this.standard = config.get("standard", null);
if (this.standard) resolvePath('standard');


this.documentFormattingProvider = config.get(
"documentFormattingProvider",
Expand All @@ -57,14 +97,16 @@ class PHPCBF {
this.debug = config.get("debug", false);
}

getArgs(fileName) {
getArgs(document, tmpFileName) {
let args = [];
if (this.debug) {
args.push("-l");
} else {
args.push("-lq");
}
args.push(fileName);
args.push(tmpFileName);

this.standard = this.getStandard(document);

if (this.standard) {
args.push("--standard=" + this.standard);
Expand All @@ -78,22 +120,71 @@ class PHPCBF {
return args;
}

format(text) {
getStandard(document) {
if (this.standard) return this.standard;
// Check if a config file exists and handle it
let standard = null;
const folder = workspace.getWorkspaceFolder(document.uri);
const workspaceRoot = folder ? folder.uri.fsPath : null;
const filePath = document.fileName;
if (this.configSearch && workspaceRoot !== null && filePath !== undefined) {
const confFileNames = [
'.phpcs.xml', '.phpcs.xml.dist', 'phpcs.xml', 'phpcs.xml.dist',
'phpcs.ruleset.xml', 'ruleset.xml',
];

const fileDir = path.relative(workspaceRoot, path.dirname(filePath));
const confFile = this.findFiles(workspaceRoot, fileDir, confFileNames);

standard = confFile || this.standard;
} else {
standard = this.standard;
}

return standard;
}

findFiles(parent, directory, name) {
const names = [].concat(name);
const chunks = path.resolve(parent, directory).split(path.sep);

while (chunks.length) {
let currentDir = chunks.join(path.sep);
for (const fileName of names) {
const filePath = path.join(currentDir, fileName);
if (fs.existsSync(filePath)) {
return filePath;
}
}
if (parent === currentDir) {
break;
}
chunks.pop();
}

return null;
}

format(document) {
if (this.debug) {
console.time("phpcbf");
}
let text = document.getText();

let phpcbfError = false;
let fileName =
TmpDir +
"/temp-" +
Math.random()
.toString(36)
.replace(/[^a-z]+/g, "")
.substr(0, 10) +
.toString(36)
.replace(/[^a-z]+/g, "")
.substr(0, 10) +
".php";
fs.writeFileSync(fileName, text);

let exec = cp.spawn(this.executablePath, this.getArgs(fileName));
let exec = cp.spawn(this.executablePath, this.getArgs(document, fileName), {
cwd: vscode.workspace.rootPath
});
if (!this.debug) {
exec.stdin.end();
}
Expand Down Expand Up @@ -142,7 +233,7 @@ class PHPCBF {
break;
}

fs.unlink(fileName, function(err) {});
fs.unlink(fileName, function (err) {});
});
});

Expand Down Expand Up @@ -213,8 +304,8 @@ exports.activate = context => {
event.document.languageId == "php" &&
phpcbf.onsave &&
workspace
.getConfiguration("editor", editor.document.uri)
.get("formatOnSave") === false
.getConfiguration("editor", editor.document.uri)
.get("formatOnSave") === false
) {
event.waitUntil(
commands.executeCommand("editor.action.formatDocument")
Expand Down Expand Up @@ -242,14 +333,14 @@ exports.activate = context => {
languages.registerDocumentFormattingEditProvider("php", {
provideDocumentFormattingEdits: (document, options, token) => {
return new Promise((resolve, reject) => {
let originalText = document.getText();
const originalText = document.getText();
let lastLine = document.lineAt(document.lineCount - 1);
let range = new Range(
new Position(0, 0),
lastLine.range.end
);
phpcbf
.format(originalText)
.format(document)
.then(text => {
if (text != originalText) {
resolve([new vscode.TextEdit(range, text)]);
Expand Down
26 changes: 15 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"displayName": "phpcbf",
"description": "PHP Code Beautifier and Fixer",
"version": "0.0.8",
"publisher": "persoderlind",
"homepage": "https://github.com/soderlind/vscode-phpcbf",
"icon": "images/logo.png",
"license": "SEE LICENSE IN LICENSE.txt",
"publisher": "persoderlind",
"homepage": "https://github.com/soderlind/vscode-phpcbf",
"icon": "images/logo.png",
"license": "SEE LICENSE IN LICENSE.txt",
"repository": {
"type": "git",
"url": "https://github.com/soderlind/vscode-phpcbf.git"
Expand All @@ -25,13 +25,11 @@
],
"main": "./extension",
"contributes": {
"commands": [
{
"command": "phpcbf-soderlind",
"title": "PHP Code Beautifier and Fixer: Fix this file",
"when": "!inOutput && editorFocus && editorLangId == php"
}
],
"commands": [{
"command": "phpcbf-soderlind",
"title": "PHP Code Beautifier and Fixer: Fix this file",
"when": "!inOutput && editorFocus && editorLangId == php"
}],
"configuration": {
"title": "PHP Code Beautifier and Fixer Configuration options",
"type": "object",
Expand All @@ -42,6 +40,12 @@
"default": "phpcbf",
"description": "Points to the phpcbf exectuable, eg: win: phpcbf.bat, other: phpcbf"
},
"phpcbf.configSearch": {
"scope": "resource",
"type": "boolean",
"default": false,
"description": "Search for phpcs configuration files in the workspace."
},
"phpcbf.standard": {
"scope": "resource",
"type": [
Expand Down