diff --git a/client/README.md b/client/README.md index 1c69717..af99bc7 100644 --- a/client/README.md +++ b/client/README.md @@ -16,6 +16,15 @@ Follow [@HvyIndustries](https://twitter.com/HvyIndustries) on Twitter for update For the best development experience, make sure you have the PHP linter enabled in your user settings, and set it to run `onType` instead of `onSave`! +--- + +## What's new in v0.2.2 (latest release) + +- Added new setting `crane.ignoredPaths` that gives users the ability to ignore files/folders for parsing _(workaround for parser crashing issue)_ +- Added "what's new" section to readme to highlight new features/bug fixes + +--- + ## Current Features - Code-completion _(in progress, not quite 100% complete yet)_ diff --git a/client/package.json b/client/package.json index 9b3002f..5b91bfa 100644 --- a/client/package.json +++ b/client/package.json @@ -7,9 +7,16 @@ "url": "https://hvy.io", "email": "joe@hvy.io" }, + "contributors": [ + { + "name": "Ryan Naddy", + "email": "untuned20@gmail.com", + "url": "http://ryannaddy.com" + } + ], "icon": "images/php-256.png", "license": "MIT", - "version": "0.2.1", + "version": "0.2.2", "publisher": "HvyIndustries", "engines": { "vscode": "^0.10.x" @@ -43,7 +50,8 @@ "private": true, "homepage": "https://hvy.io/crane", "activationEvents": [ - "onLanguage:php" + "onLanguage:php", + "workspaceContains:phpconfig.json" ], "main": "./out/src/extension", "contributes": { @@ -70,6 +78,11 @@ "type": "string", "default": "https://codeload.github.com/HvyIndustries/crane-php-stubs/zip/master", "description": "The location of the PHP Stubs zip file that can be downloaded and unzipped for 3rd party library autocompletion" + }, + "crane.ignoredPaths": { + "type": "array", + "default": [], + "description": "An array of files/folders that should be ignored by the parser. Glob patterns are accepted (eg. **/*bad.php)" } } }, @@ -112,7 +125,7 @@ "postinstall": "node ./node_modules/vscode/bin/install" }, "devDependencies": { - "typescript": "^1.6.2", + "typescript": "^2.*.*", "vscode": "^0.11.13" }, "dependencies": { @@ -123,4 +136,4 @@ "unzip": "^0.1.11", "vscode-languageclient": "^1.1.0" } -} +} \ No newline at end of file diff --git a/client/phpTest/demo/test.php b/client/phpTest/demo/test.php new file mode 100644 index 0000000..8d1f932 --- /dev/null +++ b/client/phpTest/demo/test.php @@ -0,0 +1,5 @@ + this.onChangeTextHandler(e.document), null, subscriptions); - workspace.onDidCloseTextDocument((textDocument)=> { delete this.delayers[textDocument.uri.toString()]; }, null, subscriptions); + workspace.onDidCloseTextDocument((textDocument) => { delete this.delayers[textDocument.uri.toString()]; }, null, subscriptions); workspace.onDidSaveTextDocument((document) => this.handleFileSave()); this.disposable = Disposable.from(...subscriptions); @@ -56,8 +56,7 @@ export default class Crane }); } - private checkVersion(): Thenable - { + private checkVersion(): Thenable { var self = this; Debug.info('Checking the current version of Crane'); return new Promise((resolve, reject) => { @@ -140,25 +139,33 @@ export default class Crane var types = Config.phpFileTypes; Debug.info(`Watching these files: {${types.include.join(',')}}`); - var fsw: FileSystemWatcher = workspace.createFileSystemWatcher(`{${types.include.join(',')}}`); + var fsw: FileSystemWatcher = workspace.createFileSystemWatcher(`{${types.include.join(',')},**/phpconfig.json}`); fsw.onDidChange(e => { workspace.openTextDocument(e).then(document => { - if (document.languageId != 'php') return; + if (!['php', 'json'].indexOf(document.languageId)) return; Debug.info('File Changed: ' + e.fsPath); - Crane.langClient.sendRequest({ method: 'buildObjectTreeForDocument' }, { - path: e.fsPath, - text: document.getText() - }); + if (document.languageId == 'php') { + Crane.langClient.sendRequest({ method: 'buildObjectTreeForDocument' }, { + path: e.fsPath, + text: document.getText() + }); + } else if (document.languageId == 'json') { + cranefs.processWorkspaceFiles(true); + } }); }); fsw.onDidCreate(e => { workspace.openTextDocument(e).then(document => { - if (document.languageId != 'php') return; + if (!['php', 'json'].indexOf(document.languageId)) return; Debug.info('File Created: ' + e.fsPath); - Crane.langClient.sendRequest({ method: 'buildObjectTreeForDocument' }, { - path: e.fsPath, - text: document.getText() - }); + if (document.languageId == 'php') { + Crane.langClient.sendRequest({ method: 'buildObjectTreeForDocument' }, { + path: e.fsPath, + text: document.getText() + }); + } else if (document.languageId == 'json') { + cranefs.processWorkspaceFiles(true); + } }); }); fsw.onDidDelete(e => { @@ -277,8 +284,7 @@ export default class Crane delayer.trigger(() => this.buildObjectTreeForDocument(textDocument)); } - private buildObjectTreeForDocument(document: TextDocument): Promise - { + private buildObjectTreeForDocument(document: TextDocument): Promise { return new Promise((resolve, reject) => { var path = document.fileName; var text = document.getText(); @@ -286,12 +292,11 @@ export default class Crane var projectTree = cranefs.getTreePath(); var requestType: RequestType = { method: "buildObjectTreeForDocument" }; - Crane.langClient.sendRequest(requestType, { path, text, projectDir, projectTree }).then(() => resolve() ); + Crane.langClient.sendRequest(requestType, { path, text, projectDir, projectTree }).then(() => resolve()); }); } - dispose() - { + dispose() { this.disposable.dispose(); Crane.statusBarItem.dispose(); } diff --git a/client/src/extension.ts b/client/src/extension.ts index c5ae24f..638b352 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -13,18 +13,17 @@ import { LanguageClient, LanguageClientOptions, SettingMonitor, ServerOptions, T import Crane from "./crane"; import QualityOfLife from "./features/qualityOfLife"; -import { Debug } from './utils/Debug'; -import { Config } from './utils/Config'; +import Debug from './utils/Debug'; +import Config from './utils/Config'; -export function activate(context: ExtensionContext) -{ +export function activate(context: ExtensionContext) { let qol: QualityOfLife = new QualityOfLife(); let serverModule = context.asAbsolutePath(path.join("server", "server.js")); let debugOptions = { execArgv: ["--nolazy", "--debug=6004"] }; let serverOptions: ServerOptions = { - run : { module: serverModule, transport: TransportKind.ipc }, + run: { module: serverModule, transport: TransportKind.ipc }, debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } } diff --git a/client/src/utils/Config.ts b/client/src/utils/Config.ts index 066e45d..b4a4f7e 100644 --- a/client/src/utils/Config.ts +++ b/client/src/utils/Config.ts @@ -1,9 +1,9 @@ import { workspace } from 'vscode'; -import { Debug } from './Debug'; +import Debug from './Debug'; var pkg = require('../../../package.json'); -export class Config { +export default class Config { public static craneSettings = workspace.getConfiguration("crane"); @@ -31,6 +31,11 @@ export class Config { return Config.craneSettings ? Config.craneSettings.get("phpstubsZipFile", "https://codeload.github.com/HvyIndustries/crane-php-stubs/zip/master") : "https://codeload.github.com/HvyIndustries/crane-php-stubs/zip/master"; } + public static get ignoredPaths(): Array { + Config.reloadConfig(); + return Config.craneSettings ? Config.craneSettings.get>("ignoredPaths", []) : []; + } + public static get version(): string { return pkg.version.toString(); } diff --git a/client/src/utils/Cranefs.ts b/client/src/utils/Cranefs.ts index e035247..4cfbe25 100644 --- a/client/src/utils/Cranefs.ts +++ b/client/src/utils/Cranefs.ts @@ -1,17 +1,18 @@ import { workspace, window } from 'vscode'; import { NotificationType, RequestType } from 'vscode-languageclient'; import Crane from '../crane'; -import { Debug } from './Debug'; -import { Config } from './Config'; +import Debug from './Debug'; +import Config from './Config'; +import PHPConfig from './PHPConfig'; -const crypto = require('crypto'); -const fs = require('fs'); +const crypto = require('crypto'); +const fs = require('fs'); const fstream = require('fstream'); -const http = require('https'); -const unzip = require('unzip'); -const util = require('util'); -const mkdirp = require('mkdirp'); -const rmrf = require('rimraf'); +const http = require('https'); +const unzip = require('unzip'); +const util = require('util'); +const mkdirp = require('mkdirp'); +const rmrf = require('rimraf'); let craneSettings = workspace.getConfiguration("crane"); @@ -34,7 +35,7 @@ export class Cranefs { return process.env.HOME + '/Library/Preferences/Crane'; } if (process.platform == 'linux') { - return process.env.HOME + '/Crane'; + return process.env.HOME + '/.Crane'; } } @@ -106,18 +107,18 @@ export class Cranefs { Debug.error(util.inspect(error, false, null)); }); } else { - resolve({folderExists: false, folderCreated: false, path: null}) + resolve({ folderExists: false, folderCreated: false, path: null }) } }); } - public doesProjectTreeExist(): Promise<{exists:boolean, path:string}> { + public doesProjectTreeExist(): Promise<{ exists: boolean, path: string }> { return new Promise((resolve, reject) => { fs.stat(this.getTreePath(), (err, stat) => { if (err === null) { - resolve({exists: true, path: this.getTreePath()}); + resolve({ exists: true, path: this.getTreePath() }); } else { - resolve({exists: false, path: null}); + resolve({ exists: false, path: null }); } }); }); @@ -127,11 +128,16 @@ export class Cranefs { if (workspace.rootPath == undefined) return; var fileProcessCount = 0; - // Get PHP files from 'files.associations' to be processed - var files = Config.phpFileTypes; + PHPConfig.load(); + + // Get PHP files from 'phpconfig.json' to be processed + let files = PHPConfig.getFilePatterns(); + + // Exclude files ignored by the user + // files.exclude = files.exclude.concat(Config.ignoredPaths); // Find all the php files to process - workspace.findFiles(`{${files.include.join(',')}}`, `{${files.exclude.join(',')}}`).then(files => { + workspace.findFiles(files.include, files.exclude).then(files => { Debug.info(`Preparing to parse ${files.length} PHP source files...`); fileProcessCount = files.length; diff --git a/client/src/utils/Debug.ts b/client/src/utils/Debug.ts index 76db361..1cdafa8 100644 --- a/client/src/utils/Debug.ts +++ b/client/src/utils/Debug.ts @@ -1,9 +1,9 @@ import { window, workspace, OutputChannel } from 'vscode'; -import { Config } from './Config'; +import Config from './Config'; const outputConsole = window.createOutputChannel("Crane Console"); -export class Debug { +export default class Debug { private static calls: number = 0; diff --git a/client/src/utils/PHPConfig.ts b/client/src/utils/PHPConfig.ts new file mode 100644 index 0000000..8de09e1 --- /dev/null +++ b/client/src/utils/PHPConfig.ts @@ -0,0 +1,26 @@ +import {workspace} from 'vscode'; + +export default class PHPConfig { + + private static phpConfig: { files?: string[], exclude?: string[] } = {}; + + public static getFilePatterns(): { include: string, exclude: string } { + let pattern = { include: '**/*.php', exclude: '' }; + + if (this.phpConfig.files && this.phpConfig.files.length > 0) { + pattern.include = '{' + this.phpConfig.files.join(',') + '}'; + } else if (this.phpConfig.exclude && this.phpConfig.exclude.length > 0) { + pattern.exclude = '{' + this.phpConfig.exclude.join(',') + '}'; + } + + return pattern; + } + + public static load() { + try { + let file = workspace.rootPath + '/phpconfig.json'; + this.phpConfig = require(file); + delete require.cache[require.resolve(file)]; + } catch (e) { } + } +} \ No newline at end of file diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 0000000..f76e95e --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,23 @@ +0 info it worked if it ends with ok +1 verbose cli [ 'C:\\Program Files\\nodejs\\node.exe', +1 verbose cli 'C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js', +1 verbose cli 'install' ] +2 info using npm@2.15.8 +3 info using node@v4.4.7 +4 verbose readDependencies loading dependencies from C:\Users\rnaddy\Documents\vscode\projects\crane\package.json +5 error install Couldn't read dependencies +6 verbose stack Error: ENOENT: no such file or directory, open 'C:\Users\rnaddy\Documents\vscode\projects\crane\package.json' +6 verbose stack at Error (native) +7 verbose cwd C:\Users\rnaddy\Documents\vscode\projects\crane +8 error Windows_NT 10.0.14393 +9 error argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install" +10 error node v4.4.7 +11 error npm v2.15.8 +12 error path C:\Users\rnaddy\Documents\vscode\projects\crane\package.json +13 error code ENOPACKAGEJSON +14 error errno -4058 +15 error syscall open +16 error package.json ENOENT: no such file or directory, open 'C:\Users\rnaddy\Documents\vscode\projects\crane\package.json' +16 error package.json This is most likely not a problem with npm itself. +16 error package.json npm can't find a package.json file in your current directory. +17 verbose exit [ -4058, true ] diff --git a/server/package.json b/server/package.json index 5949bd6..12fa009 100644 --- a/server/package.json +++ b/server/package.json @@ -3,6 +3,13 @@ "description": "The language server for Crane", "version": "1.0.2", "author": "HVY Industries", + "contributors": [ + { + "name": "Ryan Naddy", + "email": "untuned20@gmail.com", + "url": "http://ryannaddy.com" + } + ], "license": "MIT", "engines": { "node": "*" @@ -18,10 +25,10 @@ "vscode-languageserver": "^1.1.0" }, "devDependencies": { - "typescript": "^1.6.2" + "typescript": "^2.*.*" }, "scripts": { "compile": "installServerIntoExtension ../client ./package.json ./tsconfig.json && tsc -p .", "watch": "installServerIntoExtension ../client ./package.json ./tsconfig.json && tsc --watch -p ." } -} +} \ No newline at end of file