Merge remote-tracking branch 'origin/master' into tyriar/electron-1.7.5

This commit is contained in:
Daniel Imms 2017-08-20 16:35:38 -07:00
commit 04f22441c6
208 changed files with 4066 additions and 2287 deletions

View file

@ -9,7 +9,7 @@
a code editor with what developers need for their core edit-build-debug cycle. Code
provides comprehensive editing and debugging support, an extensibility model, and lightweight integration with existing tools.
VS Code is updated monthly with new features and bug fixes. You can download it for Windows, Mac and Linux on [VS Code's website](https://code.visualstudio.com/Download). To get the latest releases everyday, you can install the [Insiders version of VS Code](https://code.visualstudio.com/insiders). This builds from the master branch and is updated at least daily.
VS Code is updated monthly with new features and bug fixes. You can download it for Windows, macOS, and Linux on [VS Code's website](https://code.visualstudio.com/Download). To get the latest releases everyday, you can install the [Insiders version of VS Code](https://code.visualstudio.com/insiders). This builds from the master branch and is updated at least daily.
<p align="center">
<img alt="VS Code in action" src="https://cloud.githubusercontent.com/assets/11839736/16642200/6624dde0-43bd-11e6-8595-c81885ba0dc2.png">

View file

@ -43,8 +43,8 @@ const nodeModules = ['electron', 'original-fs']
// Build
const builtInExtensions = [
{ name: 'ms-vscode.node-debug', version: '1.16.4' },
{ name: 'ms-vscode.node-debug2', version: '1.16.0' }
{ name: 'ms-vscode.node-debug', version: '1.16.5' },
{ name: 'ms-vscode.node-debug2', version: '1.16.3' }
];
const excludedExtensions = [

View file

@ -5,16 +5,7 @@
declare module monaco {
interface Thenable<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
}
type Thenable<T> = PromiseLike<T>;
export interface IDisposable {
dispose(): void;
@ -41,7 +32,7 @@ declare module monaco {
Error = 3,
}
#include(vs/base/common/winjs.base.d.ts): TValueCallback, ProgressCallback, TPromise
#include(vs/base/common/winjs.base.d.ts): TValueCallback, ProgressCallback, Promise
#include(vs/base/common/cancellation): CancellationTokenSource, CancellationToken
#include(vs/base/common/uri): URI
#include(vs/editor/common/standalone/standaloneBase): KeyCode, KeyMod

View file

@ -24,6 +24,7 @@ npmInstall('extensions'); // node modules shared by all extensions
const extensions = [
'vscode-api-tests',
'vscode-colorize-tests',
'azure-account',
'json',
'configuration-editing',
'extension-editing',

View file

@ -0,0 +1,4 @@
test/**
src/**
tsconfig.json
npm-shrinkwrap.json

View file

@ -0,0 +1,521 @@
{
"name": "azure-account",
"version": "0.1.0",
"dependencies": {
"@types/copy-paste": {
"version": "1.1.30",
"from": "@types/copy-paste@>=1.1.30 <2.0.0",
"resolved": "https://registry.npmjs.org/@types/copy-paste/-/copy-paste-1.1.30.tgz",
"dev": true
},
"@types/form-data": {
"version": "2.2.0",
"from": "@types/form-data@*",
"resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.0.tgz",
"dependencies": {
"@types/node": {
"version": "8.0.24",
"from": "@types/node@*",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.24.tgz"
}
}
},
"@types/node": {
"version": "6.0.87",
"from": "@types/node@>=6.0.40 <7.0.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.87.tgz",
"dev": true
},
"@types/opn": {
"version": "3.0.28",
"from": "@types/opn@>=3.0.28 <4.0.0",
"resolved": "https://registry.npmjs.org/@types/opn/-/opn-3.0.28.tgz",
"dev": true
},
"@types/request": {
"version": "0.0.45",
"from": "@types/request@>=0.0.45 <0.0.46",
"resolved": "https://registry.npmjs.org/@types/request/-/request-0.0.45.tgz",
"dependencies": {
"@types/node": {
"version": "8.0.24",
"from": "@types/node@*",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.24.tgz"
}
}
},
"@types/uuid": {
"version": "2.0.30",
"from": "@types/uuid@>=2.0.29 <3.0.0",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-2.0.30.tgz",
"dependencies": {
"@types/node": {
"version": "8.0.24",
"from": "@types/node@*",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.24.tgz"
}
}
},
"adal-node": {
"version": "0.1.22",
"from": "adal-node@>=0.1.22 <0.2.0",
"resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.22.tgz"
},
"ajv": {
"version": "4.11.8",
"from": "ajv@>=4.9.1 <5.0.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz"
},
"asn1": {
"version": "0.2.3",
"from": "asn1@>=0.2.3 <0.3.0",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz"
},
"assert-plus": {
"version": "0.2.0",
"from": "assert-plus@>=0.2.0 <0.3.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz"
},
"async": {
"version": "2.5.0",
"from": "async@>=0.6.0",
"resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz"
},
"asynckit": {
"version": "0.4.0",
"from": "asynckit@>=0.4.0 <0.5.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
},
"aws-sign2": {
"version": "0.6.0",
"from": "aws-sign2@>=0.6.0 <0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz"
},
"aws4": {
"version": "1.6.0",
"from": "aws4@>=1.2.1 <2.0.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz"
},
"azure-arm-resource": {
"version": "2.0.0-preview",
"from": "azure-arm-resource@>=2.0.0-preview <3.0.0",
"resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-2.0.0-preview.tgz"
},
"base64url": {
"version": "2.0.0",
"from": "base64url@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz"
},
"bcrypt-pbkdf": {
"version": "1.0.1",
"from": "bcrypt-pbkdf@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
"optional": true
},
"boom": {
"version": "2.10.1",
"from": "boom@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz"
},
"buffer-equal-constant-time": {
"version": "1.0.1",
"from": "buffer-equal-constant-time@1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz"
},
"caseless": {
"version": "0.12.0",
"from": "caseless@>=0.12.0 <0.13.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz"
},
"co": {
"version": "4.6.0",
"from": "co@>=4.6.0 <5.0.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz"
},
"combined-stream": {
"version": "1.0.5",
"from": "combined-stream@>=1.0.5 <1.1.0",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz"
},
"copy-paste": {
"version": "1.3.0",
"from": "copy-paste@>=1.3.0 <2.0.0",
"resolved": "https://registry.npmjs.org/copy-paste/-/copy-paste-1.3.0.tgz"
},
"core-util-is": {
"version": "1.0.2",
"from": "core-util-is@1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
},
"cryptiles": {
"version": "2.0.5",
"from": "cryptiles@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz"
},
"dashdash": {
"version": "1.14.1",
"from": "dashdash@>=1.12.0 <2.0.0",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"from": "assert-plus@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
}
}
},
"date-utils": {
"version": "1.2.21",
"from": "date-utils@*",
"resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz"
},
"delayed-stream": {
"version": "1.0.0",
"from": "delayed-stream@>=1.0.0 <1.1.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
},
"duplexer": {
"version": "0.1.1",
"from": "duplexer@>=0.1.1 <0.2.0",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz"
},
"ecc-jsbn": {
"version": "0.1.1",
"from": "ecc-jsbn@>=0.1.1 <0.2.0",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
"optional": true
},
"ecdsa-sig-formatter": {
"version": "1.0.9",
"from": "ecdsa-sig-formatter@1.0.9",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz"
},
"extend": {
"version": "3.0.1",
"from": "extend@>=3.0.0 <3.1.0",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz"
},
"extsprintf": {
"version": "1.3.0",
"from": "extsprintf@1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz"
},
"forever-agent": {
"version": "0.6.1",
"from": "forever-agent@>=0.6.1 <0.7.0",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz"
},
"form-data": {
"version": "2.1.4",
"from": "form-data@>=2.1.1 <2.2.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz"
},
"getpass": {
"version": "0.1.7",
"from": "getpass@>=0.1.1 <0.2.0",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"from": "assert-plus@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
}
}
},
"har-schema": {
"version": "1.0.5",
"from": "har-schema@>=1.0.5 <2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz"
},
"har-validator": {
"version": "4.2.1",
"from": "har-validator@>=4.2.1 <4.3.0",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz"
},
"hawk": {
"version": "3.1.3",
"from": "hawk@>=3.1.3 <3.2.0",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz"
},
"hoek": {
"version": "2.16.3",
"from": "hoek@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz"
},
"http-signature": {
"version": "1.1.1",
"from": "http-signature@>=1.1.0 <1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz"
},
"iconv-lite": {
"version": "0.4.18",
"from": "iconv-lite@>=0.4.8 <0.5.0",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz"
},
"is-buffer": {
"version": "1.1.5",
"from": "is-buffer@>=1.1.5 <2.0.0",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz"
},
"is-stream": {
"version": "1.1.0",
"from": "is-stream@>=1.1.0 <2.0.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz"
},
"is-typedarray": {
"version": "1.0.0",
"from": "is-typedarray@>=1.0.0 <1.1.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz"
},
"is-wsl": {
"version": "1.1.0",
"from": "is-wsl@>=1.1.0 <2.0.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz"
},
"isstream": {
"version": "0.1.2",
"from": "isstream@>=0.1.2 <0.2.0",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz"
},
"jsbn": {
"version": "0.1.1",
"from": "jsbn@>=0.1.0 <0.2.0",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"optional": true
},
"json-schema": {
"version": "0.2.3",
"from": "json-schema@0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz"
},
"json-stable-stringify": {
"version": "1.0.1",
"from": "json-stable-stringify@>=1.0.1 <2.0.0",
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz"
},
"json-stringify-safe": {
"version": "5.0.1",
"from": "json-stringify-safe@>=5.0.1 <5.1.0",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
},
"jsonify": {
"version": "0.0.0",
"from": "jsonify@>=0.0.0 <0.1.0",
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz"
},
"jsprim": {
"version": "1.4.1",
"from": "jsprim@>=1.2.2 <2.0.0",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"from": "assert-plus@1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
}
}
},
"jwa": {
"version": "1.1.5",
"from": "jwa@>=1.1.4 <2.0.0",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.5.tgz"
},
"jws": {
"version": "3.1.4",
"from": "jws@>=3.0.0 <4.0.0",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.1.4.tgz"
},
"lodash": {
"version": "4.17.4",
"from": "lodash@>=4.14.0 <5.0.0",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz"
},
"mime-db": {
"version": "1.29.0",
"from": "mime-db@>=1.29.0 <1.30.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz"
},
"mime-types": {
"version": "2.1.16",
"from": "mime-types@>=2.1.7 <2.2.0",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz"
},
"moment": {
"version": "2.18.1",
"from": "moment@>=2.14.1 <3.0.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz"
},
"ms-rest": {
"version": "2.2.1",
"from": "ms-rest@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.2.1.tgz",
"dependencies": {
"@types/node": {
"version": "7.0.42",
"from": "@types/node@>=7.0.10 <8.0.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.42.tgz"
},
"uuid": {
"version": "3.1.0",
"from": "uuid@^3.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz"
}
}
},
"ms-rest-azure": {
"version": "2.2.3",
"from": "ms-rest-azure@>=2.2.3 <3.0.0",
"resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.2.3.tgz",
"dependencies": {
"@types/node": {
"version": "7.0.42",
"from": "@types/node@^7.0.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.42.tgz"
},
"async": {
"version": "0.2.7",
"from": "async@0.2.7",
"resolved": "https://registry.npmjs.org/async/-/async-0.2.7.tgz"
},
"uuid": {
"version": "3.1.0",
"from": "uuid@^3.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz"
}
}
},
"node-uuid": {
"version": "1.4.7",
"from": "node-uuid@1.4.7",
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz"
},
"oauth-sign": {
"version": "0.8.2",
"from": "oauth-sign@>=0.8.1 <0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz"
},
"opn": {
"version": "5.1.0",
"from": "opn@>=5.1.0 <6.0.0",
"resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz"
},
"performance-now": {
"version": "0.2.0",
"from": "performance-now@>=0.2.0 <0.3.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz"
},
"punycode": {
"version": "1.4.1",
"from": "punycode@>=1.4.1 <2.0.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz"
},
"qs": {
"version": "6.4.0",
"from": "qs@>=6.4.0 <6.5.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz"
},
"request": {
"version": "2.81.0",
"from": "request@>=2.52.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
"dependencies": {
"uuid": {
"version": "3.1.0",
"from": "uuid@>=3.0.0 <4.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz"
}
}
},
"safe-buffer": {
"version": "5.1.1",
"from": "safe-buffer@>=5.0.1 <6.0.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz"
},
"sntp": {
"version": "1.0.9",
"from": "sntp@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz"
},
"sshpk": {
"version": "1.13.1",
"from": "sshpk@>=1.7.0 <2.0.0",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"from": "assert-plus@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
}
}
},
"stringstream": {
"version": "0.0.5",
"from": "stringstream@>=0.0.4 <0.1.0",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz"
},
"sync-exec": {
"version": "0.6.2",
"from": "sync-exec@>=0.6.0 <0.7.0",
"resolved": "https://registry.npmjs.org/sync-exec/-/sync-exec-0.6.2.tgz",
"optional": true
},
"through": {
"version": "2.3.8",
"from": "through@>=2.3.4 <2.4.0",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
},
"tough-cookie": {
"version": "2.3.2",
"from": "tough-cookie@>=2.3.0 <2.4.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz"
},
"tunnel": {
"version": "0.0.5",
"from": "tunnel@>=0.0.2 <0.1.0",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz"
},
"tunnel-agent": {
"version": "0.6.0",
"from": "tunnel-agent@>=0.6.0 <0.7.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz"
},
"tweetnacl": {
"version": "0.14.5",
"from": "tweetnacl@>=0.14.0 <0.15.0",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"optional": true
},
"underscore": {
"version": "1.8.3",
"from": "underscore@>=1.3.1",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz"
},
"verror": {
"version": "1.10.0",
"from": "verror@1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"from": "assert-plus@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
}
}
},
"vscode-nls": {
"version": "2.0.2",
"from": "vscode-nls@>=2.0.2 <3.0.0",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz"
},
"xmldom": {
"version": "0.1.27",
"from": "xmldom@>=0.1.0",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz"
},
"xpath.js": {
"version": "1.0.7",
"from": "xpath.js@>=1.0.5 <1.1.0",
"resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.0.7.tgz"
}
}
}

View file

@ -0,0 +1,70 @@
{
"name": "azure-account",
"version": "0.1.0",
"publisher": "vscode",
"engines": {
"vscode": "*"
},
"enableProposedApi": true,
"activationEvents": [
"*"
],
"main": "./out/extension",
"contributes": {
"commands": [
{
"command": "azure-account.login",
"title": "%azure-account.commands.login%",
"category": "%azure-account.commands.azure%"
},
{
"command": "azure-account.logout",
"title": "%azure-account.commands.logout%",
"category": "%azure-account.commands.azure%"
},
{
"command": "azure-account.addFilter",
"title": "%azure-account.commands.addResourceFilter%",
"category": "%azure-account.commands.azure%"
},
{
"command": "azure-account.removeFilter",
"title": "%azure-account.commands.removeResourceFilter%",
"category": "%azure-account.commands.azure%"
},
{
"command": "azure-account.createAccount",
"title": "%azure-account.commands.createAccount%",
"category": "%azure-account.commands.azure%"
}
],
"configuration": {
"type": "object",
"title": "Azure configuration",
"properties": {
"azure.resourceFilter": {
"type": "array",
"default": null,
"description": "The resource filter, each element is either a subscription id or a subscription id and a resource group name separated by a slash."
}
}
}
},
"scripts": {
"compile": "gulp compile-extension:azure-account",
"watch": "gulp watch-extension:azure-account"
},
"devDependencies": {
"@types/copy-paste": "^1.1.30",
"@types/node": "^6.0.40",
"@types/opn": "^3.0.28"
},
"dependencies": {
"adal-node": "^0.1.22",
"azure-arm-resource": "^2.0.0-preview",
"copy-paste": "^1.3.0",
"ms-rest-azure": "^2.2.3",
"vscode-nls": "^2.0.2",
"opn": "^5.1.0"
}
}

View file

@ -0,0 +1,8 @@
{
"azure-account.commands.azure": "Azure",
"azure-account.commands.login": "Login",
"azure-account.commands.logout": "Logout",
"azure-account.commands.addResourceFilter": "Add Resource Filter",
"azure-account.commands.removeResourceFilter": "Remove Resource Filter",
"azure-account.commands.createAccount": "Create an Account"
}

View file

@ -0,0 +1,472 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const adal = require('adal-node');
const MemoryCache = adal.MemoryCache;
const AuthenticationContext = adal.AuthenticationContext;
const CacheDriver = require('adal-node/lib/cache-driver');
const createLogContext = require('adal-node/lib/log').createLogContext;
import { DeviceTokenCredentials, AzureEnvironment } from 'ms-rest-azure';
import { SubscriptionClient, ResourceManagementClient, SubscriptionModels } from 'azure-arm-resource';
import * as opn from 'opn';
import * as copypaste from 'copy-paste';
import * as nls from 'vscode-nls';
import { window, commands, credentials, EventEmitter, MessageItem, ExtensionContext, workspace, ConfigurationTarget } from 'vscode';
import { AzureAccount, AzureSession, AzureLoginStatus, AzureResourceFilter } from './typings/azure-account.api';
const localize = nls.loadMessageBundle();
const defaultEnvironment = (<any>AzureEnvironment).Azure;
const commonTenantId = 'common';
const authorityHostUrl = defaultEnvironment.activeDirectoryEndpointUrl;
const clientId = '04b07795-8ddb-461a-bbee-02f9e1bf7b46';
const authorityUrl = `${authorityHostUrl}${commonTenantId}`;
const resource = defaultEnvironment.activeDirectoryResourceId;
const credentialsService = 'VSCode Public Azure';
const credentialsAccount = 'Refresh Token';
interface DeviceLogin {
userCode: string;
deviceCode: string;
verificationUrl: string;
expiresIn: number;
interval: number;
message: string;
}
interface TokenResponse {
tokenType: string;
expiresIn: number;
expiresOn: string;
resource: string;
accessToken: string;
refreshToken: string;
userId: string;
isUserIdDisplayable: boolean;
familyName: string;
givenName: string;
oid: string;
tenantId: string;
isMRRT: boolean;
_clientId: string;
_authority: string;
}
interface AzureAccountWriteable extends AzureAccount {
status: AzureLoginStatus;
}
class AzureLoginError extends Error {
constructor(message: string, public _reason: any) {
super(message);
}
}
export class AzureLoginHelper {
private onStatusChanged = new EventEmitter<AzureLoginStatus>();
private onSessionsChanged = new EventEmitter<void>();
private onFiltersChanged = new EventEmitter<void>();
private tokenCache = new MemoryCache();
private oldResourceFilter: string;
constructor(context: ExtensionContext) {
const subscriptions = context.subscriptions;
subscriptions.push(commands.registerCommand('azure-account.login', () => this.login().catch(console.error)));
subscriptions.push(commands.registerCommand('azure-account.logout', () => this.logout().catch(console.error)));
subscriptions.push(commands.registerCommand('azure-account.askForLogin', () => this.askForLogin().catch(console.error)));
subscriptions.push(commands.registerCommand('azure-account.addFilter', () => this.addFilter().catch(console.error)));
subscriptions.push(commands.registerCommand('azure-account.removeFilter', () => this.removeFilter().catch(console.error)));
subscriptions.push(this.api.onSessionsChanged(() => this.updateFilters().catch(console.error)));
subscriptions.push(workspace.onDidChangeConfiguration(() => this.updateFilters(true).catch(console.error)));
this.initialize()
.catch(console.error);
}
api: AzureAccount = {
status: 'Initializing',
onStatusChanged: this.onStatusChanged.event,
sessions: [],
onSessionsChanged: this.onSessionsChanged.event,
filters: [],
onFiltersChanged: this.onFiltersChanged.event,
credentials
};
async login() {
try {
this.beginLoggingIn();
const deviceLogin = await deviceLogin1();
const copyAndOpen: MessageItem = { title: localize('azure-account.copyAndOpen', "Copy & Open") };
const close: MessageItem = { title: localize('azure-account.close', "Close"), isCloseAffordance: true };
const response = await window.showInformationMessage(deviceLogin.message, copyAndOpen, close);
if (response === copyAndOpen) {
copypaste.copy(deviceLogin.userCode);
opn(deviceLogin.verificationUrl);
}
const tokenResponse = await deviceLogin2(deviceLogin);
const refreshToken = tokenResponse.refreshToken;
const tokenResponses = await tokensFromToken(tokenResponse);
await credentials.writeSecret(credentialsService, credentialsAccount, refreshToken);
await this.updateSessions(tokenResponses);
} finally {
this.updateStatus();
}
}
async logout() {
await credentials.deleteSecret(credentialsService, credentialsAccount);
await this.updateSessions([]);
this.updateStatus();
}
private async initialize() {
try {
const refreshToken = await credentials.readSecret(credentialsService, credentialsAccount);
if (refreshToken) {
this.beginLoggingIn();
const tokenResponse = await tokenFromRefreshToken(refreshToken);
const tokenResponses = await tokensFromToken(tokenResponse);
await this.updateSessions(tokenResponses);
}
} catch (err) {
if (!(err instanceof AzureLoginError)) {
throw err;
}
} finally {
this.updateStatus();
}
}
private beginLoggingIn() {
if (this.api.status !== 'LoggedIn') {
(<AzureAccountWriteable>this.api).status = 'LoggingIn';
this.onStatusChanged.fire(this.api.status);
}
}
private updateStatus() {
const status = this.api.sessions.length ? 'LoggedIn' : 'LoggedOut';
if (this.api.status !== status) {
(<AzureAccountWriteable>this.api).status = status;
this.onStatusChanged.fire(this.api.status);
}
}
private async updateSessions(tokenResponses: TokenResponse[]) {
await clearTokenCache(this.tokenCache);
for (const tokenResponse of tokenResponses) {
await addTokenToCache(this.tokenCache, tokenResponse);
}
const sessions = this.api.sessions;
sessions.splice(0, sessions.length, ...tokenResponses.map<AzureSession>(tokenResponse => ({
environment: defaultEnvironment,
userId: tokenResponse.userId,
tenantId: tokenResponse.tenantId,
credentials: new DeviceTokenCredentials({ username: tokenResponse.userId, clientId, tokenCache: this.tokenCache, domain: tokenResponse.tenantId })
})));
this.onSessionsChanged.fire();
}
private async askForLogin() {
if (this.api.status === 'LoggedIn') {
return;
}
const login = { title: localize('azure-account.login', "Login") };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showInformationMessage(localize('azure-account.loginFirst', "Not logged in, log in first."), login, cancel);
return result === login && commands.executeCommand('azure-account.login');
}
private async addFilter() {
if (this.api.status !== 'LoggedIn') {
return commands.executeCommand('azure-account.askForLogin');
}
const azureConfig = workspace.getConfiguration('azure');
const resourceFilter = azureConfig.get<string[]>('resourceFilter') || [];
const subscriptionItems: { session: AzureSession; subscription: SubscriptionModels.Subscription }[] = [];
for (const session of this.api.sessions) {
const credentials = session.credentials;
const client = new SubscriptionClient(credentials);
const subscriptions = await listAll(client.subscriptions, client.subscriptions.list());
subscriptionItems.push(...subscriptions.filter(subscription => resourceFilter.indexOf(`${session.tenantId}/${subscription.subscriptionId}`) === -1)
.map(subscription => ({
session,
subscription
})));
}
subscriptionItems.sort((a, b) => a.subscription.displayName!.localeCompare(b.subscription.displayName!));
const subscriptionResult = await window.showQuickPick(subscriptionItems.map(subscription => ({
label: subscription.subscription.displayName!,
description: subscription.subscription.subscriptionId!,
subscription
})));
if (!subscriptionResult) {
return;
}
const { session, subscription } = subscriptionResult.subscription;
const client = new ResourceManagementClient(session.credentials, subscription.subscriptionId!);
const resourceGroups = await listAll(client.resourceGroups, client.resourceGroups.list());
const resourceGroupFilters: AzureResourceFilter[] = [
{
...subscriptionResult.subscription,
allResourceGroups: true,
resourceGroups
}
];
resourceGroupFilters.push(...resourceGroups.filter(resourceGroup => resourceFilter.indexOf(`${session.tenantId}/${subscription.subscriptionId}/${resourceGroup.name}`) === -1)
.map(resourceGroup => ({
session,
subscription,
allResourceGroups: false,
resourceGroups: [resourceGroup]
})));
resourceGroupFilters.sort((a, b) => (!a.allResourceGroups ? a.resourceGroups[0].name! : '').localeCompare(!b.allResourceGroups ? b.resourceGroups[0].name! : ''));
const resourceGroupResult = await window.showQuickPick(resourceGroupFilters.map(resourceGroup => (!resourceGroup.allResourceGroups ? {
label: resourceGroup.resourceGroups[0].name!,
description: resourceGroup.resourceGroups[0].location,
resourceGroup
} : {
label: localize('azure-account.entireSubscription', "Entire Subscription"),
description: '',
resourceGroup
})));
if (!resourceGroupResult) {
return;
}
const resourceGroup = resourceGroupResult.resourceGroup;
if (!resourceGroup.allResourceGroups) {
resourceFilter.push(`${resourceGroup.session.tenantId}/${resourceGroup.subscription.subscriptionId}/${resourceGroup.resourceGroups[0].name}`);
} else {
resourceFilter.splice(0, resourceFilter.length, ...resourceFilter.filter(c => !c.startsWith(`${resourceGroup.session.tenantId}/${resourceGroup.subscription.subscriptionId}/`)));
resourceFilter.push(`${resourceGroup.session.tenantId}/${resourceGroup.subscription.subscriptionId}`);
}
const resourceFilterConfig = azureConfig.inspect<string[]>('resourceFilter');
let target = ConfigurationTarget.Global;
if (resourceFilterConfig) {
if (resourceFilterConfig.workspaceFolderValue) {
target = ConfigurationTarget.WorkspaceFolder;
} else if (resourceFilterConfig.workspaceValue) {
target = ConfigurationTarget.Workspace;
} else if (resourceFilterConfig.globalValue) {
target = ConfigurationTarget.Global;
}
}
await azureConfig.update('resourceFilter', resourceFilter, target);
}
private async removeFilter() {
if (this.api.status !== 'LoggedIn') {
return commands.executeCommand('azure-account.askForLogin');
}
const azureConfig = workspace.getConfiguration('azure');
let resourceFilter = azureConfig.get<string[]>('resourceFilter') || [];
const filters = resourceFilter.length ? this.api.filters.reduce((list, filter) => {
if (filter.allResourceGroups) {
list.push(filter);
} else {
list.push(...filter.resourceGroups.map(resourceGroup => ({
...filter,
resourceGroups: [resourceGroup]
})));
}
return list;
}, <AzureResourceFilter[]>[]) : [];
filters.sort((a, b) => (!a.allResourceGroups ? a.resourceGroups[0].name! : `/${a.subscription.displayName}`).localeCompare(!b.allResourceGroups ? b.resourceGroups[0].name! : `/${b.subscription.displayName}`));
const filterResult = await window.showQuickPick(filters.map(filter => (!filter.allResourceGroups ? {
label: filter.resourceGroups[0].name!,
description: filter.subscription.displayName!,
filter
} : {
label: filter.subscription.displayName!,
description: filter.subscription.subscriptionId!,
filter
})));
if (!filterResult) {
return;
}
const filter = filterResult.filter;
const remove = !filter.allResourceGroups ?
`${filter.session.tenantId}/${filter.subscription.subscriptionId}/${filter.resourceGroups[0].name}` :
`${filter.session.tenantId}/${filter.subscription.subscriptionId}`;
resourceFilter = resourceFilter.filter(e => e !== remove);
const resourceFilterConfig = azureConfig.inspect<string[]>('resourceFilter');
let target = ConfigurationTarget.Global;
if (resourceFilterConfig) {
if (resourceFilterConfig.workspaceFolderValue) {
target = ConfigurationTarget.WorkspaceFolder;
} else if (resourceFilterConfig.workspaceValue) {
target = ConfigurationTarget.Workspace;
} else if (resourceFilterConfig.globalValue) {
target = ConfigurationTarget.Global;
}
}
await azureConfig.update('resourceFilter', resourceFilter.length ? resourceFilter : undefined, target);
}
private async updateFilters(configChange = false) {
const azureConfig = workspace.getConfiguration('azure');
let resourceFilter = azureConfig.get<string[]>('resourceFilter');
if (configChange && JSON.stringify(resourceFilter) === this.oldResourceFilter) {
return;
}
this.oldResourceFilter = JSON.stringify(resourceFilter);
if (resourceFilter && !Array.isArray(resourceFilter)) {
resourceFilter = [];
}
const filters = resourceFilter && resourceFilter.map(s => typeof s === 'string' ? s.split('/') : [])
.filter(s => s.length === 2 || s.length === 3)
.map(([tenantId, subscriptionId, resourceGroup]) => ({ tenantId, subscriptionId, resourceGroup }));
const tenantIds = filters && filters.reduce<Record<string, Record<string, Record<string, boolean> | boolean>>>((result, filter) => {
const tenant = result[filter.tenantId] || (result[filter.tenantId] = {});
const resourceGroups = tenant[filter.subscriptionId] || (tenant[filter.subscriptionId] = (filter.resourceGroup ? {} : true));
if (typeof resourceGroups === 'object' && filter.resourceGroup) {
resourceGroups[filter.resourceGroup] = true;
}
return result;
}, {});
const newFilters: AzureResourceFilter[] = [];
const sessions = tenantIds ? this.api.sessions.filter(session => tenantIds[session.tenantId]) : this.api.sessions;
for (const session of sessions) {
const client = new SubscriptionClient(session.credentials);
const subscriptionIds = tenantIds && tenantIds[session.tenantId];
const subscriptions = await listAll(client.subscriptions, client.subscriptions.list());
const filteredSubscriptions = subscriptionIds ? subscriptions.filter(subscription => subscriptionIds[subscription.subscriptionId!]) : subscriptions;
for (const subscription of filteredSubscriptions) {
const client = new ResourceManagementClient(session.credentials, subscription.subscriptionId!);
const resourceGroupNames = subscriptionIds && subscriptionIds[subscription.subscriptionId!];
const allResourceGroups = !(resourceGroupNames && typeof resourceGroupNames === 'object');
const unfilteredResourceGroups = await listAll(client.resourceGroups, client.resourceGroups.list());
const resourceGroups = allResourceGroups ? unfilteredResourceGroups : unfilteredResourceGroups.filter(resourceGroup => (<Record<string, boolean>>resourceGroupNames!)[resourceGroup.name!]);
newFilters.push({ session, subscription, allResourceGroups, resourceGroups });
}
}
this.api.filters.splice(0, this.api.filters.length, ...newFilters);
this.onFiltersChanged.fire();
}
}
async function deviceLogin1(): Promise<DeviceLogin> {
return new Promise<DeviceLogin>((resolve, reject) => {
const cache = new MemoryCache();
const context = new AuthenticationContext(authorityUrl, null, cache);
context.acquireUserCode(resource, clientId, 'en-us', function (err: any, response: any) {
if (err) {
reject(new AzureLoginError(localize('azure-account.userCodeFailed', "Aquiring user code failed"), err));
} else {
resolve(response);
}
});
});
}
async function deviceLogin2(deviceLogin: DeviceLogin) {
return new Promise<TokenResponse>((resolve, reject) => {
const tokenCache = new MemoryCache();
const context = new AuthenticationContext(authorityUrl, null, tokenCache);
context.acquireTokenWithDeviceCode(resource, clientId, deviceLogin, function (err: any, tokenResponse: TokenResponse) {
if (err) {
reject(new AzureLoginError(localize('azure-account.tokenFailed', "Aquiring token with device code"), err));
} else {
resolve(tokenResponse);
}
});
});
}
async function tokenFromRefreshToken(refreshToken: string, tenantId = commonTenantId) {
return new Promise<TokenResponse>((resolve, reject) => {
const tokenCache = new MemoryCache();
const context = new AuthenticationContext(`${authorityHostUrl}${tenantId}`, null, tokenCache);
context.acquireTokenWithRefreshToken(refreshToken, clientId, null, function (err: any, tokenResponse: TokenResponse) {
if (err) {
reject(new AzureLoginError(localize('azure-account.tokenFromRefreshTokenFailed', "Aquiring token with refresh token"), err));
} else {
resolve(tokenResponse);
}
});
});
}
async function tokensFromToken(firstTokenResponse: TokenResponse) {
const tokenResponses = [firstTokenResponse];
const tokenCache = new MemoryCache();
await addTokenToCache(tokenCache, firstTokenResponse);
const credentials = new DeviceTokenCredentials({ username: firstTokenResponse.userId, clientId, tokenCache });
const client = new SubscriptionClient(credentials);
const tenants = await listAll(client.tenants, client.tenants.list());
for (const tenant of tenants) {
if (tenant.tenantId !== firstTokenResponse.tenantId) {
const tokenResponse = await tokenFromRefreshToken(firstTokenResponse.refreshToken, tenant.tenantId);
tokenResponses.push(tokenResponse);
}
}
return tokenResponses;
}
async function addTokenToCache(tokenCache: any, tokenResponse: TokenResponse) {
return new Promise<any>((resolve, reject) => {
const driver = new CacheDriver(
{ _logContext: createLogContext('') },
`${authorityHostUrl}${tokenResponse.tenantId}`,
tokenResponse.resource,
clientId,
tokenCache,
(entry: any, resource: any, callback: (err: any, response: any) => {}) => {
callback(null, entry);
}
);
driver.add(tokenResponse, function (err: any) {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}
async function clearTokenCache(tokenCache: any) {
await new Promise<void>((resolve, reject) => {
tokenCache.find({}, (err: any, entries: any[]) => {
if (err) {
reject(err);
} else {
tokenCache.remove(entries, (err: any) => {
if (err) {
reject(err);
} else {
resolve();
}
});
}
});
});
}
export interface PartialList<T> extends Array<T> {
nextLink?: string;
}
export async function listAll<T>(client: { listNext(nextPageLink: string): Promise<PartialList<T>>; }, first: Promise<PartialList<T>>): Promise<T[]> {
const all: T[] = [];
for (let list = await first; list.length || list.nextLink; list = list.nextLink ? await client.listNext(list.nextLink) : []) {
all.push(...list);
}
return all;
}

View file

@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { window, ExtensionContext, commands, credentials } from 'vscode';
import { AzureLoginHelper } from './azure-account';
import { AzureAccount } from './typings/azure-account.api';
import * as opn from 'opn';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
export function activate(context: ExtensionContext) {
if (!credentials) {
return; // Proposed API not available.
}
const azureLogin = new AzureLoginHelper(context);
const subscriptions = context.subscriptions;
subscriptions.push(createStatusBarItem(azureLogin.api));
subscriptions.push(commands.registerCommand('azure-account.createAccount', createAccount));
return azureLogin.api;
}
function createAccount() {
opn('https://azure.microsoft.com/en-us/free');
}
function createStatusBarItem(api: AzureAccount) {
const statusBarItem = window.createStatusBarItem();
function updateStatusBar() {
switch (api.status) {
case 'LoggingIn':
statusBarItem.text = localize('azure-account.loggingIn', "Azure: Logging in...");
statusBarItem.show();
break;
case 'LoggedIn':
statusBarItem.text = localize('azure-account.loggedIn', "Azure: {0}", api.sessions[0].userId);
statusBarItem.show();
break;
default:
statusBarItem.hide();
break;
}
}
api.onStatusChanged(updateStatusBar);
api.onSessionsChanged(updateStatusBar);
updateStatusBar();
return statusBarItem;
}
export function deactivate() {
}

View file

@ -0,0 +1,41 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vscode';
import { ServiceClientCredentials } from 'ms-rest';
import { AzureEnvironment } from 'ms-rest-azure';
import { SubscriptionModels, ResourceModels } from 'azure-arm-resource';
export type AzureLoginStatus = 'Initializing' | 'LoggingIn' | 'LoggedIn' | 'LoggedOut';
export interface AzureAccount {
readonly status: AzureLoginStatus;
readonly onStatusChanged: Event<AzureLoginStatus>;
readonly sessions: AzureSession[];
readonly onSessionsChanged: Event<void>;
readonly filters: AzureResourceFilter[];
readonly onFiltersChanged: Event<void>;
readonly credentials: Credentials;
}
export interface AzureSession {
readonly environment: AzureEnvironment;
readonly userId: string;
readonly tenantId: string;
readonly credentials: ServiceClientCredentials;
}
export interface AzureResourceFilter {
readonly session: AzureSession;
readonly subscription: SubscriptionModels.Subscription;
readonly allResourceGroups: boolean;
readonly resourceGroups: ResourceModels.ResourceGroup[];
}
export interface Credentials {
readSecret(service: string, account: string): Thenable<string | undefined>;
writeSecret(service: string, account: string, secret: string): Thenable<void>;
deleteSecret(service: string, account: string): Thenable<boolean>;
}

View file

@ -0,0 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/// <reference path='../../../../src/vs/vscode.d.ts'/>

View file

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// This is the place for API experiments and proposal.
declare module 'vscode' {
/**
* Namespace for handling credentials.
*/
export namespace credentials {
/**
* Read a previously stored secret from the credential store.
*
* @param service The service of the credential.
* @param account The account of the credential.
* @return A promise for the secret of the credential.
*/
export function readSecret(service: string, account: string): Thenable<string | undefined>;
/**
* Write a secret to the credential store.
*
* @param service The service of the credential.
* @param account The account of the credential.
* @param secret The secret of the credential to write to the credential store.
* @return A promise indicating completion of the operation.
*/
export function writeSecret(service: string, account: string, secret: string): Thenable<void>;
/**
* Delete a previously stored secret from the credential store.
*
* @param service The service of the credential.
* @param account The account of the credential.
* @return A promise resolving to true if there was a secret for that service and account.
*/
export function deleteSecret(service: string, account: string): Thenable<boolean>;
}
}

View file

@ -0,0 +1,19 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"strict": true,
"noUnusedLocals": true,
"outDir": "./out",
"lib": [
"es6"
],
"sourceMap": true
},
"exclude": [
"node_modules"
],
"include": [
"src/**/*"
]
}

View file

@ -9,6 +9,7 @@ import * as path from 'path';
import { languages, window, commands, workspace, ExtensionContext } from 'vscode';
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, Range, TextEdit } from 'vscode-languageclient';
import { activateColorDecorations, ColorProvider } from './colorDecorators';
import { ConfigurationFeature } from 'vscode-languageclient/lib/proposed';
import * as nls from 'vscode-nls';
let localize = nls.loadMessageBundle();
@ -23,7 +24,7 @@ export function activate(context: ExtensionContext) {
// The server is implemented in node
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'cssServerMain.js'));
// The debug options for the server
let debugOptions = { execArgv: ['--nolazy', '--debug=6004'] };
let debugOptions = { execArgv: ['--nolazy', '--inspect=6004'] };
// If the extension is launch in debug mode the debug server options are use
// Otherwise the run options are used
@ -44,6 +45,7 @@ export function activate(context: ExtensionContext) {
// Create the language client and start the client.
let client = new LanguageClient('css', localize('cssserver.name', 'CSS Language Server'), serverOptions, clientOptions);
client.registerFeature(new ConfigurationFeature(client));
let disposable = client.start();
// Push the disposable to the context's subscriptions so that the

View file

@ -13,19 +13,19 @@
"resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz"
},
"vscode-jsonrpc": {
"version": "3.2.0",
"from": "vscode-jsonrpc@>=3.2.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.2.0.tgz"
"version": "3.3.1",
"from": "vscode-jsonrpc@>=3.3.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.3.1.tgz"
},
"vscode-languageclient": {
"version": "3.2.0",
"from": "vscode-languageclient@3.2.0",
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.2.0.tgz"
"version": "3.4.0-next.10",
"from": "vscode-languageclient@next",
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.4.0-next.10.tgz"
},
"vscode-languageserver-types": {
"version": "3.2.0",
"from": "vscode-languageserver-types@>=3.2.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.2.0.tgz"
"version": "3.3.0",
"from": "vscode-languageserver-types@>=3.3.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.3.0.tgz"
},
"vscode-nls": {
"version": "2.0.2",

View file

@ -62,16 +62,19 @@
"properties": {
"css.validate": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%css.validate.desc%"
},
"css.colorDecorators.enable": {
"type": "boolean",
"scope": "window",
"default": true,
"description": "%css.colorDecorators.enable.desc%"
},
"css.lint.compatibleVendorPrefixes": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -82,6 +85,7 @@
},
"css.lint.vendorPrefix": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -92,6 +96,7 @@
},
"css.lint.duplicateProperties": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -102,6 +107,7 @@
},
"css.lint.emptyRules": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -112,6 +118,7 @@
},
"css.lint.importStatement": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -122,6 +129,7 @@
},
"css.lint.boxModel": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -132,6 +140,7 @@
},
"css.lint.universalSelector": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -142,6 +151,7 @@
},
"css.lint.zeroUnits": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -152,6 +162,7 @@
},
"css.lint.fontFaceProperties": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -162,6 +173,7 @@
},
"css.lint.hexColorLength": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -172,6 +184,7 @@
},
"css.lint.argumentsInColorFunction": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -182,6 +195,7 @@
},
"css.lint.unknownProperties": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -192,6 +206,7 @@
},
"css.lint.ieHack": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -202,6 +217,7 @@
},
"css.lint.unknownVendorSpecificProperties": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -212,6 +228,7 @@
},
"css.lint.propertyIgnoredDueToDisplay": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -222,6 +239,7 @@
},
"css.lint.important": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -232,6 +250,7 @@
},
"css.lint.float": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -242,6 +261,7 @@
},
"css.lint.idSelector": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -252,6 +272,7 @@
},
"css.trace.server": {
"type": "string",
"scope": "window",
"enum": [
"off",
"messages",
@ -274,16 +295,19 @@
"properties": {
"scss.validate": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%scss.validate.desc%"
},
"scss.colorDecorators.enable": {
"type": "boolean",
"scope": "window",
"default": true,
"description": "%scss.colorDecorators.enable.desc%"
},
"scss.lint.compatibleVendorPrefixes": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -294,6 +318,7 @@
},
"scss.lint.vendorPrefix": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -304,6 +329,7 @@
},
"scss.lint.duplicateProperties": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -314,6 +340,7 @@
},
"scss.lint.emptyRules": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -324,6 +351,7 @@
},
"scss.lint.importStatement": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -334,6 +362,7 @@
},
"scss.lint.boxModel": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -344,6 +373,7 @@
},
"scss.lint.universalSelector": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -354,6 +384,7 @@
},
"scss.lint.zeroUnits": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -364,6 +395,7 @@
},
"scss.lint.fontFaceProperties": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -374,6 +406,7 @@
},
"scss.lint.hexColorLength": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -384,6 +417,7 @@
},
"scss.lint.argumentsInColorFunction": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -394,6 +428,7 @@
},
"scss.lint.unknownProperties": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -404,6 +439,7 @@
},
"scss.lint.ieHack": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -414,6 +450,7 @@
},
"scss.lint.unknownVendorSpecificProperties": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -424,6 +461,7 @@
},
"scss.lint.propertyIgnoredDueToDisplay": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -434,6 +472,7 @@
},
"scss.lint.important": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -444,6 +483,7 @@
},
"scss.lint.float": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -454,6 +494,7 @@
},
"scss.lint.idSelector": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -477,16 +518,19 @@
"properties": {
"less.validate": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%less.validate.desc%"
},
"less.colorDecorators.enable": {
"type": "boolean",
"scope": "window",
"default": true,
"description": "%less.colorDecorators.enable.desc%"
},
"less.lint.compatibleVendorPrefixes": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -497,6 +541,7 @@
},
"less.lint.vendorPrefix": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -507,6 +552,7 @@
},
"less.lint.duplicateProperties": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -517,6 +563,7 @@
},
"less.lint.emptyRules": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -527,6 +574,7 @@
},
"less.lint.importStatement": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -537,6 +585,7 @@
},
"less.lint.boxModel": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -547,6 +596,7 @@
},
"less.lint.universalSelector": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -557,6 +607,7 @@
},
"less.lint.zeroUnits": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -567,6 +618,7 @@
},
"less.lint.fontFaceProperties": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -577,6 +629,7 @@
},
"less.lint.hexColorLength": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -587,6 +640,7 @@
},
"less.lint.argumentsInColorFunction": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -597,6 +651,7 @@
},
"less.lint.unknownProperties": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -607,6 +662,7 @@
},
"less.lint.ieHack": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -617,6 +673,7 @@
},
"less.lint.unknownVendorSpecificProperties": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -627,6 +684,7 @@
},
"less.lint.propertyIgnoredDueToDisplay": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -637,6 +695,7 @@
},
"less.lint.important": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -647,6 +706,7 @@
},
"less.lint.float": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -657,6 +717,7 @@
},
"less.lint.idSelector": {
"type": "string",
"scope": "resource",
"enum": [
"ignore",
"warning",
@ -674,10 +735,10 @@
},
"dependencies": {
"parse-color": "^1.0.0",
"vscode-languageclient": "^3.2.0",
"vscode-languageclient": "3.4.0-next.10",
"vscode-nls": "^2.0.2"
},
"devDependencies": {
"@types/node": "^6.0.51"
}
}
}

View file

@ -3,29 +3,34 @@
"version": "1.0.0",
"dependencies": {
"vscode-css-languageservice": {
"version": "2.1.2",
"version": "2.1.3",
"from": "vscode-css-languageservice@next",
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.1.2.tgz"
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.1.3.tgz"
},
"vscode-jsonrpc": {
"version": "3.2.0",
"from": "vscode-jsonrpc@>=3.2.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.2.0.tgz"
"version": "3.3.1",
"from": "vscode-jsonrpc@>=3.3.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.3.1.tgz"
},
"vscode-languageserver": {
"version": "3.2.0",
"from": "vscode-languageserver@3.2.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.2.0.tgz"
"version": "3.4.0-next.4",
"from": "vscode-languageserver@next",
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.4.0-next.4.tgz"
},
"vscode-languageserver-types": {
"version": "3.2.0",
"from": "vscode-languageserver-types@>=3.2.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.2.0.tgz"
"version": "3.3.0",
"from": "vscode-languageserver-types@>=3.3.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.3.0.tgz"
},
"vscode-nls": {
"version": "2.0.2",
"from": "vscode-nls@>=2.0.1 <3.0.0",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz"
},
"vscode-uri": {
"version": "1.0.1",
"from": "vscode-uri@>=1.0.1 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.1.tgz"
}
}
}

View file

@ -8,8 +8,8 @@
"node": "*"
},
"dependencies": {
"vscode-css-languageservice": "^2.1.2",
"vscode-languageserver": "^3.2.0"
"vscode-css-languageservice": "^2.1.3",
"vscode-languageserver": "3.4.0-next.4"
},
"devDependencies": {
"@types/node": "^6.0.51"

View file

@ -8,6 +8,7 @@ import {
createConnection, IConnection, Range,
TextDocuments, TextDocument, InitializeParams, InitializeResult, RequestType
} from 'vscode-languageserver';
import { GetConfigurationRequest } from 'vscode-languageserver/lib/protocol.proposed';
import { getCSSLanguageService, getSCSSLanguageService, getLESSLanguageService, LanguageSettings, LanguageService, Stylesheet } from 'vscode-css-languageservice';
import { getLanguageModelCache } from './languageModelCache';
@ -43,10 +44,20 @@ connection.onShutdown(() => {
stylesheets.dispose();
});
let scopedSettingsSupport = false;
// After the server has started the client sends an initilize request. The server receives
// in the passed params the rootPath of the workspace plus the client capabilities.
connection.onInitialize((params: InitializeParams): InitializeResult => {
let snippetSupport = params.capabilities && params.capabilities.textDocument && params.capabilities.textDocument.completion && params.capabilities.textDocument.completion.completionItem && params.capabilities.textDocument.completion.completionItem.snippetSupport;
function hasClientCapability(name: string) {
let keys = name.split('.');
let c = params.capabilities;
for (let i = 0; c && i < keys.length; i++) {
c = c[keys[i]];
}
return !!c;
}
let snippetSupport = hasClientCapability('textDocument.completion.completionItem.snippetSupport');
scopedSettingsSupport = hasClientCapability('workspace.configuration');
return {
capabilities: {
// Tell the client that the server works in FULL text document sync mode
@ -78,6 +89,20 @@ function getLanguageService(document: TextDocument) {
return service;
}
let documentSettings: { [key: string]: Thenable<LanguageSettings> } = {};
function getDocumentSettings(textDocument: TextDocument): Thenable<LanguageSettings> {
if (scopedSettingsSupport) {
let promise = documentSettings[textDocument.uri];
if (!promise) {
let configRequestParam = { items: [{ scopeUri: textDocument.uri, section: textDocument.languageId }] };
promise = connection.sendRequest(GetConfigurationRequest.type, configRequestParam).then(s => s[0]);
documentSettings[textDocument.uri] = promise;
}
return promise;
}
return void 0;
}
// The settings have changed. Is send on server activation as well.
connection.onDidChangeConfiguration(change => {
updateConfiguration(<Settings>change.settings);
@ -87,6 +112,8 @@ function updateConfiguration(settings: Settings) {
for (let languageId in languageServices) {
languageServices[languageId].configure(settings[languageId]);
}
// reset all document settings
documentSettings = {};
// Revalidate any open text documents
documents.all().forEach(triggerValidation);
}
@ -123,10 +150,13 @@ function triggerValidation(textDocument: TextDocument): void {
}
function validateTextDocument(textDocument: TextDocument): void {
let settingsPromise = getDocumentSettings(textDocument);
let stylesheet = stylesheets.get(textDocument);
let diagnostics = getLanguageService(textDocument).doValidation(textDocument, stylesheet);
// Send the computed diagnostics to VSCode.
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
settingsPromise.then(settings => {
let diagnostics = getLanguageService(textDocument).doValidation(textDocument, stylesheet, settings);
// Send the computed diagnostics to VSCode.
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
});
}
connection.onCompletion(textDocumentPosition => {

View file

@ -4,8 +4,8 @@
"dependencies": {
"@emmetio/css-parser": {
"version": "0.4.0",
"from": "@emmetio/css-parser@>=0.4.0 <0.5.0",
"resolved": "https://registry.npmjs.org/@emmetio/css-parser/-/css-parser-0.4.0.tgz"
"from": "ramya-rao-a/css-parser#vscode",
"resolved": "git://github.com/ramya-rao-a/css-parser.git#370c480ac103bd17c7bcfb34bf5d577dc40d3660"
},
"@emmetio/extract-abbreviation": {
"version": "0.1.3",
@ -38,9 +38,9 @@
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz"
},
"vscode-emmet-helper": {
"version": "1.0.16",
"from": "vscode-emmet-helper@>=1.0.16 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-emmet-helper/-/vscode-emmet-helper-1.0.16.tgz"
"version": "1.0.17",
"from": "vscode-emmet-helper@>=1.0.17 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-emmet-helper/-/vscode-emmet-helper-1.0.17.tgz"
},
"vscode-languageserver-types": {
"version": "3.3.0",

View file

@ -210,9 +210,9 @@
"dependencies": {
"@emmetio/html-matcher": "^0.3.1",
"@emmetio/css-parser": "^0.4.0",
"@emmetio/css-parser": "ramya-rao-a/css-parser#vscode",
"@emmetio/math-expression": "^0.1.1",
"vscode-emmet-helper": "^1.0.16",
"vscode-emmet-helper": "^1.0.17",
"vscode-languageserver-types": "^3.0.3",
"image-size": "^0.5.2",
"vscode-nls": "2.0.2"

View file

@ -95,10 +95,7 @@ export function expandEmmetAbbreviation(args): Thenable<boolean> {
const editor = vscode.window.activeTextEditor;
let rootNode = parseDocument(editor.document);
if (!rootNode) {
return fallbackTab();
}
let rootNode = parseDocument(editor.document, false);
// When tabbed on a non empty selection, do not treat it as an emmet abbreviation, and fallback to tab instead
if (vscode.workspace.getConfiguration('emmet')['triggerExpansionOnTab'] === true && editor.selections.find(x => !x.isEmpty)) {

View file

@ -72,9 +72,13 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi
const currentHtmlNode = <HtmlNode>currentNode;
if (currentHtmlNode
&& currentHtmlNode.close
&& currentHtmlNode.name === 'style'
&& getInnerRange(currentHtmlNode).contains(position)) {
return 'css';
if (currentHtmlNode.name === 'style') {
return 'css';
}
if (currentHtmlNode.name === 'script') {
return;
}
}
}

View file

@ -16,7 +16,7 @@ export const LANGUAGE_MODES: Object = {
'slim': ['!', '.', '}', ':', '*', '$'],
'haml': ['!', '.', '}', ':', '*', '$'],
'xml': ['.', '}', '*', '$'],
'xsl': ['.', '}', '*', '$'],
'xsl': ['!', '.', '}', '*', '$'],
'css': [':'],
'scss': [':'],
'sass': [':'],
@ -83,6 +83,10 @@ export function parseDocument(document: vscode.TextDocument, showError: boolean
* @param includeNodeBoundary
*/
export function getNode(root: Node, position: vscode.Position, includeNodeBoundary: boolean = false) {
if (!root) {
return null;
}
let currentNode = root.firstChild;
let foundNode: Node = null;

View file

@ -5,7 +5,7 @@
'use strict';
import { Uri, commands, scm, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn } from 'vscode';
import { Uri, commands, scm, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation } from 'vscode';
import { Ref, RefType, Git, GitErrorCodes, Branch } from './git';
import { Model, Resource, Status, CommitOptions, WorkingTreeGroup, IndexGroup, MergeGroup } from './model';
import { toGitUri, fromGitUri } from './uri';
@ -278,9 +278,12 @@ export class CommandCenter {
}
const clonePromise = this.git.clone(url, parentPath);
window.setStatusBarMessage(localize('cloning', "Cloning git repository..."), clonePromise);
try {
window.withProgress({ location: ProgressLocation.SourceControl, title: localize('cloning', "Cloning git repository...") }, () => clonePromise);
window.withProgress({ location: ProgressLocation.Window, title: localize('cloning', "Cloning git repository...") }, () => clonePromise);
const repositoryPath = await clonePromise;
const open = localize('openrepo', "Open Repository");

View file

@ -12,6 +12,8 @@ import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared';
import { activateColorDecorations } from './colorDecorators';
import TelemetryReporter from 'vscode-extension-telemetry';
import { ConfigurationFeature } from 'vscode-languageclient/lib/proposed';
import * as nls from 'vscode-nls';
let localize = nls.loadMessageBundle();
@ -34,7 +36,7 @@ export function activate(context: ExtensionContext) {
// The server is implemented in node
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'htmlServerMain.js'));
// The debug options for the server
let debugOptions = { execArgv: ['--nolazy', '--debug=6004'] };
let debugOptions = { execArgv: ['--nolazy', '--inspect=6004'] };
// If the extension is launch in debug mode the debug server options are use
// Otherwise the run options are used
@ -59,6 +61,8 @@ export function activate(context: ExtensionContext) {
// Create the language client and start the client.
let client = new LanguageClient('html', localize('htmlserver.name', 'HTML Language Server'), serverOptions, clientOptions);
client.registerFeature(new ConfigurationFeature(client));
let disposable = client.start();
context.subscriptions.push(disposable);
client.onReady().then(() => {

View file

@ -8,24 +8,24 @@
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz"
},
"vscode-extension-telemetry": {
"version": "0.0.7",
"version": "0.0.8",
"from": "vscode-extension-telemetry@>=0.0.8 <0.0.9",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz"
},
"vscode-jsonrpc": {
"version": "3.1.0-alpha.1",
"from": "vscode-jsonrpc@>=3.1.0-alpha.1 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.1.0-alpha.1.tgz"
"version": "3.3.1",
"from": "vscode-jsonrpc@>=3.3.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.3.1.tgz"
},
"vscode-languageclient": {
"version": "3.1.0-alpha.1",
"version": "3.4.0-next.10",
"from": "vscode-languageclient@next",
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.1.0-alpha.1.tgz"
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.4.0-next.10.tgz"
},
"vscode-languageserver-types": {
"version": "3.0.3",
"from": "vscode-languageserver-types@>=3.0.2-beta.5 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.0.3.tgz"
"version": "3.3.0",
"from": "vscode-languageserver-types@>=3.3.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.3.0.tgz"
},
"vscode-nls": {
"version": "2.0.2",
@ -38,4 +38,4 @@
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.3.tgz"
}
}
}
}

View file

@ -75,11 +75,13 @@
"properties": {
"html.format.enable": {
"type": "boolean",
"scope": "window",
"default": true,
"description": "%html.format.enable.desc%"
},
"html.format.wrapLineLength": {
"type": "integer",
"scope": "resource",
"default": 120,
"description": "%html.format.wrapLineLength.desc%"
},
@ -88,6 +90,7 @@
"string",
"null"
],
"scope": "resource",
"default": "a, abbr, acronym, b, bdo, big, br, button, cite, code, dfn, em, i, img, input, kbd, label, map, object, q, samp, select, small, span, strong, sub, sup, textarea, tt, var",
"description": "%html.format.unformatted.desc%"
},
@ -96,16 +99,19 @@
"string",
"null"
],
"scope": "resource",
"default": "pre",
"description": "%html.format.contentUnformatted.desc%"
},
"html.format.indentInnerHtml": {
"type": "boolean",
"scope": "resource",
"default": false,
"description": "%html.format.indentInnerHtml.desc%"
},
"html.format.preserveNewLines": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%html.format.preserveNewLines.desc%"
},
@ -114,16 +120,19 @@
"number",
"null"
],
"scope": "resource",
"default": null,
"description": "%html.format.maxPreserveNewLines.desc%"
},
"html.format.indentHandlebars": {
"type": "boolean",
"scope": "resource",
"default": false,
"description": "%html.format.indentHandlebars.desc%"
},
"html.format.endWithNewline": {
"type": "boolean",
"scope": "resource",
"default": false,
"description": "%html.format.endWithNewline.desc%"
},
@ -132,11 +141,13 @@
"string",
"null"
],
"scope": "resource",
"default": "head, body, /html",
"description": "%html.format.extraLiners.desc%"
},
"html.format.wrapAttributes": {
"type": "string",
"scope": "resource",
"default": "auto",
"enum": [
"auto",
@ -154,31 +165,37 @@
},
"html.suggest.angular1": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%html.suggest.angular1.desc%"
},
"html.suggest.ionic": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%html.suggest.ionic.desc%"
},
"html.suggest.html5": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%html.suggest.html5.desc%"
},
"html.validate.scripts": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%html.validate.scripts%"
},
"html.validate.styles": {
"type": "boolean",
"scope": "resource",
"default": true,
"description": "%html.validate.styles%"
},
"html.trace.server": {
"type": "string",
"scope": "window",
"enum": [
"off",
"messages",
@ -192,12 +209,12 @@
},
"dependencies": {
"vscode-extension-telemetry": "0.0.8",
"vscode-languageclient": "3.1.0-alpha.1",
"vscode-languageserver-types": "3.0.3",
"vscode-languageclient": "3.4.0-next.10",
"vscode-languageserver-types": "^3.3.0",
"vscode-nls": "2.0.2"
},
"devDependencies": {
"@types/node": "^6.0.51",
"@types/mocha": "^2.2.33"
}
}
}

View file

@ -3,16 +3,9 @@
"version": "1.0.0",
"dependencies": {
"vscode-css-languageservice": {
"version": "2.1.0",
"version": "2.1.3",
"from": "vscode-css-languageservice@next",
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.1.0.tgz",
"dependencies": {
"vscode-languageserver-types": {
"version": "3.2.0",
"from": "vscode-languageserver-types@>=3.2.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.2.0.tgz"
}
}
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.1.3.tgz"
},
"vscode-html-languageservice": {
"version": "2.0.5",
@ -20,19 +13,19 @@
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-2.0.5.tgz"
},
"vscode-jsonrpc": {
"version": "3.1.0-alpha.1",
"from": "vscode-jsonrpc@>=3.1.0-alpha.1 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.1.0-alpha.1.tgz"
"version": "3.3.1",
"from": "vscode-jsonrpc@>=3.3.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.3.1.tgz"
},
"vscode-languageserver": {
"version": "3.1.0-alpha.1",
"version": "3.4.0-next.4",
"from": "vscode-languageserver@next",
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.1.0-alpha.1.tgz"
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.4.0-next.4.tgz"
},
"vscode-languageserver-types": {
"version": "3.0.3",
"from": "vscode-languageserver-types@>=3.0.3 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.0.3.tgz"
"version": "3.3.0",
"from": "vscode-languageserver-types@>=3.3.0 <4.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.3.0.tgz"
},
"vscode-nls": {
"version": "2.0.2",
@ -40,9 +33,9 @@
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz"
},
"vscode-uri": {
"version": "1.0.0",
"from": "vscode-uri@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.0.tgz"
"version": "1.0.1",
"from": "vscode-uri@latest",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.1.tgz"
}
}
}

View file

@ -8,11 +8,12 @@
"node": "*"
},
"dependencies": {
"vscode-css-languageservice": "^2.1.0",
"vscode-css-languageservice": "^2.1.3",
"vscode-html-languageservice": "^2.0.5",
"vscode-languageserver": "^3.1.0-alpha.1",
"vscode-languageserver": "3.4.0-next.4",
"vscode-languageserver-types": "^3.3.0",
"vscode-nls": "^2.0.2",
"vscode-uri": "^1.0.0"
"vscode-uri": "^1.0.1"
},
"devDependencies": {
"@types/node": "^6.0.51",
@ -25,6 +26,6 @@
"install-service-local": "npm install ../../../../vscode-css-languageservice -f -S && npm install ../../../../vscode-html-languageservice -f -S",
"install-server-next": "npm install vscode-languageserver@next -f -S",
"install-server-local": "npm install ../../../../vscode-languageserver-node/server -f -S",
"test": "mocha"
"test": "../../../node_modules/.bin/mocha"
}
}

View file

@ -4,10 +4,12 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, RequestType, DocumentRangeFormattingRequest, Disposable, DocumentSelector } from 'vscode-languageserver';
import { createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, RequestType, DocumentRangeFormattingRequest, Disposable, DocumentSelector, GetConfigurationParams } from 'vscode-languageserver';
import { DocumentContext } from 'vscode-html-languageservice';
import { TextDocument, Diagnostic, DocumentLink, Range, SymbolInformation } from 'vscode-languageserver-types';
import { getLanguageModes, LanguageModes } from './modes/languageModes';
import { getLanguageModes, LanguageModes, Settings } from './modes/languageModes';
import { GetConfigurationRequest } from 'vscode-languageserver/lib/protocol.proposed';
import { format } from './modes/formatting';
import { pushAll } from './utils/arrays';
@ -38,10 +40,27 @@ documents.listen(connection);
let workspacePath: string;
var languageModes: LanguageModes;
var settings: any = {};
let clientSnippetSupport = false;
let clientDynamicRegisterSupport = false;
let scopedSettingsSupport = false;
var globalSettings: Settings = {};
let documentSettings: { [key: string]: Thenable<Settings> } = {};
function getDocumentSettings(textDocument: TextDocument, needsDocumentSettings: () => boolean): Thenable<Settings> {
if (scopedSettingsSupport && needsDocumentSettings()) {
let promise = documentSettings[textDocument.uri];
if (!promise) {
let scopeUri = textDocument.uri;
let configRequestParam: GetConfigurationParams = { items: [{ scopeUri, section: 'css' }, { scopeUri, section: 'html' }, { scopeUri, section: 'javascript' }] };
promise = connection.sendRequest(GetConfigurationRequest.type, configRequestParam).then(s => ({ css: s[0], html: s[1], javascript: s[2] }));
documentSettings[textDocument.uri] = promise;
}
return promise;
}
return Promise.resolve(void 0);
}
// After the server has started the client sends an initilize request. The server receives
// in the passed params the rootPath of the workspace plus the client capabilites
@ -68,6 +87,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
clientSnippetSupport = hasClientCapability('textDocument', 'completion', 'completionItem', 'snippetSupport');
clientDynamicRegisterSupport = hasClientCapability('workspace', 'symbol', 'dynamicRegistration');
scopedSettingsSupport = hasClientCapability('workspace', 'configuration');
return {
capabilities: {
// Tell the client that the server works in FULL text document sync mode
@ -85,21 +105,13 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
};
});
let validation = {
html: true,
css: true,
javascript: true
};
let formatterRegistration: Thenable<Disposable> = null;
// The settings have changed. Is send on server activation as well.
connection.onDidChangeConfiguration((change) => {
settings = change.settings;
let validationSettings = settings && settings.html && settings.html.validate || {};
validation.css = validationSettings.styles !== false;
validation.javascript = validationSettings.scripts !== false;
globalSettings = change.settings;
documentSettings = {}; // reset all document settings
languageModes.getAllModes().forEach(m => {
if (m.configure) {
m.configure(change.settings);
@ -109,7 +121,7 @@ connection.onDidChangeConfiguration((change) => {
// dynamically enable & disable the formatter
if (clientDynamicRegisterSupport) {
let enableFormatter = settings && settings.html && settings.html.format && settings.html.format.enable;
let enableFormatter = globalSettings && globalSettings.html && globalSettings.html.format && globalSettings.html.format.enable;
if (enableFormatter) {
if (!formatterRegistration) {
let documentSelector: DocumentSelector = [{ language: 'html' }, { language: 'handlebars' }]; // don't register razor, the formatter does more harm than good
@ -154,26 +166,37 @@ function triggerValidation(textDocument: TextDocument): void {
}, validationDelayMs);
}
function validateTextDocument(textDocument: TextDocument): void {
function isValidationEnabled(languageId: string, settings: Settings = globalSettings) {
let validationSettings = settings && settings.html && settings.html.validate;
if (validationSettings) {
return languageId === 'css' && validationSettings.styles !== false || languageId === 'javascript' && validationSettings.scripts !== false;
}
return true;
}
async function validateTextDocument(textDocument: TextDocument) {
let diagnostics: Diagnostic[] = [];
if (textDocument.languageId === 'html') {
languageModes.getAllModesInDocument(textDocument).forEach(mode => {
if (mode.doValidation && validation[mode.getId()]) {
pushAll(diagnostics, mode.doValidation(textDocument));
let modes = languageModes.getAllModesInDocument(textDocument);
let settings = await getDocumentSettings(textDocument, () => modes.some(m => m.doValidation && m.doValidation.length > 1));
modes.forEach(mode => {
if (mode.doValidation && isValidationEnabled(mode.getId(), settings)) {
pushAll(diagnostics, mode.doValidation(textDocument, settings));
}
});
}
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
}
connection.onCompletion(textDocumentPosition => {
connection.onCompletion(async textDocumentPosition => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, textDocumentPosition.position);
if (mode && mode.doComplete) {
if (mode.getId() !== 'html') {
connection.telemetry.logEvent({ key: 'html.embbedded.complete', value: { languageId: mode.getId() } });
}
return mode.doComplete(document, textDocumentPosition.position);
let settings = await getDocumentSettings(document, () => mode.doComplete.length > 2);
return mode.doComplete(document, textDocumentPosition.position, settings);
}
return { isIncomplete: true, items: [] };
});
@ -235,13 +258,16 @@ connection.onSignatureHelp(signatureHelpParms => {
return null;
});
connection.onDocumentRangeFormatting(formatParams => {
connection.onDocumentRangeFormatting(async formatParams => {
let document = documents.get(formatParams.textDocument.uri);
let settings = await getDocumentSettings(document, () => true);
if (!settings) {
settings = globalSettings;
}
let unformattedTags: string = settings && settings.html && settings.html.format && settings.html.format.unformatted || '';
let enabledModes = { css: !unformattedTags.match(/\bstyle\b/), javascript: !unformattedTags.match(/\bscript\b/) };
return format(languageModes, document, formatParams.range, formatParams.options, enabledModes);
return format(languageModes, document, formatParams.range, formatParams.options, settings, enabledModes);
});
connection.onDocumentLinks(documentLinkParam => {

View file

@ -7,7 +7,7 @@
import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache';
import { TextDocument, Position } from 'vscode-languageserver-types';
import { getCSSLanguageService, Stylesheet } from 'vscode-css-languageservice';
import { LanguageMode } from './languageModes';
import { LanguageMode, Settings } from './languageModes';
import { HTMLDocumentRegions, CSS_STYLE_RULE } from './embeddedSupport';
export function getCSSMode(documentRegions: LanguageModelCache<HTMLDocumentRegions>): LanguageMode {
@ -22,9 +22,9 @@ export function getCSSMode(documentRegions: LanguageModelCache<HTMLDocumentRegio
configure(options: any) {
cssLanguageService.configure(options && options.css);
},
doValidation(document: TextDocument) {
doValidation(document: TextDocument, settings: Settings) {
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.doValidation(embedded, cssStylesheets.get(embedded));
return cssLanguageService.doValidation(embedded, cssStylesheets.get(embedded), settings && settings.css);
},
doComplete(document: TextDocument, position: Position) {
let embedded = embeddedCSSDocuments.get(document);

View file

@ -6,11 +6,11 @@
import { applyEdits } from '../utils/edits';
import { TextDocument, Range, TextEdit, FormattingOptions, Position } from 'vscode-languageserver-types';
import { LanguageModes } from './languageModes';
import { LanguageModes, Settings } from './languageModes';
import { pushAll } from '../utils/arrays';
import { isEOL } from '../utils/strings';
export function format(languageModes: LanguageModes, document: TextDocument, formatRange: Range, formattingOptions: FormattingOptions, enabledModes: { [mode: string]: boolean }) {
export function format(languageModes: LanguageModes, document: TextDocument, formatRange: Range, formattingOptions: FormattingOptions, settings: Settings, enabledModes: { [mode: string]: boolean }) {
let result: TextEdit[] = [];
let endPos = formatRange.end;
@ -40,7 +40,7 @@ export function format(languageModes: LanguageModes, document: TextDocument, for
while (i < allRanges.length && allRanges[i].mode.getId() !== 'html') {
let range = allRanges[i];
if (!range.attributeValue && range.mode.format) {
let edits = range.mode.format(document, Range.create(startPos, range.end), formattingOptions);
let edits = range.mode.format(document, Range.create(startPos, range.end), formattingOptions, settings);
pushAll(result, edits);
}
startPos = range.end;
@ -54,7 +54,7 @@ export function format(languageModes: LanguageModes, document: TextDocument, for
// perform a html format and apply changes to a new document
let htmlMode = languageModes.getMode('html');
let htmlEdits = htmlMode.format(document, formatRange, formattingOptions);
let htmlEdits = htmlMode.format(document, formatRange, formattingOptions, settings);
let htmlFormattedContent = applyEdits(document, htmlEdits);
let newDocument = TextDocument.create(document.uri + '.tmp', document.languageId, document.version, htmlFormattedContent);
try {
@ -68,7 +68,7 @@ export function format(languageModes: LanguageModes, document: TextDocument, for
for (let r of embeddedRanges) {
let mode = r.mode;
if (mode && mode.format && enabledModes[mode.getId()] && !r.attributeValue) {
let edits = mode.format(newDocument, r, formattingOptions);
let edits = mode.format(newDocument, r, formattingOptions, settings);
for (let edit of edits) {
embeddedEdits.push(edit);
}

View file

@ -7,20 +7,20 @@
import { getLanguageModelCache } from '../languageModelCache';
import { LanguageService as HTMLLanguageService, HTMLDocument, DocumentContext, FormattingOptions } from 'vscode-html-languageservice';
import { TextDocument, Position, Range } from 'vscode-languageserver-types';
import { LanguageMode } from './languageModes';
import { LanguageMode, Settings } from './languageModes';
export function getHTMLMode(htmlLanguageService: HTMLLanguageService): LanguageMode {
let settings: any = {};
let globalSettings: Settings = {};
let htmlDocuments = getLanguageModelCache<HTMLDocument>(10, 60, document => htmlLanguageService.parseHTMLDocument(document));
return {
getId() {
return 'html';
},
configure(options: any) {
settings = options && options.html;
globalSettings = options;
},
doComplete(document: TextDocument, position: Position) {
let options = settings && settings.suggest;
doComplete(document: TextDocument, position: Position, settings: Settings = globalSettings) {
let options = settings && settings.html && settings.html.suggest;
return htmlLanguageService.doComplete(document, position, htmlDocuments.get(document), options);
},
doHover(document: TextDocument, position: Position) {
@ -35,8 +35,8 @@ export function getHTMLMode(htmlLanguageService: HTMLLanguageService): LanguageM
findDocumentSymbols(document: TextDocument) {
return htmlLanguageService.findDocumentSymbols(document, htmlDocuments.get(document));
},
format(document: TextDocument, range: Range, formatParams: FormattingOptions) {
let formatSettings = settings && settings.format;
format(document: TextDocument, range: Range, formatParams: FormattingOptions, settings: Settings = globalSettings) {
let formatSettings = settings && settings.html && settings.html.format;
if (!formatSettings) {
formatSettings = formatParams;
} else {

View file

@ -6,7 +6,7 @@
import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache';
import { SymbolInformation, SymbolKind, CompletionItem, Location, SignatureHelp, SignatureInformation, ParameterInformation, Definition, TextEdit, TextDocument, Diagnostic, DiagnosticSeverity, Range, CompletionItemKind, Hover, MarkedString, DocumentHighlight, DocumentHighlightKind, CompletionList, Position, FormattingOptions } from 'vscode-languageserver-types';
import { LanguageMode } from './languageModes';
import { LanguageMode, Settings } from './languageModes';
import { getWordAtText, startsWith, isWhitespaceOnly, repeat } from '../utils/strings';
import { HTMLDocumentRegions } from './embeddedSupport';
@ -60,14 +60,14 @@ export function getJavascriptMode(documentRegions: LanguageModelCache<HTMLDocume
};
let jsLanguageService = ts.createLanguageService(host);
let settings: any = {};
let globalSettings: Settings = {};
return {
getId() {
return 'javascript';
},
configure(options: any) {
settings = options && options.javascript;
globalSettings = options;
},
doValidation(document: TextDocument): Diagnostic[] {
updateCurrentTextDocument(document);
@ -242,12 +242,14 @@ export function getJavascriptMode(documentRegions: LanguageModelCache<HTMLDocume
}
return null;
},
format(document: TextDocument, range: Range, formatParams: FormattingOptions): TextEdit[] {
format(document: TextDocument, range: Range, formatParams: FormattingOptions, settings: Settings = globalSettings): TextEdit[] {
currentTextDocument = documentRegions.get(document).getEmbeddedDocument('javascript', true);
scriptFileVersion++;
let formatterSettings = settings && settings.javascript && settings.javascript.format;
let initialIndentLevel = computeInitialIndent(document, range, formatParams);
let formatSettings = convertOptions(formatParams, settings && settings.format, initialIndentLevel + 1);
let formatSettings = convertOptions(formatParams, formatterSettings, initialIndentLevel + 1);
let start = currentTextDocument.offsetAt(range.start);
let end = currentTextDocument.offsetAt(range.end);
let lastLineRange = null;

View file

@ -16,11 +16,21 @@ import { getCSSMode } from './cssMode';
import { getJavascriptMode } from './javascriptMode';
import { getHTMLMode } from './htmlMode';
export interface Settings {
css?: any;
html?: any;
javascript?: any;
}
export interface SettingProvider {
getDocumentSettings(textDocument: TextDocument): Thenable<Settings>;
}
export interface LanguageMode {
getId();
configure?: (options: any) => void;
doValidation?: (document: TextDocument) => Diagnostic[];
doComplete?: (document: TextDocument, position: Position) => CompletionList;
configure?: (options: Settings) => void;
doValidation?: (document: TextDocument, settings?: Settings) => Diagnostic[];
doComplete?: (document: TextDocument, position: Position, settings?: Settings) => CompletionList;
doResolve?: (document: TextDocument, item: CompletionItem) => CompletionItem;
doHover?: (document: TextDocument, position: Position) => Hover;
doSignatureHelp?: (document: TextDocument, position: Position) => SignatureHelp;
@ -29,7 +39,7 @@ export interface LanguageMode {
findDocumentLinks?: (document: TextDocument, documentContext: DocumentContext) => DocumentLink[];
findDefinition?: (document: TextDocument, position: Position) => Definition;
findReferences?: (document: TextDocument, position: Position) => Location[];
format?: (document: TextDocument, range: Range, options: FormattingOptions) => TextEdit[];
format?: (document: TextDocument, range: Range, options: FormattingOptions, settings: Settings) => TextEdit[];
findColorSymbols?: (document: TextDocument) => Range[];
onDocumentRemoved(document: TextDocument): void;
dispose(): void;

View file

@ -38,7 +38,7 @@ suite('HTML Embedded Formatting', () => {
formatOptions = FormattingOptions.create(2, true);
}
let result = format(languageModes, document, range, formatOptions, { css: true, javascript: true });
let result = format(languageModes, document, range, formatOptions, void 0, { css: true, javascript: true });
let actual = applyEdits(document, result);
assert.equal(actual, expected, message);

View file

@ -6,7 +6,7 @@
import * as assert from 'assert';
import { getJavascriptMode } from '../modes/javascriptMode';
import { TextDocument, Range, TextEdit, FormattingOptions } from 'vscode-languageserver-types';
import { TextDocument } from 'vscode-languageserver-types';
import { getLanguageModelCache } from '../languageModelCache';
import { getLanguageService } from 'vscode-html-languageservice';

View file

@ -68,7 +68,7 @@ const fencedCodeBlockDefinition = (name, identifiers, sourceScope) => {
return `<key>fenced_code_block_${name}</key>
<dict>
<key>begin</key>
<string>(^|\\G)(\\s*)(\`{3,}|~{3,})\\s*((${identifiers.join('|')})(\\s+[^\`~]*)?$)</string>
<string>(^|\\G)(\\s*)(\`{3,}|~{3,})\\s*(?i:(${identifiers.join('|')})(\\s+[^\`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>

View file

@ -588,7 +588,7 @@
<key>fenced_code_block_css</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((css|css.erb)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(css|css.erb)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -639,7 +639,7 @@
<key>fenced_code_block_basic</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((html|htm|shtml|xhtml|inc|tmpl|tpl)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(html|htm|shtml|xhtml|inc|tmpl|tpl)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -690,7 +690,7 @@
<key>fenced_code_block_ini</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((ini|conf)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(ini|conf)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -741,7 +741,7 @@
<key>fenced_code_block_java</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((java|bsh)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(java|bsh)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -792,7 +792,7 @@
<key>fenced_code_block_lua</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((lua)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(lua)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -843,7 +843,7 @@
<key>fenced_code_block_makefile</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((Makefile|makefile|GNUmakefile|OCamlMakefile)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(Makefile|makefile|GNUmakefile|OCamlMakefile)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -894,7 +894,7 @@
<key>fenced_code_block_perl</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((perl|pl|pm|pod|t|PL|psgi|vcl)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(perl|pl|pm|pod|t|PL|psgi|vcl)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -945,7 +945,7 @@
<key>fenced_code_block_r</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((R|r|s|S|Rprofile)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(R|r|s|S|Rprofile)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -996,7 +996,7 @@
<key>fenced_code_block_ruby</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((ruby|rb|rbx|rjs|Rakefile|rake|cgi|fcgi|gemspec|irbrc|Capfile|ru|prawn|Cheffile|Gemfile|Guardfile|Hobofile|Vagrantfile|Appraisals|Rantfile|Berksfile|Berksfile.lock|Thorfile|Puppetfile)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(ruby|rb|rbx|rjs|Rakefile|rake|cgi|fcgi|gemspec|irbrc|Capfile|ru|prawn|Cheffile|Gemfile|Guardfile|Hobofile|Vagrantfile|Appraisals|Rantfile|Berksfile|Berksfile.lock|Thorfile|Puppetfile)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1047,7 +1047,7 @@
<key>fenced_code_block_php</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((php|php3|php4|php5|phpt|phtml|aw|ctp)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(php|php3|php4|php5|phpt|phtml|aw|ctp)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1102,7 +1102,7 @@
<key>fenced_code_block_sql</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((sql|ddl|dml)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(sql|ddl|dml)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1153,7 +1153,7 @@
<key>fenced_code_block_vs_net</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((vb)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(vb)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1204,7 +1204,7 @@
<key>fenced_code_block_xml</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((xml|xsd|tld|jsp|pt|cpt|dtml|rss|opml)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(xml|xsd|tld|jsp|pt|cpt|dtml|rss|opml)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1255,7 +1255,7 @@
<key>fenced_code_block_xsl</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((xsl|xslt)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(xsl|xslt)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1306,7 +1306,7 @@
<key>fenced_code_block_yaml</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((yaml|yml)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(yaml|yml)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1357,7 +1357,7 @@
<key>fenced_code_block_dosbatch</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((bat|batch)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(bat|batch)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1408,7 +1408,7 @@
<key>fenced_code_block_clojure</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((clj|cljs|clojure)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(clj|cljs|clojure)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1459,7 +1459,7 @@
<key>fenced_code_block_coffee</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((coffee|Cakefile|coffee.erb)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(coffee|Cakefile|coffee.erb)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1510,7 +1510,7 @@
<key>fenced_code_block_c</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((c|h)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(c|h)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1561,7 +1561,7 @@
<key>fenced_code_block_cpp</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((cpp|c\+\+|cxx)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(cpp|c\+\+|cxx)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1612,7 +1612,7 @@
<key>fenced_code_block_diff</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((patch|diff|rej)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(patch|diff|rej)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1663,7 +1663,7 @@
<key>fenced_code_block_dockerfile</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((dockerfile|Dockerfile)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(dockerfile|Dockerfile)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1714,7 +1714,7 @@
<key>fenced_code_block_git_commit</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((COMMIT_EDITMSG|MERGE_MSG)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(COMMIT_EDITMSG|MERGE_MSG)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1765,7 +1765,7 @@
<key>fenced_code_block_git_rebase</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((git-rebase-todo)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(git-rebase-todo)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1816,7 +1816,7 @@
<key>fenced_code_block_go</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((go|golang)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(go|golang)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1867,7 +1867,7 @@
<key>fenced_code_block_groovy</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((groovy|gvy)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(groovy|gvy)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1918,7 +1918,7 @@
<key>fenced_code_block_jade</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((jade|pug)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(jade|pug)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -1969,7 +1969,7 @@
<key>fenced_code_block_js</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((js|jsx|javascript|es6|mjs)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(js|jsx|javascript|es6|mjs)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2020,7 +2020,7 @@
<key>fenced_code_block_js_regexp</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((regexp)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(regexp)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2071,7 +2071,7 @@
<key>fenced_code_block_json</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((json|sublime-settings|sublime-menu|sublime-keymap|sublime-mousemap|sublime-theme|sublime-build|sublime-project|sublime-completions)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(json|sublime-settings|sublime-menu|sublime-keymap|sublime-mousemap|sublime-theme|sublime-build|sublime-project|sublime-completions)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2122,7 +2122,7 @@
<key>fenced_code_block_less</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((less)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(less)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2173,7 +2173,7 @@
<key>fenced_code_block_objc</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((objectivec|objective-c|mm|objc|obj-c|m|h)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(objectivec|objective-c|mm|objc|obj-c|m|h)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2224,7 +2224,7 @@
<key>fenced_code_block_scss</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((scss)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(scss)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2275,7 +2275,7 @@
<key>fenced_code_block_perl6</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((perl6|p6|pl6|pm6|nqp)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(perl6|p6|pl6|pm6|nqp)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2326,7 +2326,7 @@
<key>fenced_code_block_powershell</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((powershell|ps1|psm1|psd1)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(powershell|ps1|psm1|psd1)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2377,7 +2377,7 @@
<key>fenced_code_block_python</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((python|py|py3|rpy|pyw|cpy|SConstruct|Sconstruct|sconstruct|SConscript|gyp|gypi)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(python|py|py3|rpy|pyw|cpy|SConstruct|Sconstruct|sconstruct|SConscript|gyp|gypi)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2428,7 +2428,7 @@
<key>fenced_code_block_regexp_python</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((re)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(re)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2479,7 +2479,7 @@
<key>fenced_code_block_rust</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((rust|rs)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(rust|rs)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2530,7 +2530,7 @@
<key>fenced_code_block_scala</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((scala|sbt)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(scala|sbt)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2581,7 +2581,7 @@
<key>fenced_code_block_shell</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((shell|sh|bash|zsh|bashrc|bash_profile|bash_login|profile|bash_logout|.textmate_init)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(shell|sh|bash|zsh|bashrc|bash_profile|bash_login|profile|bash_logout|.textmate_init)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2632,7 +2632,7 @@
<key>fenced_code_block_ts</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((typescript|ts)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(typescript|ts)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2683,7 +2683,7 @@
<key>fenced_code_block_tsx</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((tsx)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(tsx)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2734,7 +2734,7 @@
<key>fenced_code_block_csharp</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((cs|csharp|c#)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(cs|csharp|c#)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
@ -2785,7 +2785,7 @@
<key>fenced_code_block_fsharp</key>
<dict>
<key>begin</key>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*((fs|fsharp|f#)(\s+[^`~]*)?$)</string>
<string>(^|\G)(\s*)(`{3,}|~{3,})\s*(?i:(fs|fsharp|f#)(\s+[^`~]*)?$)</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>

View file

@ -3,9 +3,9 @@
"version": "0.0.1",
"dependencies": {
"typescript": {
"version": "2.4.2",
"from": "typescript@2.4.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.4.2.tgz"
"version": "2.5.1-insiders.20170818",
"from": "typescript@2.5.1-insiders.20170818",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.1-insiders.20170818.tgz"
}
}
}

View file

@ -3,7 +3,7 @@
"version": "0.0.1",
"description": "Dependencies shared by all extensions",
"dependencies": {
"typescript": "2.4.2"
"typescript": "2.5.1-insiders.20170818"
},
"scripts": {
"postinstall": "node ./postinstall"

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/MagicStack/MagicPython/commit/976e59dcb78cb577e79c8f2117216c06718337e0",
"version": "https://github.com/MagicStack/MagicPython/commit/b453f26ed856c9b16a053517c41207e3a72cc7d5",
"name": "MagicPython",
"scopeName": "source.python",
"fileTypes": [
@ -260,14 +260,6 @@
}
}
},
"codetags": {
"match": "(?:\\b(NOTE|XXX|HACK|FIXME|BUG|TODO)\\b)",
"captures": {
"1": {
"name": "keyword.codetag.notation.python"
}
}
},
"statement-keyword": {
"patterns": [
{
@ -392,8 +384,13 @@
]
},
"member-access": {
"begin": "\\.\\s*(?!\\.)",
"begin": "(\\.)\\s*(?!\\.)",
"end": "(?x)\n # stop when you've just read non-whitespace followed by non-word\n # i.e. when finished reading an identifier or function call\n (?<=\\S)(?=\\W) |\n # stop when seeing the start of something that's not a word,\n # i.e. when seeing a non-identifier\n (^|(?<=\\s))(?=[^\\\\\\w\\s]) |\n $\n",
"beginCaptures": {
"1": {
"name": "punctuation.separator.period.python"
}
},
"patterns": [
{
"include": "#function-call"
@ -918,29 +915,6 @@
}
]
},
"fstring-formatting-braces": {
"patterns": [
{
"comment": "empty braces are illegal",
"match": "({)(\\s*?)(})",
"captures": {
"1": {
"name": "constant.character.format.placeholder.other.python"
},
"2": {
"name": "invalid.illegal.brace.python"
},
"3": {
"name": "constant.character.format.placeholder.other.python"
}
}
},
{
"name": "constant.character.escape.python",
"match": "({{|}})"
}
]
},
"fstring-formatting-singe-brace": {
"name": "invalid.illegal.brace.python",
"match": "(}(?!}))"
@ -949,11 +923,14 @@
"comment": "Import statements\n",
"patterns": [
{
"match": "(?x)\n \\s* \\b(from)\\b (\\s*\\.+\\s*) (import)?\n",
"match": "(?x)\n \\s* \\b(from)\\b \\s*(\\.+)\\s* (import)?\n",
"captures": {
"1": {
"name": "keyword.control.import.python"
},
"2": {
"name": "punctuation.separator.period.python"
},
"3": {
"name": "keyword.control.import.python"
}
@ -1077,8 +1054,13 @@
}
},
"member-access-class": {
"begin": "\\.\\s*(?!\\.)",
"begin": "(\\.)\\s*(?!\\.)",
"end": "(?<=\\S)(?=\\W)|$",
"beginCaptures": {
"1": {
"name": "punctuation.separator.period.python"
}
},
"patterns": [
{
"include": "#call-wrapper-inheritance"
@ -1671,7 +1653,7 @@
},
"magic-variable-names": {
"comment": "magic variables which a class/module may have.",
"match": "(?x)\n \\b(\n __(?:\n all | bases | builtins | class | code | debug | defaults | dict\n | doc | file | func | kwdefaults | members\n | metaclass | methods | module | mro | name\n | qualname | self | signature | slots | subclasses\n | version | weakref | wrapped | annotations | classcell\n | spec | path | package | future\n )__\n )\\b\n",
"match": "(?x)\n \\b(\n __(?:\n all | bases | builtins | class | code | debug | defaults | dict\n | doc | file | func | kwdefaults | members\n | metaclass | methods | module | mro | name\n | qualname | self | signature | slots | subclasses\n | version | weakref | wrapped | annotations | classcell\n | spec | path | package | future | traceback\n )__\n )\\b\n",
"captures": {
"1": {
"name": "support.variable.magic.python"
@ -1769,6 +1751,29 @@
}
]
},
"fstring-formatting-braces": {
"patterns": [
{
"comment": "empty braces are illegal",
"match": "({)(\\s*?)(})",
"captures": {
"1": {
"name": "constant.character.format.placeholder.other.python"
},
"2": {
"name": "invalid.illegal.brace.python"
},
"3": {
"name": "constant.character.format.placeholder.other.python"
}
}
},
{
"name": "constant.character.escape.python",
"match": "({{|}})"
}
]
},
"regexp-base-common": {
"patterns": [
{
@ -1891,6 +1896,14 @@
}
]
},
"codetags": {
"match": "(?:\\b(NOTE|XXX|HACK|FIXME|BUG|TODO)\\b)",
"captures": {
"1": {
"name": "keyword.codetag.notation.python"
}
}
},
"comments-base": {
"name": "comment.line.number-sign.python",
"begin": "(\\#)",

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/MagicStack/MagicPython/commit/df5bb18c64252f2e7b1aa87e2ed124666d314f1d",
"version": "https://github.com/MagicStack/MagicPython/commit/361a4964a559481330764a447e7bab88d4f1b01b",
"name": "MagicRegExp",
"scopeName": "source.regexp.python",
"fileTypes": [
@ -43,6 +43,29 @@
}
]
},
"fstring-formatting-braces": {
"patterns": [
{
"comment": "empty braces are illegal",
"match": "({)(\\s*?)(})",
"captures": {
"1": {
"name": "constant.character.format.placeholder.other.python"
},
"2": {
"name": "invalid.illegal.brace.python"
},
"3": {
"name": "constant.character.format.placeholder.other.python"
}
}
},
{
"name": "constant.character.escape.python",
"match": "({{|}})"
}
]
},
"regexp-base-common": {
"patterns": [
{
@ -165,6 +188,14 @@
}
]
},
"codetags": {
"match": "(?:\\b(NOTE|XXX|HACK|FIXME|BUG|TODO)\\b)",
"captures": {
"1": {
"name": "keyword.codetag.notation.python"
}
}
},
"regexp-expression": {
"patterns": [
{

View file

@ -407,7 +407,29 @@
}
},
{
"c": "banana.size",
"c": "banana",
"t": "source.python",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": ".",
"t": "source.python punctuation.separator.period.python",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "size",
"t": "source.python",
"r": {
"dark_plus": "default: #D4D4D4",
@ -2189,7 +2211,7 @@
}
},
{
"c": " g.",
"c": " g",
"t": "source.python",
"r": {
"dark_plus": "default: #D4D4D4",
@ -2199,6 +2221,17 @@
"hc_black": "default: #FFFFFF"
}
},
{
"c": ".",
"t": "source.python punctuation.separator.period.python",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "next",
"t": "source.python meta.function-call.python meta.function-call.generic.python",
@ -4499,7 +4532,18 @@
}
},
{
"c": ".fn ",
"c": ".",
"t": "source.python punctuation.separator.period.python",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "fn ",
"t": "source.python",
"r": {
"dark_plus": "default: #D4D4D4",
@ -4554,7 +4598,18 @@
}
},
{
"c": ".memo ",
"c": ".",
"t": "source.python punctuation.separator.period.python",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "memo ",
"t": "source.python",
"r": {
"dark_plus": "default: #D4D4D4",
@ -4829,7 +4884,18 @@
}
},
{
"c": ".memo",
"c": ".",
"t": "source.python punctuation.separator.period.python",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "memo",
"t": "source.python",
"r": {
"dark_plus": "default: #D4D4D4",
@ -4874,7 +4940,7 @@
},
{
"c": ".",
"t": "source.python",
"t": "source.python punctuation.separator.period.python",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -4973,7 +5039,7 @@
},
{
"c": ".",
"t": "source.python",
"t": "source.python punctuation.separator.period.python",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -5083,7 +5149,7 @@
},
{
"c": ".",
"t": "source.python",
"t": "source.python punctuation.separator.period.python",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -5159,7 +5225,7 @@
}
},
{
"c": " re.",
"c": " re",
"t": "source.python",
"r": {
"dark_plus": "default: #D4D4D4",
@ -5169,6 +5235,17 @@
"hc_black": "default: #FFFFFF"
}
},
{
"c": ".",
"t": "source.python punctuation.separator.period.python",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "search",
"t": "source.python meta.function-call.python meta.function-call.generic.python",

View file

@ -243,10 +243,8 @@
{
"name": "JavaScript string interpolation ${}",
"scope": [
"punctuation.definition.template-expression.begin.js",
"punctuation.definition.template-expression.begin.ts",
"punctuation.definition.template-expression.end.ts",
"punctuation.definition.template-expression.end.js",
"punctuation.definition.template-expression.begin",
"punctuation.definition.template-expression.end",
"punctuation.section.embedded.coffee"
],
"settings": {
@ -256,8 +254,7 @@
{
"name": "Reset JavaScript string interpolation expression",
"scope": [
"meta.template.expression.js",
"meta.template.expression.ts"
"meta.template.expression"
],
"settings": {
"foreground": "#d4d4d4"

View file

@ -32,7 +32,6 @@
"foreground": "#000080"
}
},
{
"scope": "comment",
"settings": {
@ -230,10 +229,8 @@
{
"name": "JavaScript string interpolation ${}",
"scope": [
"punctuation.definition.template-expression.begin.js",
"punctuation.definition.template-expression.begin.ts",
"punctuation.definition.template-expression.end.ts",
"punctuation.definition.template-expression.end.js",
"punctuation.definition.template-expression.begin",
"punctuation.definition.template-expression.end",
"punctuation.section.embedded.coffee"
],
"settings": {
@ -243,8 +240,7 @@
{
"name": "Reset JavaScript string interpolation expression",
"scope": [
"meta.template.expression.js",
"meta.template.expression.ts"
"meta.template.expression"
],
"settings": {
"foreground": "#ffffff"

View file

@ -239,10 +239,8 @@
{
"name": "JavaScript string interpolation ${}",
"scope": [
"punctuation.definition.template-expression.begin.js",
"punctuation.definition.template-expression.begin.ts",
"punctuation.definition.template-expression.end.ts",
"punctuation.definition.template-expression.end.js",
"punctuation.definition.template-expression.begin",
"punctuation.definition.template-expression.end",
"punctuation.section.embedded.coffee"
],
"settings": {
@ -252,8 +250,7 @@
{
"name": "Reset JavaScript string interpolation expression",
"scope": [
"meta.template.expression.js",
"meta.template.expression.ts"
"meta.template.expression"
],
"settings": {
"foreground": "#000000"

View file

@ -4,7 +4,7 @@
"configuration.typescript": "TypeScript",
"typescript.useCodeSnippetsOnMethodSuggest.dec": "Complete functions with their parameter signature.",
"typescript.tsdk.desc": "Specifies the folder path containing the tsserver and lib*.d.ts files to use.",
"typescript.disableAutomaticTypeAcquisition": "Disables automatic type acquisition. Requires TypeScript >= 2.0.6 and a restart after changing it.",
"typescript.disableAutomaticTypeAcquisition": "Disables automatic type acquisition. Requires TypeScript >= 2.0.6.",
"typescript.tsserver.log": "Enables logging of the TS server to a file. This log can be used to diagnose TS Server issues. The log may contain file paths, source code, and other potentially sensitive information from your project.",
"typescript.tsserver.trace": "Enables tracing of messages sent to the TS server. This trace can be used to diagnose TS Server issues. The trace may contain file paths, source code, and other potentially sensitive information from your project.",
"typescript.validate.enable": "Enable/disable TypeScript validation.",

View file

@ -53,6 +53,15 @@ class SyncedBuffer {
}
}
if (this.client.apiVersion.has240Features()) {
const tsPluginsForDocument = this.client.plugins
.filter(x => x.languages.indexOf(this.document.languageId) >= 0);
if (tsPluginsForDocument.length) {
(args as any).plugins = tsPluginsForDocument.map(plugin => plugin.name);
}
}
this.client.execute('open', args, false);
}

View file

@ -278,7 +278,7 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
// Don't complete function calls inside of destructive assigments or imports
return this.client.execute('quickinfo', args).then(infoResponse => {
const info = infoResponse.body;
switch (info && info.kind) {
switch (info && info.kind as string) {
case 'var':
case 'let':
case 'const':

View file

@ -71,7 +71,7 @@ export default class TypeScriptDocumentSymbolProvider implements DocumentSymbolP
let key = `${realIndent}|${item.text}`;
if (realIndent !== 0 && !foldingMap[key] && TypeScriptDocumentSymbolProvider.shouldInclueEntry(item.text)) {
let result = new SymbolInformation(item.text,
outlineTypeTable[item.kind] || SymbolKind.Variable,
outlineTypeTable[item.kind as string] || SymbolKind.Variable,
containerLabel ? containerLabel : '',
new Location(resource, textSpan2Range(item.spans[0])));
foldingMap[key] = result;
@ -86,7 +86,7 @@ export default class TypeScriptDocumentSymbolProvider implements DocumentSymbolP
private static convertNavTree(resource: Uri, bucket: SymbolInformation[], item: Proto.NavigationTree, containerLabel?: string): void {
const result = new SymbolInformation(item.text,
outlineTypeTable[item.kind] || SymbolKind.Variable,
outlineTypeTable[item.kind as string] || SymbolKind.Variable,
containerLabel ? containerLabel : '',
new Location(resource, textSpan2Range(item.spans[0]))
);

View file

@ -5,7 +5,7 @@
'use strict';
import { CodeActionProvider, TextDocument, Range, CancellationToken, CodeActionContext, Command, commands, workspace, WorkspaceEdit, window, QuickPickItem } from 'vscode';
import { CodeActionProvider, TextDocument, Range, CancellationToken, CodeActionContext, Command, commands, workspace, WorkspaceEdit, window, QuickPickItem, Selection, Position } from 'vscode';
import * as Proto from '../protocol';
import { ITypescriptServiceClient } from '../typescriptService';
@ -123,6 +123,18 @@ export default class TypeScriptRefactorProvider implements CodeActionProvider {
}
const edit = this.toWorkspaceEdit(response.body.edits);
return workspace.applyEdit(edit);
if (!(await workspace.applyEdit(edit))) {
return false;
}
const renameLocation = response.body.renameLocation;
if (renameLocation) {
if (window.activeTextEditor && window.activeTextEditor.document.uri.fsPath === file) {
const pos = new Position(renameLocation.line - 1, renameLocation.offset - 1);
window.activeTextEditor.selection = new Selection(pos, pos);
await commands.executeCommand('editor.action.rename');
}
}
return true;
}
}

View file

@ -78,10 +78,10 @@ class TscTaskProvider implements vscode.TaskProvider {
const editor = vscode.window.activeTextEditor;
if (editor) {
if (path.basename(editor.document.fileName).match(/^tsconfig\.(.\.)?json$/)) {
const path = editor.document.uri;
const uri = editor.document.uri;
return [{
path: path.fsPath,
workspaceFolder: vscode.workspace.getWorkspaceFolder(path)
path: uri.fsPath,
workspaceFolder: vscode.workspace.getWorkspaceFolder(uri)
}];
}
}
@ -103,10 +103,11 @@ class TscTaskProvider implements vscode.TaskProvider {
const { configFileName } = res.body;
if (configFileName && !isImplicitProjectConfigFile(configFileName)) {
const path = vscode.Uri.file(configFileName);
const folder = vscode.workspace.getWorkspaceFolder(path);
const normalizedConfigPath = path.normalize(configFileName);
const uri = vscode.Uri.file(normalizedConfigPath);
const folder = vscode.workspace.getWorkspaceFolder(uri);
return [{
path: configFileName,
path: normalizedConfigPath,
workspaceFolder: folder
}];
}

View file

@ -300,8 +300,7 @@ class LanguageProvider {
// ^(.*\*/)?\s*\}.*$
decreaseIndentPattern: /^((?!.*?\/\*).*\*\/)?\s*[\}\]\)].*$/,
// ^.*\{[^}"']*$
increaseIndentPattern: /^((?!\/\/).)*(\{[^}"'`]*|\([^)"'`]*|\[[^\]"'`]*)$/,
indentNextLinePattern: /^\s*(for|while|if|else)\b(?!.*[;{}]\s*(\/\/.*|\/[*].*[*]\/\s*)?$)/
increaseIndentPattern: /^((?!\/\/).)*(\{[^}"'`]*|\([^)"'`]*|\[[^\]"'`]*)$/
},
wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
onEnterRules: [
@ -327,12 +326,6 @@ class LanguageProvider {
// e.g. *-----*/|
beforeText: /^(\t|(\ \ ))*\ \*[^/]*\*\/\s*$/,
action: { indentAction: IndentAction.None, removeText: 1 }
},
{
// e.g. if (...) | {}
beforeText: /^\s*(for|while|if|else)\s*/,
afterText: /^\s*{/,
action: { indentAction: IndentAction.None }
}
]
}));

View file

@ -7,6 +7,7 @@
import { CancellationToken, Uri, Event } from 'vscode';
import * as Proto from './protocol';
import API from './utils/api';
import { TypeScriptServerPlugin } from "./utils/plugins";
export interface ITypescriptServiceClientHost {
syntaxDiagnosticsReceived(event: Proto.DiagnosticEvent): void;
@ -34,6 +35,8 @@ export interface ITypescriptServiceClient {
apiVersion: API;
plugins: TypeScriptServerPlugin[];
execute(command: 'configure', args: Proto.ConfigureRequestArguments, token?: CancellationToken): Promise<Proto.ConfigureResponse>;
execute(command: 'open', args: Proto.OpenRequestArgs, expectedResult: boolean, token?: CancellationToken): Promise<any>;
execute(command: 'close', args: Proto.FileRequestArgs, expectedResult: boolean, token?: CancellationToken): Promise<any>;

View file

@ -159,7 +159,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
private readonly host: ITypescriptServiceClientHost,
private readonly workspaceState: Memento,
private readonly versionStatus: VersionStatus,
private readonly plugins: TypeScriptServerPlugin[]
public readonly plugins: TypeScriptServerPlugin[]
) {
this.pathSeparator = path.sep;
this.lastStart = Date.now();
@ -332,7 +332,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
const args: string[] = [];
if (this.apiVersion.has206Features()) {
args.push('--useSingleInferredProject');
if (workspace.getConfiguration().get<boolean>('typescript.disableAutomaticTypeAcquisition', false)) {
if (this.configuration.disableAutomaticTypeAcquisition) {
args.push('--disableAutomaticTypingAcquisition');
}
}
@ -501,12 +501,12 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
}
const compilerOptions: Proto.ExternalProjectCompilerOptions = {
module: 'CommonJS',
target: 'ES6',
module: Proto.ModuleKind.CommonJS,
target: Proto.ScriptTarget.ES6,
allowSyntheticDefaultImports: true,
allowNonTsExtensions: true,
allowJs: true,
jsx: 'Preserve'
jsx: Proto.JsxEmit.Preserve
};
if (this.apiVersion.has230Features()) {

View file

@ -4,64 +4,65 @@
*--------------------------------------------------------------------------------------------*/
import * as semver from 'semver';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
export default class API {
public static readonly defaultVersion = new API('1.0.0');
public static readonly defaultVersion = new API('1.0.0', '1.0.0');
private readonly _version: string;
constructor(
private readonly _versionString: string
) {
this._version = semver.valid(_versionString);
if (!this._version) {
this._version = '1.0.0';
} else {
// Cut of any prerelease tag since we sometimes consume those
// on purpose.
let index = _versionString.indexOf('-');
if (index >= 0) {
this._version = this._version.substr(0, index);
}
public static fromVersionString(versionString: string): API {
let version = semver.valid(versionString);
if (!version) {
return new API(localize('invalidVersion', 'invalid version'), '1.0.0');
}
// Cut of any prerelease tag since we sometimes consume those on purpose.
const index = versionString.indexOf('-');
if (index >= 0) {
version = version.substr(0, index);
}
return new API(versionString, version);
}
public get versionString(): string {
return this._versionString;
}
private constructor(
public readonly versionString: string,
private readonly version: string
) { }
public has203Features(): boolean {
return semver.gte(this._version, '2.0.3');
return semver.gte(this.version, '2.0.3');
}
public has206Features(): boolean {
return semver.gte(this._version, '2.0.6');
return semver.gte(this.version, '2.0.6');
}
public has208Features(): boolean {
return semver.gte(this._version, '2.0.8');
return semver.gte(this.version, '2.0.8');
}
public has213Features(): boolean {
return semver.gte(this._version, '2.1.3');
return semver.gte(this.version, '2.1.3');
}
public has220Features(): boolean {
return semver.gte(this._version, '2.2.0');
return semver.gte(this.version, '2.2.0');
}
public has222Features(): boolean {
return semver.gte(this._version, '2.2.2');
return semver.gte(this.version, '2.2.2');
}
public has230Features(): boolean {
return semver.gte(this._version, '2.3.0');
return semver.gte(this.version, '2.3.0');
}
public has234Features(): boolean {
return semver.gte(this._version, '2.3.4');
return semver.gte(this.version, '2.3.4');
}
public has240Features(): boolean {
return semver.gte(this._version, '2.4.0');
return semver.gte(this.version, '2.4.0');
}
}

View file

@ -47,6 +47,7 @@ export class TypeScriptServiceConfiguration {
public readonly npmLocation: string | null;
public readonly tsServerLogLevel: TsServerLogLevel = TsServerLogLevel.Off;
public readonly checkJs: boolean;
public readonly disableAutomaticTypeAcquisition: boolean;
public static loadFromWorkspace(): TypeScriptServiceConfiguration {
return new TypeScriptServiceConfiguration();
@ -60,6 +61,7 @@ export class TypeScriptServiceConfiguration {
this.npmLocation = TypeScriptServiceConfiguration.readNpmLocation(configuration);
this.tsServerLogLevel = TypeScriptServiceConfiguration.readTsServerLogLevel(configuration);
this.checkJs = TypeScriptServiceConfiguration.readCheckJs(configuration);
this.disableAutomaticTypeAcquisition = TypeScriptServiceConfiguration.readDisableAutomaticTypeAcquisition(configuration);
}
public isEqualTo(other: TypeScriptServiceConfiguration): boolean {
@ -67,7 +69,8 @@ export class TypeScriptServiceConfiguration {
&& this.localTsdk === other.localTsdk
&& this.npmLocation === other.npmLocation
&& this.tsServerLogLevel === other.tsServerLogLevel
&& this.checkJs === other.checkJs;
&& this.checkJs === other.checkJs
&& this.disableAutomaticTypeAcquisition === other.disableAutomaticTypeAcquisition;
}
private static extractGlobalTsdk(configuration: WorkspaceConfiguration): string | null {
@ -98,4 +101,8 @@ export class TypeScriptServiceConfiguration {
private static readNpmLocation(configuration: WorkspaceConfiguration): string | null {
return configuration.get<string | null>('typescript.npm', null);
}
}
private static readDisableAutomaticTypeAcquisition(configuration: WorkspaceConfiguration): boolean {
return configuration.get<boolean>('typescript.disableAutomaticTypeAcquisition', false);
}
}

View file

@ -41,7 +41,7 @@ export class TypeScriptVersion {
// Allow TS developers to provide custom version
const tsdkVersion = workspace.getConfiguration().get<string | undefined>('typescript.tsdk_version', undefined);
if (tsdkVersion) {
return new API(tsdkVersion);
return API.fromVersionString(tsdkVersion);
}
return undefined;
@ -78,7 +78,7 @@ export class TypeScriptVersion {
if (!desc || !desc.version) {
return undefined;
}
return desc.version ? new API(desc.version) : undefined;
return desc.version ? API.fromVersionString(desc.version) : undefined;
}
}

View file

@ -355,11 +355,11 @@
"c": "${",
"t": "source.ts meta.function.ts meta.block.ts meta.var.expr.ts string.template.ts meta.template.expression.ts punctuation.definition.template-expression.begin.ts",
"r": {
"dark_plus": "punctuation.definition.template-expression.begin.ts: #569CD6",
"light_plus": "punctuation.definition.template-expression.begin.ts: #0000FF",
"dark_vs": "punctuation.definition.template-expression.begin.ts: #569CD6",
"light_vs": "punctuation.definition.template-expression.begin.ts: #0000FF",
"hc_black": "punctuation.definition.template-expression.begin.ts: #569CD6"
"dark_plus": "punctuation.definition.template-expression.begin: #569CD6",
"light_plus": "punctuation.definition.template-expression.begin: #0000FF",
"dark_vs": "punctuation.definition.template-expression.begin: #569CD6",
"light_vs": "punctuation.definition.template-expression.begin: #0000FF",
"hc_black": "punctuation.definition.template-expression.begin: #569CD6"
}
},
{
@ -368,8 +368,8 @@
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "variable: #9CDCFE"
}
},
@ -377,11 +377,11 @@
"c": "}",
"t": "source.ts meta.function.ts meta.block.ts meta.var.expr.ts string.template.ts meta.template.expression.ts punctuation.definition.template-expression.end.ts",
"r": {
"dark_plus": "punctuation.definition.template-expression.end.ts: #569CD6",
"light_plus": "punctuation.definition.template-expression.end.ts: #0000FF",
"dark_vs": "punctuation.definition.template-expression.end.ts: #569CD6",
"light_vs": "punctuation.definition.template-expression.end.ts: #0000FF",
"hc_black": "punctuation.definition.template-expression.end.ts: #569CD6"
"dark_plus": "punctuation.definition.template-expression.end: #569CD6",
"light_plus": "punctuation.definition.template-expression.end: #0000FF",
"dark_vs": "punctuation.definition.template-expression.end: #569CD6",
"light_vs": "punctuation.definition.template-expression.end: #0000FF",
"hc_black": "punctuation.definition.template-expression.end: #569CD6"
}
},
{
@ -399,11 +399,11 @@
"c": "${",
"t": "source.ts meta.function.ts meta.block.ts meta.var.expr.ts string.template.ts meta.template.expression.ts punctuation.definition.template-expression.begin.ts",
"r": {
"dark_plus": "punctuation.definition.template-expression.begin.ts: #569CD6",
"light_plus": "punctuation.definition.template-expression.begin.ts: #0000FF",
"dark_vs": "punctuation.definition.template-expression.begin.ts: #569CD6",
"light_vs": "punctuation.definition.template-expression.begin.ts: #0000FF",
"hc_black": "punctuation.definition.template-expression.begin.ts: #569CD6"
"dark_plus": "punctuation.definition.template-expression.begin: #569CD6",
"light_plus": "punctuation.definition.template-expression.begin: #0000FF",
"dark_vs": "punctuation.definition.template-expression.begin: #569CD6",
"light_vs": "punctuation.definition.template-expression.begin: #0000FF",
"hc_black": "punctuation.definition.template-expression.begin: #569CD6"
}
},
{
@ -412,8 +412,8 @@
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "variable: #9CDCFE"
}
},
@ -421,11 +421,11 @@
"c": "}",
"t": "source.ts meta.function.ts meta.block.ts meta.var.expr.ts string.template.ts meta.template.expression.ts punctuation.definition.template-expression.end.ts",
"r": {
"dark_plus": "punctuation.definition.template-expression.end.ts: #569CD6",
"light_plus": "punctuation.definition.template-expression.end.ts: #0000FF",
"dark_vs": "punctuation.definition.template-expression.end.ts: #569CD6",
"light_vs": "punctuation.definition.template-expression.end.ts: #0000FF",
"hc_black": "punctuation.definition.template-expression.end.ts: #569CD6"
"dark_plus": "punctuation.definition.template-expression.end: #569CD6",
"light_plus": "punctuation.definition.template-expression.end: #0000FF",
"dark_vs": "punctuation.definition.template-expression.end: #569CD6",
"light_vs": "punctuation.definition.template-expression.end: #0000FF",
"hc_black": "punctuation.definition.template-expression.end: #569CD6"
}
},
{

View file

@ -91,11 +91,11 @@
"c": "${",
"t": "source.ts meta.var.expr.ts string.template.ts meta.template.expression.ts punctuation.definition.template-expression.begin.ts",
"r": {
"dark_plus": "punctuation.definition.template-expression.begin.ts: #569CD6",
"light_plus": "punctuation.definition.template-expression.begin.ts: #0000FF",
"dark_vs": "punctuation.definition.template-expression.begin.ts: #569CD6",
"light_vs": "punctuation.definition.template-expression.begin.ts: #0000FF",
"hc_black": "punctuation.definition.template-expression.begin.ts: #569CD6"
"dark_plus": "punctuation.definition.template-expression.begin: #569CD6",
"light_plus": "punctuation.definition.template-expression.begin: #0000FF",
"dark_vs": "punctuation.definition.template-expression.begin: #569CD6",
"light_vs": "punctuation.definition.template-expression.begin: #0000FF",
"hc_black": "punctuation.definition.template-expression.begin: #569CD6"
}
},
{
@ -104,8 +104,8 @@
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "variable: #9CDCFE"
}
},
@ -113,11 +113,11 @@
"c": "}",
"t": "source.ts meta.var.expr.ts string.template.ts meta.template.expression.ts punctuation.definition.template-expression.end.ts",
"r": {
"dark_plus": "punctuation.definition.template-expression.end.ts: #569CD6",
"light_plus": "punctuation.definition.template-expression.end.ts: #0000FF",
"dark_vs": "punctuation.definition.template-expression.end.ts: #569CD6",
"light_vs": "punctuation.definition.template-expression.end.ts: #0000FF",
"hc_black": "punctuation.definition.template-expression.end.ts: #569CD6"
"dark_plus": "punctuation.definition.template-expression.end: #569CD6",
"light_plus": "punctuation.definition.template-expression.end: #0000FF",
"dark_vs": "punctuation.definition.template-expression.end: #569CD6",
"light_vs": "punctuation.definition.template-expression.end: #0000FF",
"hc_black": "punctuation.definition.template-expression.end: #569CD6"
}
},
{
@ -344,22 +344,22 @@
"c": "${",
"t": "source.ts string.template.ts meta.template.expression.ts punctuation.definition.template-expression.begin.ts",
"r": {
"dark_plus": "punctuation.definition.template-expression.begin.ts: #569CD6",
"light_plus": "punctuation.definition.template-expression.begin.ts: #0000FF",
"dark_vs": "punctuation.definition.template-expression.begin.ts: #569CD6",
"light_vs": "punctuation.definition.template-expression.begin.ts: #0000FF",
"hc_black": "punctuation.definition.template-expression.begin.ts: #569CD6"
"dark_plus": "punctuation.definition.template-expression.begin: #569CD6",
"light_plus": "punctuation.definition.template-expression.begin: #0000FF",
"dark_vs": "punctuation.definition.template-expression.begin: #569CD6",
"light_vs": "punctuation.definition.template-expression.begin: #0000FF",
"hc_black": "punctuation.definition.template-expression.begin: #569CD6"
}
},
{
"c": " ",
"t": "source.ts string.template.ts meta.template.expression.ts",
"r": {
"dark_plus": "meta.template.expression.ts: #D4D4D4",
"light_plus": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"hc_black": "meta.template.expression.ts: #FFFFFF"
"dark_plus": "meta.template.expression: #D4D4D4",
"light_plus": "meta.template.expression: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "meta.template.expression: #FFFFFF"
}
},
{
@ -368,8 +368,8 @@
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "variable: #9CDCFE"
}
},
@ -377,11 +377,11 @@
"c": " ",
"t": "source.ts string.template.ts meta.template.expression.ts",
"r": {
"dark_plus": "meta.template.expression.ts: #D4D4D4",
"light_plus": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"hc_black": "meta.template.expression.ts: #FFFFFF"
"dark_plus": "meta.template.expression: #D4D4D4",
"light_plus": "meta.template.expression: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "meta.template.expression: #FFFFFF"
}
},
{
@ -399,11 +399,11 @@
"c": " ",
"t": "source.ts string.template.ts meta.template.expression.ts",
"r": {
"dark_plus": "meta.template.expression.ts: #D4D4D4",
"light_plus": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"hc_black": "meta.template.expression.ts: #FFFFFF"
"dark_plus": "meta.template.expression: #D4D4D4",
"light_plus": "meta.template.expression: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "meta.template.expression: #FFFFFF"
}
},
{
@ -412,8 +412,8 @@
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "variable: #9CDCFE"
}
},
@ -421,22 +421,22 @@
"c": " ",
"t": "source.ts string.template.ts meta.template.expression.ts",
"r": {
"dark_plus": "meta.template.expression.ts: #D4D4D4",
"light_plus": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"hc_black": "meta.template.expression.ts: #FFFFFF"
"dark_plus": "meta.template.expression: #D4D4D4",
"light_plus": "meta.template.expression: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "meta.template.expression: #FFFFFF"
}
},
{
"c": "}",
"t": "source.ts string.template.ts meta.template.expression.ts punctuation.definition.template-expression.end.ts",
"r": {
"dark_plus": "punctuation.definition.template-expression.end.ts: #569CD6",
"light_plus": "punctuation.definition.template-expression.end.ts: #0000FF",
"dark_vs": "punctuation.definition.template-expression.end.ts: #569CD6",
"light_vs": "punctuation.definition.template-expression.end.ts: #0000FF",
"hc_black": "punctuation.definition.template-expression.end.ts: #569CD6"
"dark_plus": "punctuation.definition.template-expression.end: #569CD6",
"light_plus": "punctuation.definition.template-expression.end: #0000FF",
"dark_vs": "punctuation.definition.template-expression.end: #569CD6",
"light_vs": "punctuation.definition.template-expression.end: #0000FF",
"hc_black": "punctuation.definition.template-expression.end: #569CD6"
}
},
{
@ -454,22 +454,22 @@
"c": "${",
"t": "source.ts string.template.ts meta.template.expression.ts punctuation.definition.template-expression.begin.ts",
"r": {
"dark_plus": "punctuation.definition.template-expression.begin.ts: #569CD6",
"light_plus": "punctuation.definition.template-expression.begin.ts: #0000FF",
"dark_vs": "punctuation.definition.template-expression.begin.ts: #569CD6",
"light_vs": "punctuation.definition.template-expression.begin.ts: #0000FF",
"hc_black": "punctuation.definition.template-expression.begin.ts: #569CD6"
"dark_plus": "punctuation.definition.template-expression.begin: #569CD6",
"light_plus": "punctuation.definition.template-expression.begin: #0000FF",
"dark_vs": "punctuation.definition.template-expression.begin: #569CD6",
"light_vs": "punctuation.definition.template-expression.begin: #0000FF",
"hc_black": "punctuation.definition.template-expression.begin: #569CD6"
}
},
{
"c": " ",
"t": "source.ts string.template.ts meta.template.expression.ts",
"r": {
"dark_plus": "meta.template.expression.ts: #D4D4D4",
"light_plus": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"hc_black": "meta.template.expression.ts: #FFFFFF"
"dark_plus": "meta.template.expression: #D4D4D4",
"light_plus": "meta.template.expression: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "meta.template.expression: #FFFFFF"
}
},
{
@ -478,8 +478,8 @@
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "variable: #9CDCFE"
}
},
@ -487,11 +487,11 @@
"c": " ",
"t": "source.ts string.template.ts meta.template.expression.ts",
"r": {
"dark_plus": "meta.template.expression.ts: #D4D4D4",
"light_plus": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"hc_black": "meta.template.expression.ts: #FFFFFF"
"dark_plus": "meta.template.expression: #D4D4D4",
"light_plus": "meta.template.expression: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "meta.template.expression: #FFFFFF"
}
},
{
@ -509,11 +509,11 @@
"c": " ",
"t": "source.ts string.template.ts meta.template.expression.ts",
"r": {
"dark_plus": "meta.template.expression.ts: #D4D4D4",
"light_plus": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"hc_black": "meta.template.expression.ts: #FFFFFF"
"dark_plus": "meta.template.expression: #D4D4D4",
"light_plus": "meta.template.expression: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "meta.template.expression: #FFFFFF"
}
},
{
@ -522,8 +522,8 @@
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "variable: #9CDCFE"
}
},
@ -531,22 +531,22 @@
"c": " ",
"t": "source.ts string.template.ts meta.template.expression.ts",
"r": {
"dark_plus": "meta.template.expression.ts: #D4D4D4",
"light_plus": "meta.template.expression.ts: #000000",
"dark_vs": "meta.template.expression.ts: #D4D4D4",
"light_vs": "meta.template.expression.ts: #000000",
"hc_black": "meta.template.expression.ts: #FFFFFF"
"dark_plus": "meta.template.expression: #D4D4D4",
"light_plus": "meta.template.expression: #000000",
"dark_vs": "meta.template.expression: #D4D4D4",
"light_vs": "meta.template.expression: #000000",
"hc_black": "meta.template.expression: #FFFFFF"
}
},
{
"c": "}",
"t": "source.ts string.template.ts meta.template.expression.ts punctuation.definition.template-expression.end.ts",
"r": {
"dark_plus": "punctuation.definition.template-expression.end.ts: #569CD6",
"light_plus": "punctuation.definition.template-expression.end.ts: #0000FF",
"dark_vs": "punctuation.definition.template-expression.end.ts: #569CD6",
"light_vs": "punctuation.definition.template-expression.end.ts: #0000FF",
"hc_black": "punctuation.definition.template-expression.end.ts: #569CD6"
"dark_plus": "punctuation.definition.template-expression.end: #569CD6",
"light_plus": "punctuation.definition.template-expression.end: #0000FF",
"dark_vs": "punctuation.definition.template-expression.end: #569CD6",
"light_vs": "punctuation.definition.template-expression.end: #0000FF",
"hc_black": "punctuation.definition.template-expression.end: #569CD6"
}
},
{

View file

@ -36,6 +36,7 @@
".proj",
".props",
".pt",
".publishsettings",
".pubxml",
".pubxml.user",
".rdf",

12
npm-shrinkwrap.json generated
View file

@ -296,9 +296,9 @@
"resolved": "https://registry.npmjs.org/native-keymap/-/native-keymap-1.2.4.tgz"
},
"native-watchdog": {
"version": "0.1.0",
"from": "native-watchdog@0.1.0",
"resolved": "https://registry.npmjs.org/native-watchdog/-/native-watchdog-0.1.0.tgz"
"version": "0.2.0",
"from": "native-watchdog@0.2.0",
"resolved": "https://registry.npmjs.org/native-watchdog/-/native-watchdog-0.2.0.tgz"
},
"node-pty": {
"version": "0.6.9",
@ -567,9 +567,9 @@
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.0.tgz"
},
"xterm": {
"version": "2.8.1",
"from": "Tyriar/xterm.js#vscode-release/1.15",
"resolved": "git+https://github.com/Tyriar/xterm.js.git#75ffea5ebd5510ad0478b017c3946cb8d504855f"
"version": "2.9.1",
"from": "Tyriar/xterm.js#vscode-release/1.16",
"resolved": "git+https://github.com/Tyriar/xterm.js.git#cdf3177fd735ab64403a34778d69daa833e539a5"
},
"yauzl": {
"version": "2.8.0",

View file

@ -35,7 +35,7 @@
"keytar": "^4.0.3",
"minimist": "1.2.0",
"native-keymap": "1.2.4",
"native-watchdog": "0.1.0",
"native-watchdog": "0.2.0",
"node-pty": "0.6.9",
"nsfw": "1.0.16",
"semver": "4.3.6",
@ -44,7 +44,7 @@
"vscode-ripgrep": "0.0.25",
"vscode-textmate": "^3.1.5",
"winreg": "1.2.0",
"xterm": "Tyriar/xterm.js#vscode-release/1.15",
"xterm": "Tyriar/xterm.js#vscode-release/1.16",
"yauzl": "2.8.0"
},
"devDependencies": {

18
src/bootstrap.js vendored
View file

@ -103,13 +103,15 @@ if (!process.env['VSCODE_ALLOW_IO']) {
process.__defineGetter__('stdin', function () { return writable; });
}
// Handle uncaught exceptions
process.on('uncaughtException', function (err) {
console.error('Uncaught Exception: ', err.toString());
if (err.stack) {
console.error(err.stack);
}
});
if (!process.env['VSCODE_HANDLES_UNCAUGHT_ERRORS']) {
// Handle uncaught exceptions
process.on('uncaughtException', function (err) {
console.error('Uncaught Exception: ', err.toString());
if (err.stack) {
console.error(err.stack);
}
});
}
// Kill oneself if one's parent dies. Much drama.
if (process.env['VSCODE_PARENT_PID']) {
@ -138,4 +140,4 @@ if (typeof crashReporterOptionsRaw === 'string') {
}
}
require('./bootstrap-amd').bootstrap(process.env['AMD_ENTRYPOINT']);
require('./bootstrap-amd').bootstrap(process.env['AMD_ENTRYPOINT']);

592
src/typings/xterm.d.ts vendored
View file

@ -1,197 +1,455 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/**
* @license MIT
*
* This contains the type declarations for the xterm.js library. Note that
* some interfaces differ between this file and the actual implementation in
* src/, that's because this file declares the *public* API which is intended
* to be stable and consumed by external programs.
*/
declare module 'xterm' {
type LinkMatcherHandler = (event: MouseEvent, uri: string) => boolean | void;
/**
* An object containing start up options for the terminal.
*/
interface ITerminalOptions {
/**
* A data uri of the sound to use for the bell (needs bellStyle = 'sound').
*/
bellSound?: string;
class Terminal {
cols: number;
rows: number;
ydisp: number;
element: HTMLElement;
textarea: HTMLTextAreaElement;
/**
* The type of the bell notification the terminal will use.
*/
bellStyle?: 'none' | 'visual' | 'sound' | 'both';
/**
* Creates a new `Terminal` object.
*
* @param {object} options An object containing a set of options.
*/
constructor(options?: any);
/**
* The number of columns in the terminal.
*/
cols?: number;
/**
* Registers an event listener.
* @param eventName The name of the event.
* @param callback The callback.
*/
on(eventName: string, callback: (data: any) => void): void;
/**
* Whether the cursor blinks.
*/
cursorBlink?: boolean;
/**
* Resizes the terminal.
*
* @param x The number of columns to resize to.
* @param y The number of rows to resize to.
*/
resize(columns: number, rows: number): void;
/**
* The style of the cursor.
*/
cursorStyle?: 'block' | 'underline' | 'bar';
/**
* Emits an event.
* @param eventName The name of the event.
* @param data The data attached to the event.
*/
emit(eventName: string, data: any): void;
/**
* Whether input should be disabled.
*/
disableStdin?: boolean;
/**
* Writes text to the terminal, followed by a break line character (\n).
* @param data The text to write to the terminal.
*/
writeln(data: string): void;
/**
* The number of rows in the terminal.
*/
rows?: number;
/**
* Opens the terminal within an element.
* @param parent The element to create the terminal within.
* @param focus Focus the terminal, after it gets instantiated in the
* DOM.
*/
open(parent: HTMLElement, focus: boolean): void;
/**
* The amount of scrollback in the terminal. Scrollback is the amount of rows
* that are retained when lines are scrolled beyond the initial viewport.
*/
scrollback?: number;
/**
* Attaches a custom key event handler which is run before keys are
* processed, giving consumers of xterm.js ultimate control as to what
* keys should be processed by the terminal and what keys should not.
* @param customKeyEventHandler The custom KeyboardEvent handler to
* attach. This is a function that takes a KeyboardEvent, allowing
* consumers to stop propogation and/or prevent the default action. The
* function returns whether the event should be processed by xterm.js.
*/
attachCustomKeyEventHandler(customKeyEventHandler: (...any) => boolean);
/**
* The size of tab stops in the terminal.
*/
tabStopWidth?: number;
}
/**
* Retrieves an option's value from the terminal.
* @param key The option key.
*/
getOption(key: string): any;
/**
* An object containing options for a link matcher.
*/
interface ILinkMatcherOptions {
/**
* The index of the link from the regex.match(text) call. This defaults to 0
* (for regular expressions without capture groups).
*/
matchIndex?: number;
/**
* Registers a link matcher, allowing custom link patterns to be matched and
* handled.
* @param {RegExp} regex The regular expression to search for, specifically
* this searches the textContent of the rows. You will want to use \s to match
* a space ' ' character for example.
* @param {LinkMatcherHandler} handler The callback when the link is called.
* @param {LinkMatcherOptions} [options] Options for the link matcher.
* @return {number} The ID of the new matcher, this can be used to deregister.
*/
registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler , options?: any);
/**
* A callback that validates an individual link, returning true if valid and
* false if invalid.
*/
validationCallback?: (uri: string, element: HTMLElement, callback: (isValid: boolean) => void) => void;
/**
* Deregisters a link matcher if it has been registered.
* @param matcherId The link matcher's ID (returned after register)
*/
deregisterLinkMatcher(matcherId: number): void;
/**
* The priority of the link matcher, this defines the order in which the link
* matcher is evaluated relative to others, from highest to lowest. The
* default value is 0.
*/
priority?: number;
}
/**
* Gets whether the terminal has an active selection.
*/
hasSelection(): boolean;
declare module 'xterm' {
/**
* The class that represents an xterm.js terminal.
*/
export class Terminal {
/**
* The element containing the terminal.
*/
element: HTMLElement;
/**
* Gets the terminal's current selection, this is useful for implementing copy
* behavior outside of xterm.js.
*/
getSelection(): string;
/**
* The textarea that accepts input for the terminal.
*/
textarea: HTMLTextAreaElement;
/**
* Clears the current terminal selection.
*/
clearSelection(): void;
/**
* The number of rows in the terminal's viewport.
*/
rows: number;
/**
* Selects all text within the terminal.
*/
selectAll(): void;
/**
* The number of columns in the terminal's viewport.
*/
cols: number;
/**
* Focus the terminal. Delegates focus handling to the terminal's DOM element.
*/
focus(): void;
/**
* Creates a new `Terminal` object.
*
* @param options An object containing a set of options.
*/
constructor(options?: ITerminalOptions);
/**
* Find the next instance of the term, then scroll to and select it. If it
* doesn't exist, do nothing.
* @param term Tne search term.
* @return Whether a result was found.
*/
findNext(term: string): boolean;
/**
* Unfocus the terminal.
*/
blur(): void;
/**
* Find the previous instance of the term, then scroll to and select it. If it
* doesn't exist, do nothing.
* @param term Tne search term.
* @return Whether a result was found.
*/
findPrevious(term: string): boolean;
/**
* Focus the terminal.
*/
focus(): void;
/**
* Destroys the terminal.
*/
destroy(): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'blur' | 'focus' | 'lineFeed', listener: () => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'data', listener: (data?: string) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'key', listener: (key?: string, event?: KeyboardEvent) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'keypress' | 'keydown', listener: (event?: KeyboardEvent) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'refresh', listener: (data?: {start: number, end: number}) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'resize', listener: (data?: {cols: number, rows: number}) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'scroll', listener: (ydisp?: number) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'title', listener: (title?: string) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: string, listener: (...args: any[]) => void): void;
/**
* Scroll the display of the terminal
* @param disp The number of lines to scroll down (negatives scroll up).
*/
scrollDisp(disp: number): void;
/**
* Deregisters an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
off(type: 'blur' | 'focus' | 'lineFeed' | 'data' | 'key' | 'keypress' | 'keydown' | 'refresh' | 'resize' | 'scroll' | 'title' | string, listener: (...args: any[]) => void): void;
/**
* Scroll the display of the terminal by a number of pages.
* @param {number} pageCount The number of pages to scroll (negative scrolls up).
*/
scrollPages(pageCount: number): void;
/**
* Resizes the terminal.
* @param x The number of columns to resize to.
* @param y The number of rows to resize to.
*/
resize(columns: number, rows: number): void;
/**
* Scrolls the display of the terminal to the top.
*/
scrollToTop(): void;
/**
* Writes text to the terminal, followed by a break line character (\n).
* @param data The text to write to the terminal.
*/
writeln(data: string): void;
/**
* Scrolls the display of the terminal to the bottom.
*/
scrollToBottom(): void;
/**
* Opens the terminal within an element.
* @param parent The element to create the terminal within.
*/
open(parent: HTMLElement): void;
/**
* Clears the entire buffer, making the prompt line the new first line.
*/
clear(): void;
/**
* Attaches a custom key event handler which is run before keys are
* processed, giving consumers of xterm.js ultimate control as to what keys
* should be processed by the terminal and what keys should not.
* @param customKeyEventHandler The custom KeyboardEvent handler to attach.
* This is a function that takes a KeyboardEvent, allowing consumers to stop
* propogation and/or prevent the default action. The function returns
* whether the event should be processed by xterm.js.
*/
attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void;
/**
* Writes text to the terminal.
* @param data The text to write to the terminal.
*/
write(data: string): void;
/**
* (EXPERIMENTAL) Registers a link matcher, allowing custom link patterns to
* be matched and handled.
* @param regex The regular expression to search for, specifically this
* searches the textContent of the rows. You will want to use \s to match a
* space ' ' character for example.
* @param handler The callback when the link is called.
* @param options Options for the link matcher.
* @return The ID of the new matcher, this can be used to deregister.
*/
registerLinkMatcher(regex: RegExp, handler: (event: MouseEvent, uri: string) => boolean | void , options?: ILinkMatcherOptions): number;
/**
* Sets an option on the terminal.
* @param key The option key.
* @param value The option value.
*/
setOption(key: string, value: any): void;
/**
* (EXPERIMENTAL) Deregisters a link matcher if it has been registered.
* @param matcherId The link matcher's ID (returned after register)
*/
deregisterLinkMatcher(matcherId: number): void;
/**
* Tells the renderer to refresh terminal content between two rows (inclusive) at the next
* opportunity.
* @param start The row to start from (between 0 and this.rows - 1).
* @param end The row to end at (between start and this.rows - 1).
*/
refresh(start: number, end: number): void;
/**
* Gets whether the terminal has an active selection.
*/
hasSelection(): boolean;
/**
* Loads an addon, attaching it to the Terminal prototype.
* @param addon The addon to load.
*/
static loadAddon(addon: string): void;
/**
* Gets the terminal's current selection, this is useful for implementing
* copy behavior outside of xterm.js.
*/
getSelection(): string;
/**
* Clears the current terminal selection.
*/
clearSelection(): void;
/**
* Selects all text within the terminal.
*/
selectAll(): void;
// /**
// * Find the next instance of the term, then scroll to and select it. If it
// * doesn't exist, do nothing.
// * @param term Tne search term.
// * @return Whether a result was found.
// */
// findNext(term: string): boolean;
// /**
// * Find the previous instance of the term, then scroll to and select it. If it
// * doesn't exist, do nothing.
// * @param term Tne search term.
// * @return Whether a result was found.
// */
// findPrevious(term: string): boolean;
/**
* Destroys the terminal and detaches it from the DOM.
*/
destroy(): void;
/**
* Scroll the display of the terminal
* @param amount The number of lines to scroll down (negative scroll up).
*/
scrollDisp(amount: number): void;
/**
* Scroll the display of the terminal by a number of pages.
* @param pageCount The number of pages to scroll (negative scrolls up).
*/
scrollPages(pageCount: number): void;
/**
* Scrolls the display of the terminal to the top.
*/
scrollToTop(): void;
/**
* Scrolls the display of the terminal to the bottom.
*/
scrollToBottom(): void;
/**
* Clear the entire buffer, making the prompt line the new first line.
*/
clear(): void;
/**
* Writes text to the terminal.
* @param data The text to write to the terminal.
*/
write(data: string): void;
/**
* Retrieves an option's value from the terminal.
* @param key The option key.
*/
getOption(key: 'bellSound' | 'bellStyle' | 'cursorStyle' | 'termName'): string;
/**
* Retrieves an option's value from the terminal.
* @param key The option key.
*/
getOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell'): boolean;
/**
* Retrieves an option's value from the terminal.
* @param key The option key.
*/
getOption(key: 'colors'): string[];
/**
* Retrieves an option's value from the terminal.
* @param key The option key.
*/
getOption(key: 'cols' | 'rows' | 'tabStopWidth' | 'scrollback'): number;
/**
* Retrieves an option's value from the terminal.
* @param key The option key.
*/
getOption(key: 'geometry'): [number, number];
/**
* Retrieves an option's value from the terminal.
* @param key The option key.
*/
getOption(key: 'handler'): (data: string) => void;
/**
* Retrieves an option's value from the terminal.
* @param key The option key.
*/
getOption(key: string): any;
/**
* Sets an option on the terminal.
* @param key The option key.
* @param value The option value.
*/
setOption(key: 'termName' | 'bellSound', value: string): void;
/**
* Sets an option on the terminal.
* @param key The option key.
* @param value The option value.
*/
setOption(key: 'bellStyle', value: null | 'none' | 'visual' | 'sound' | 'both'): void;
/**
* Sets an option on the terminal.
* @param key The option key.
* @param value The option value.
*/
setOption(key: 'cursorStyle', value: null | 'block' | 'underline' | 'bar'): void;
/**
* Sets an option on the terminal.
* @param key The option key.
* @param value The option value.
*/
setOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell', value: boolean): void;
/**
* Sets an option on the terminal.
* @param key The option key.
* @param value The option value.
*/
setOption(key: 'colors', value: string[]): void;
/**
* Sets an option on the terminal.
* @param key The option key.
* @param value The option value.
*/
setOption(key: 'cols' | 'rows' | 'tabStopWidth' | 'scrollback', value: number): void;
/**
* Sets an option on the terminal.
* @param key The option key.
* @param value The option value.
*/
setOption(key: 'geometry', value: [number, number]): void;
/**
* Sets an option on the terminal.
* @param key The option key.
* @param value The option value.
*/
setOption(key: 'handler', value: (data: string) => void): void;
/**
* Sets an option on the terminal.
* @param key The option key.
* @param value The option value.
*/
setOption(key: string, value: any): void;
/**
* Tells the renderer to refresh terminal content between two rows
* (inclusive) at the next opportunity.
* @param start The row to start from (between 0 and this.rows - 1).
* @param end The row to end at (between start and this.rows - 1).
*/
refresh(start: number, end: number): void;
/**
* Perform a full reset (RIS, aka '\x1bc').
*/
reset(): void
/**
* Loads an addon, attaching it to the Terminal prototype and making it
* available to all newly created Terminals.
* @param addon The addon to load.
*/
static loadAddon(addon: 'attach' | 'fit' | 'fullscreen' | 'search' | 'terminado'): void;
// Moficiations to official .d.ts below
/**
* The viewport position.
*/
ydisp: number;
/**
* Emit an event on the terminal.
*/
emit(type: string, data: any): void;
/**
* Find the next instance of the term, then scroll to and select it. If it
* doesn't exist, do nothing.
* @param term Tne search term.
* @return Whether a result was found.
*/
findNext(term: string): boolean;
/**
* Find the previous instance of the term, then scroll to and select it. If it
* doesn't exist, do nothing.
* @param term Tne search term.
* @return Whether a result was found.
*/
findPrevious(term: string): boolean;
}
export = Terminal;
}
}

View file

@ -29,15 +29,15 @@ export class RGBA {
readonly b: number;
/**
* Alpha: integer in [0-255]
* Alpha: float in [0-1]
*/
readonly a: number;
constructor(r: number, g: number, b: number, a: number = 255) {
constructor(r: number, g: number, b: number, a: number = 1) {
this.r = Math.min(255, Math.max(0, r)) | 0;
this.g = Math.min(255, Math.max(0, g)) | 0;
this.b = Math.min(255, Math.max(0, b)) | 0;
this.a = Math.min(255, Math.max(0, a)) | 0;
this.a = roundFloat(Math.max(Math.min(1, a), 0), 3);
}
static equals(a: RGBA, b: RGBA): boolean {
@ -90,7 +90,7 @@ export class HSLA {
const r = rgba.r / 255;
const g = rgba.g / 255;
const b = rgba.b / 255;
const a = rgba.a / 255;
const a = rgba.a;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
@ -154,7 +154,7 @@ export class HSLA {
b = HSLA._hue2rgb(p, q, h - 1 / 3);
}
return new RGBA(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), Math.round(a * 255));
return new RGBA(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a);
}
}
@ -214,7 +214,7 @@ export class HSVA {
m = ((r - g) / delta) + 4;
}
return new HSVA(m * 60, s, cmax, rgba.a / 255);
return new HSVA(m * 60, s, cmax, rgba.a);
}
// from http://www.rapidtables.com/convert/color/hsv-to-rgb.htm
@ -249,7 +249,7 @@ export class HSVA {
g = Math.round((g + m) * 255);
b = Math.round((b + m) * 255);
return new RGBA(r, g, b, Math.round(a * 255));
return new RGBA(r, g, b, a);
}
}
@ -349,7 +349,7 @@ export class Color {
transparent(factor: number): Color {
const { r, g, b, a } = this.rgba;
return new Color(new RGBA(r, g, b, Math.round(a * factor)));
return new Color(new RGBA(r, g, b, a * factor));
}
isTransparent(): boolean {
@ -357,7 +357,7 @@ export class Color {
}
isOpaque(): boolean {
return this.rgba.a === 255;
return this.rgba.a === 1;
}
opposite(): Color {
@ -368,8 +368,8 @@ export class Color {
const rgba = c.rgba;
// Convert to 0..1 opacity
const thisA = this.rgba.a / 255;
const colorA = rgba.a / 255;
const thisA = this.rgba.a;
const colorA = rgba.a;
let a = thisA + colorA * (1 - thisA);
if (a < 1.0e-6) {
@ -379,7 +379,6 @@ export class Color {
const r = this.rgba.r * thisA / a + rgba.r * colorA * (1 - thisA) / a;
const g = this.rgba.g * thisA / a + rgba.g * colorA * (1 - thisA) / a;
const b = this.rgba.b * thisA / a + rgba.b * colorA * (1 - thisA) / a;
a *= 255;
return new Color(new RGBA(r, g, b, a));
}
@ -410,13 +409,13 @@ export class Color {
return of.darken(factor);
}
static readonly white = new Color(new RGBA(255, 255, 255, 255));
static readonly black = new Color(new RGBA(0, 0, 0, 255));
static readonly red = new Color(new RGBA(255, 0, 0, 255));
static readonly blue = new Color(new RGBA(0, 0, 255, 255));
static readonly green = new Color(new RGBA(0, 255, 0, 255));
static readonly cyan = new Color(new RGBA(0, 255, 255, 255));
static readonly lightgrey = new Color(new RGBA(211, 211, 211, 255));
static readonly white = new Color(new RGBA(255, 255, 255, 1));
static readonly black = new Color(new RGBA(0, 0, 0, 1));
static readonly red = new Color(new RGBA(255, 0, 0, 1));
static readonly blue = new Color(new RGBA(0, 0, 255, 1));
static readonly green = new Color(new RGBA(0, 255, 0, 1));
static readonly cyan = new Color(new RGBA(0, 255, 255, 1));
static readonly lightgrey = new Color(new RGBA(211, 211, 211, 1));
static readonly transparent = new Color(new RGBA(0, 0, 0, 0));
}
@ -425,7 +424,7 @@ export namespace Color {
export namespace CSS {
export function formatRGB(color: Color): string {
if (color.rgba.a === 255) {
if (color.rgba.a === 1) {
return `rgb(${color.rgba.r}, ${color.rgba.g}, ${color.rgba.b})`;
}
@ -433,7 +432,7 @@ export namespace Color {
}
export function formatRGBA(color: Color): string {
return `rgba(${color.rgba.r}, ${color.rgba.g}, ${color.rgba.b}, ${+(color.rgba.a / 255).toFixed(2)})`;
return `rgba(${color.rgba.r}, ${color.rgba.g}, ${color.rgba.b}, ${+(color.rgba.a).toFixed(2)})`;
}
export function formatHSL(color: Color): string {
@ -465,11 +464,11 @@ export namespace Color {
* If 'compact' is set, colors without transparancy will be printed as #RRGGBB
*/
export function formatHexA(color: Color, compact = false): string {
if (compact && color.rgba.a === 0xFF) {
if (compact && color.rgba.a === 1) {
return Color.Format.CSS.formatHex(color);
}
return `#${_toTwoDigitHex(color.rgba.r)}${_toTwoDigitHex(color.rgba.g)}${_toTwoDigitHex(color.rgba.b)}${_toTwoDigitHex(color.rgba.a)}`;
return `#${_toTwoDigitHex(color.rgba.r)}${_toTwoDigitHex(color.rgba.g)}${_toTwoDigitHex(color.rgba.b)}${_toTwoDigitHex(Math.round(color.rgba.a * 255))}`;
}
/**
@ -515,7 +514,7 @@ export namespace Color {
const r = 16 * _parseHexDigit(hex.charCodeAt(1)) + _parseHexDigit(hex.charCodeAt(2));
const g = 16 * _parseHexDigit(hex.charCodeAt(3)) + _parseHexDigit(hex.charCodeAt(4));
const b = 16 * _parseHexDigit(hex.charCodeAt(5)) + _parseHexDigit(hex.charCodeAt(6));
return new Color(new RGBA(r, g, b, 255));
return new Color(new RGBA(r, g, b, 1));
}
if (length === 9) {
@ -524,7 +523,7 @@ export namespace Color {
const g = 16 * _parseHexDigit(hex.charCodeAt(3)) + _parseHexDigit(hex.charCodeAt(4));
const b = 16 * _parseHexDigit(hex.charCodeAt(5)) + _parseHexDigit(hex.charCodeAt(6));
const a = 16 * _parseHexDigit(hex.charCodeAt(7)) + _parseHexDigit(hex.charCodeAt(8));
return new Color(new RGBA(r, g, b, a));
return new Color(new RGBA(r, g, b, a / 255));
}
if (length === 4) {
@ -541,7 +540,7 @@ export namespace Color {
const g = _parseHexDigit(hex.charCodeAt(2));
const b = _parseHexDigit(hex.charCodeAt(3));
const a = _parseHexDigit(hex.charCodeAt(4));
return new Color(new RGBA(16 * r + r, 16 * g + g, 16 * b + b, 16 * a + a));
return new Color(new RGBA(16 * r + r, 16 * g + g, 16 * b + b, (16 * a + a) / 255));
}
// Invalid color

View file

@ -132,26 +132,35 @@ export function setUnexpectedErrorHandler(newUnexpectedErrorHandler: (e: any) =>
errorHandler.setUnexpectedErrorHandler(newUnexpectedErrorHandler);
}
export function onUnexpectedError(e: any): void {
export function onUnexpectedError(e: any): undefined {
// ignore errors from cancelled promises
if (!isPromiseCanceledError(e)) {
errorHandler.onUnexpectedError(e);
}
return undefined;
}
export function onUnexpectedExternalError(e: any): void {
export function onUnexpectedExternalError(e: any): undefined {
// ignore errors from cancelled promises
if (!isPromiseCanceledError(e)) {
errorHandler.onUnexpectedExternalError(e);
}
return undefined;
}
export function onUnexpectedPromiseError<T>(promise: TPromise<T>): TPromise<T> {
return promise.then<T>(null, onUnexpectedError);
export function onUnexpectedPromiseError<T>(promise: TPromise<T>): TPromise<T | void> {
return promise.then(null, onUnexpectedError);
}
export interface SerializedError {
readonly $isError: true;
readonly name: string;
readonly message: string;
readonly stack: string;
}
export function transformErrorForSerialization(error: Error): SerializedError;
export function transformErrorForSerialization(error: any): any;
export function transformErrorForSerialization(error: any): any {
if (error instanceof Error) {
let { name, message } = error;
@ -168,6 +177,24 @@ export function transformErrorForSerialization(error: any): any {
return error;
}
// see https://github.com/v8/v8/wiki/Stack%20Trace%20API#basic-stack-traces
export interface V8CallSite {
getThis(): any;
getTypeName(): string;
getFunction(): string;
getFunctionName(): string;
getMethodName(): string;
getFileName(): string;
getLineNumber(): number;
getColumnNumber(): number;
getEvalOrigin(): string;
isToplevel(): boolean;
isEval(): boolean;
isNative(): boolean;
isConstructor(): boolean;
toString(): string;
}
const canceledName = 'Canceled';
/**

View file

@ -110,6 +110,7 @@ export function tildify(path: string, userHome: string): string {
*/
const ellipsis = '\u2026';
const unc = '\\\\';
const home = '~';
export function shorten(paths: string[]): string[] {
const shortenedPaths: string[] = new Array(paths.length);
@ -130,7 +131,7 @@ export function shorten(paths: string[]): string[] {
match = true;
// trim for now and concatenate unc path (e.g. \\network) or root path (/etc) later
// trim for now and concatenate unc path (e.g. \\network) or root path (/etc, ~/etc) later
let prefix = '';
if (path.indexOf(unc) === 0) {
prefix = path.substr(0, path.indexOf(unc) + unc.length);
@ -138,6 +139,9 @@ export function shorten(paths: string[]): string[] {
} else if (path.indexOf(nativeSep) === 0) {
prefix = path.substr(0, path.indexOf(nativeSep) + nativeSep.length);
path = path.substr(path.indexOf(nativeSep) + nativeSep.length);
} else if (path.indexOf(home) === 0) {
prefix = path.substr(0, path.indexOf(home) + home.length);
path = path.substr(path.indexOf(home) + home.length);
}
// pick the first shortest subpath found

View file

@ -238,7 +238,7 @@ export class TrieMap<E> {
private readonly _splitter: (s: string) => string[];
private _root = new Node<E>();
constructor(splitter: (s: string) => string[]) {
constructor(splitter: (s: string) => string[] = TrieMap.PathSplitter) {
this._splitter = s => splitter(s).filter(s => Boolean(s));
}

View file

@ -182,18 +182,6 @@ export function endsWith(haystack: string, needle: string): boolean {
}
}
export function indexOfIgnoreCase(haystack: string, needle: string, position: number = 0): number {
let index = haystack.indexOf(needle, position);
if (index < 0) {
if (position > 0) {
haystack = haystack.substr(position);
}
needle = escapeRegExpCharacters(needle);
index = haystack.search(new RegExp(needle, 'i'));
}
return index;
}
export interface RegExpOptions {
matchCase?: boolean;
wholeWord?: boolean;

View file

@ -4,110 +4,47 @@
*--------------------------------------------------------------------------------------------*/
/// Interfaces for WinJS
export interface ValueCallback {
(value: any): any;
}
export type ErrorCallback = (error: any) => void;
export type ProgressCallback<TProgress = any> = (progress: TProgress) => void;
export interface EventCallback {
(value: any): void;
}
export declare class Promise<T = any, TProgress = any> {
constructor(
executor: (
resolve: (value: T | PromiseLike<T>) => void,
reject: (reason: any) => void,
progress: (progress: TProgress) => void) => void,
oncancel?: () => void);
export interface ErrorCallback {
(error: any): any;
}
public then<TResult1 = T, TResult2 = never>(
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,
onprogress?: (progress: TProgress) => void): Promise<TResult1 | TResult2, TProgress>;
export interface ProgressCallback {
(progress: any): any;
}
public done(
onfulfilled?: (value: T) => void,
onrejected?: (reason: any) => void,
onprogress?: (progress: TProgress) => void): void;
export declare class Promise {
// commented out because this conflicts with the native promise
// constructor(init: (complete: ValueCallback, error: ErrorCallback, progress: ProgressCallback) => void, oncancel?: any);
// commented out to speed up adoption of TPromise
// static as(value:any):Promise;
// static join(promises: { [name: string]: Promise; }): Promise;
static join(promises: Promise[]): Promise;
// static any(promises: Promise[]): Promise;
// commented out to speed up adoption of TPromise
// static timeout(delay:number):Promise;
// static wrapError(error: Error): Promise;
// static is(value: any): value is Thenable<any>;
// static addEventListener(type: string, fn: EventCallback): void;
public then(success?: ValueCallback, error?: ErrorCallback, progress?: ProgressCallback): Promise;
// public then<U>(success?: ValueCallback, error?: ErrorCallback, progress?: ProgressCallback): TPromise<U>;
public done(success?: ValueCallback, error?: ErrorCallback, progress?: ProgressCallback): void;
public cancel(): void;
}
/**
* The value callback to complete a promise
*/
export interface TValueCallback<T> {
(value: T | Thenable<T>): void;
}
export interface TProgressCallback<T> {
(progress: T): void;
}
interface IPromiseErrorDetail {
parent: TPromise<any>;
error: any;
id: number;
handler: Function;
exception: Error;
}
interface IPromiseError {
detail: IPromiseErrorDetail;
}
/**
* A Promise implementation that supports progress and cancelation.
*/
export declare class TPromise<V> {
constructor(init: (complete: TValueCallback<V>, error: (err: any) => void, progress: ProgressCallback) => void, oncancel?: any);
public then<U>(success?: (value: V) => TPromise<U>, error?: (err: any) => TPromise<U>, progress?: ProgressCallback): TPromise<U>;
public then<U>(success?: (value: V) => TPromise<U>, error?: (err: any) => TPromise<U> | U, progress?: ProgressCallback): TPromise<U>;
public then<U>(success?: (value: V) => TPromise<U>, error?: (err: any) => U, progress?: ProgressCallback): TPromise<U>;
public then<U>(success?: (value: V) => TPromise<U>, error?: (err: any) => void, progress?: ProgressCallback): TPromise<U>;
public then<U>(success?: (value: V) => TPromise<U> | U, error?: (err: any) => TPromise<U>, progress?: ProgressCallback): TPromise<U>;
public then<U>(success?: (value: V) => TPromise<U> | U, error?: (err: any) => TPromise<U> | U, progress?: ProgressCallback): TPromise<U>;
public then<U>(success?: (value: V) => TPromise<U> | U, error?: (err: any) => U, progress?: ProgressCallback): TPromise<U>;
public then<U>(success?: (value: V) => TPromise<U> | U, error?: (err: any) => void, progress?: ProgressCallback): TPromise<U>;
public then<U>(success?: (value: V) => U, error?: (err: any) => TPromise<U>, progress?: ProgressCallback): TPromise<U>;
public then<U>(success?: (value: V) => U, error?: (err: any) => TPromise<U> | U, progress?: ProgressCallback): TPromise<U>;
public then<U>(success?: (value: V) => U, error?: (err: any) => U, progress?: ProgressCallback): TPromise<U>;
public then<U>(success?: (value: V) => U, error?: (err: any) => void, progress?: ProgressCallback): TPromise<U>;
public done(success?: (value: V) => void, error?: (err: any) => any, progress?: ProgressCallback): void;
public cancel(): void;
public static as(value: null): TPromise<null>;
public static as(value: undefined): TPromise<undefined>;
public static as<ValueType>(value: TPromise<ValueType>): TPromise<ValueType>;
public static as<ValueType>(value: Thenable<ValueType>): Thenable<ValueType>;
public static as<ValueType>(value: ValueType): TPromise<ValueType>;
public static as(value: null): Promise<null>;
public static as(value: undefined): Promise<undefined>;
public static as<T, TPromise extends PromiseLike<T>>(value: TPromise): TPromise;
public static as<T>(value: T): Promise<T>;
public static is(value: any): value is Thenable<any>;
public static timeout(delay: number): TPromise<void>;
public static join<ValueType>(promises: TPromise<ValueType>[]): TPromise<ValueType[]>;
public static join<ValueType>(promises: Thenable<ValueType>[]): Thenable<ValueType[]>;
public static join<ValueType>(promises: { [n: string]: TPromise<ValueType> }): TPromise<{ [n: string]: ValueType }>;
public static any<ValueType>(promises: TPromise<ValueType>[]): TPromise<{ key: string; value: TPromise<ValueType>; }>;
public static is(value: any): value is PromiseLike<any>;
public static wrap<ValueType>(value: Thenable<ValueType>): TPromise<ValueType>;
public static wrap<ValueType>(value: ValueType): TPromise<ValueType>;
public static timeout(delay: number): Promise<void>;
public static wrapError<ValueType>(error: Error): TPromise<ValueType>;
public static join<T1, T2>(promises: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<[T1, T2]>;
public static join<T>(promises: (T | PromiseLike<T>)[]): Promise<T[]>;
public static join<T>(promises: { [n: string]: T | PromiseLike<T> }): Promise<{ [n: string]: T }>;
public static any<T>(promises: (T | PromiseLike<T>)[]): Promise<{ key: string; value: Promise<T>; }>;
public static wrap<T>(value: T | PromiseLike<T>): Promise<T>;
public static wrapError<T = never>(error: Error): Promise<T>;
/**
* @internal
@ -115,25 +52,23 @@ export declare class TPromise<V> {
public static addEventListener(event: 'error', promiseErrorHandler: (e: IPromiseError) => void);
}
// --- Generic promise with generic progress value
export declare class PPromise<C, P> extends TPromise<C> {
export type TValueCallback<T = any> = (value: T | PromiseLike<T>) => void;
constructor(init: (complete: TValueCallback<C>, error: (err: any) => void, progress: TProgressCallback<P>) => void, oncancel?: any);
export {
Promise as TPromise,
Promise as PPromise,
TValueCallback as ValueCallback,
ProgressCallback as TProgressCallback
};
public then<U>(success?: (value: C) => PPromise<U, P>, error?: (err: any) => PPromise<U, P>, progress?: (value: P) => void): PPromise<U, P>;
public then<U>(success?: (value: C) => PPromise<U, P>, error?: (err: any) => U, progress?: (value: P) => void): PPromise<U, P>;
public then<U>(success?: (value: C) => PPromise<U, P>, error?: (err: any) => void, progress?: (value: P) => void): PPromise<U, P>;
public then<U>(success?: (value: C) => U, error?: (err: any) => PPromise<C, P>, progress?: (value: P) => void): PPromise<U, P>;
public then<U>(success?: (value: C) => U, error?: (err: any) => U, progress?: (value: P) => void): PPromise<U, P>;
public then<U>(success?: (value: C) => U, error?: (err: any) => void, progress?: (value: P) => void): PPromise<U, P>;
public done(success?: (value: C) => void, error?: (err: any) => any, progress?: (value: P) => void): void;
public cancel(): void;
public static as<V>(value: V): TPromise<V>;
public static timeout(delay: number): PPromise<void, void>;
public static join<C, P>(promises: PPromise<C, P>[]): PPromise<C, P[]>;
public static join<C, P>(promises: { [n: string]: PPromise<C, P> }): PPromise<{ [n: string]: C }, P>;
public static any<C, P>(promises: PPromise<C, P>[]): PPromise<{ key: string; value: PPromise<C, P>; }, P>;
public static wrapError<V>(error: Error): TPromise<V>;
export interface IPromiseErrorDetail {
parent: Promise;
error: any;
id: number;
handler: Function;
exception: Error;
}
export interface IPromiseError {
detail: IPromiseErrorDetail;
}

View file

@ -58,59 +58,61 @@ async function getNodeRequest(options: IRequestOptions): TPromise<IRawRequestFun
export function request(options: IRequestOptions): TPromise<IRequestContext> {
let req: http.ClientRequest;
return new TPromise<IRequestContext>(async (c, e) => {
const endpoint = parseUrl(options.url);
const rawRequest = options.getRawRequest
? options.getRawRequest(options)
: await getNodeRequest(options);
const rawRequestPromise = options.getRawRequest
? TPromise.as(options.getRawRequest(options))
: getNodeRequest(options);
const opts: https.RequestOptions = {
hostname: endpoint.hostname,
port: endpoint.port ? parseInt(endpoint.port) : (endpoint.protocol === 'https:' ? 443 : 80),
protocol: endpoint.protocol,
path: endpoint.path,
method: options.type || 'GET',
headers: options.headers,
agent: options.agent,
rejectUnauthorized: isBoolean(options.strictSSL) ? options.strictSSL : true
};
return rawRequestPromise.then(rawRequest => {
return new TPromise<IRequestContext>((c, e) => {
const endpoint = parseUrl(options.url);
if (options.user && options.password) {
opts.auth = options.user + ':' + options.password;
}
const opts: https.RequestOptions = {
hostname: endpoint.hostname,
port: endpoint.port ? parseInt(endpoint.port) : (endpoint.protocol === 'https:' ? 443 : 80),
protocol: endpoint.protocol,
path: endpoint.path,
method: options.type || 'GET',
headers: options.headers,
agent: options.agent,
rejectUnauthorized: isBoolean(options.strictSSL) ? options.strictSSL : true
};
req = rawRequest(opts, (res: http.ClientResponse) => {
const followRedirects = isNumber(options.followRedirects) ? options.followRedirects : 3;
if (res.statusCode >= 300 && res.statusCode < 400 && followRedirects > 0 && res.headers['location']) {
request(assign({}, options, {
url: res.headers['location'],
followRedirects: followRedirects - 1
})).done(c, e);
} else {
let stream: Stream = res;
if (res.headers['content-encoding'] === 'gzip') {
stream = stream.pipe(createGunzip());
}
c({ res, stream });
if (options.user && options.password) {
opts.auth = options.user + ':' + options.password;
}
});
req.on('error', e);
req = rawRequest(opts, (res: http.ClientResponse) => {
const followRedirects = isNumber(options.followRedirects) ? options.followRedirects : 3;
if (options.timeout) {
req.setTimeout(options.timeout);
}
if (res.statusCode >= 300 && res.statusCode < 400 && followRedirects > 0 && res.headers['location']) {
request(assign({}, options, {
url: res.headers['location'],
followRedirects: followRedirects - 1
})).done(c, e);
} else {
let stream: Stream = res;
if (options.data) {
req.write(options.data);
}
if (res.headers['content-encoding'] === 'gzip') {
stream = stream.pipe(createGunzip());
}
req.end();
},
() => req && req.abort());
c({ res, stream });
}
});
req.on('error', e);
if (options.timeout) {
req.setTimeout(options.timeout);
}
if (options.data) {
req.write(options.data);
}
req.end();
}, () => req && req.abort());
});
}
function isSuccess(context: IRequestContext): boolean {

View file

@ -340,6 +340,10 @@ export class QuickOpenWidget implements IModelProvider {
// Allows focus to switch to next/previous entry after tab into an actionbar item
DOM.addDisposableListener(this.treeContainer.getHTMLElement(), DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
const keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e);
// Only handle when not in quick navigation mode
if (this.quickNavigateConfiguration) {
return;
}
if (keyboardEvent.keyCode === KeyCode.DownArrow || keyboardEvent.keyCode === KeyCode.UpArrow || keyboardEvent.keyCode === KeyCode.PageDown || keyboardEvent.keyCode === KeyCode.PageUp) {
DOM.EventHelper.stop(e, true);
this.navigateInTree(keyboardEvent.keyCode, keyboardEvent.shiftKey);

View file

@ -51,133 +51,133 @@ suite('Color', () => {
});
test('luminance', function () {
assert.deepEqual(0, new Color(new RGBA(0, 0, 0, 255)).getRelativeLuminance());
assert.deepEqual(1, new Color(new RGBA(255, 255, 255, 255)).getRelativeLuminance());
assert.deepEqual(0, new Color(new RGBA(0, 0, 0, 1)).getRelativeLuminance());
assert.deepEqual(1, new Color(new RGBA(255, 255, 255, 1)).getRelativeLuminance());
assert.deepEqual(0.2126, new Color(new RGBA(255, 0, 0, 255)).getRelativeLuminance());
assert.deepEqual(0.7152, new Color(new RGBA(0, 255, 0, 255)).getRelativeLuminance());
assert.deepEqual(0.0722, new Color(new RGBA(0, 0, 255, 255)).getRelativeLuminance());
assert.deepEqual(0.2126, new Color(new RGBA(255, 0, 0, 1)).getRelativeLuminance());
assert.deepEqual(0.7152, new Color(new RGBA(0, 255, 0, 1)).getRelativeLuminance());
assert.deepEqual(0.0722, new Color(new RGBA(0, 0, 255, 1)).getRelativeLuminance());
assert.deepEqual(0.9278, new Color(new RGBA(255, 255, 0, 255)).getRelativeLuminance());
assert.deepEqual(0.7874, new Color(new RGBA(0, 255, 255, 255)).getRelativeLuminance());
assert.deepEqual(0.2848, new Color(new RGBA(255, 0, 255, 255)).getRelativeLuminance());
assert.deepEqual(0.9278, new Color(new RGBA(255, 255, 0, 1)).getRelativeLuminance());
assert.deepEqual(0.7874, new Color(new RGBA(0, 255, 255, 1)).getRelativeLuminance());
assert.deepEqual(0.2848, new Color(new RGBA(255, 0, 255, 1)).getRelativeLuminance());
assert.deepEqual(0.5271, new Color(new RGBA(192, 192, 192, 255)).getRelativeLuminance());
assert.deepEqual(0.5271, new Color(new RGBA(192, 192, 192, 1)).getRelativeLuminance());
assert.deepEqual(0.2159, new Color(new RGBA(128, 128, 128, 255)).getRelativeLuminance());
assert.deepEqual(0.0459, new Color(new RGBA(128, 0, 0, 255)).getRelativeLuminance());
assert.deepEqual(0.2003, new Color(new RGBA(128, 128, 0, 255)).getRelativeLuminance());
assert.deepEqual(0.1544, new Color(new RGBA(0, 128, 0, 255)).getRelativeLuminance());
assert.deepEqual(0.0615, new Color(new RGBA(128, 0, 128, 255)).getRelativeLuminance());
assert.deepEqual(0.17, new Color(new RGBA(0, 128, 128, 255)).getRelativeLuminance());
assert.deepEqual(0.0156, new Color(new RGBA(0, 0, 128, 255)).getRelativeLuminance());
assert.deepEqual(0.2159, new Color(new RGBA(128, 128, 128, 1)).getRelativeLuminance());
assert.deepEqual(0.0459, new Color(new RGBA(128, 0, 0, 1)).getRelativeLuminance());
assert.deepEqual(0.2003, new Color(new RGBA(128, 128, 0, 1)).getRelativeLuminance());
assert.deepEqual(0.1544, new Color(new RGBA(0, 128, 0, 1)).getRelativeLuminance());
assert.deepEqual(0.0615, new Color(new RGBA(128, 0, 128, 1)).getRelativeLuminance());
assert.deepEqual(0.17, new Color(new RGBA(0, 128, 128, 1)).getRelativeLuminance());
assert.deepEqual(0.0156, new Color(new RGBA(0, 0, 128, 1)).getRelativeLuminance());
});
test('blending', function () {
assert.deepEqual(new Color(new RGBA(0, 0, 0, 0)).blend(new Color(new RGBA(243, 34, 43))), new Color(new RGBA(243, 34, 43)));
assert.deepEqual(new Color(new RGBA(255, 255, 255)).blend(new Color(new RGBA(243, 34, 43))), new Color(new RGBA(255, 255, 255)));
assert.deepEqual(new Color(new RGBA(122, 122, 122, 178.5)).blend(new Color(new RGBA(243, 34, 43))), new Color(new RGBA(158, 95, 98)));
assert.deepEqual(new Color(new RGBA(0, 0, 0, 147.9)).blend(new Color(new RGBA(255, 255, 255, 84.15))), new Color(new RGBA(49, 49, 49, 182)));
assert.deepEqual(new Color(new RGBA(122, 122, 122, 0.7)).blend(new Color(new RGBA(243, 34, 43))), new Color(new RGBA(158, 95, 98)));
assert.deepEqual(new Color(new RGBA(0, 0, 0, 0.58)).blend(new Color(new RGBA(255, 255, 255, 0.33))), new Color(new RGBA(49, 49, 49, 0.719)));
});
suite('HSLA', () => {
test('HSLA.toRGBA', function () {
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 0, 0)), new RGBA(0, 0, 0, 0));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 0, 1)), new RGBA(0, 0, 0, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 1, 1)), new RGBA(255, 255, 255, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 0, 1)), new RGBA(0, 0, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 1, 1)), new RGBA(255, 255, 255, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 1, 0.5, 1)), new RGBA(255, 0, 0, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(120, 1, 0.5, 1)), new RGBA(0, 255, 0, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(240, 1, 0.5, 1)), new RGBA(0, 0, 255, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 1, 0.5, 1)), new RGBA(255, 0, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(120, 1, 0.5, 1)), new RGBA(0, 255, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(240, 1, 0.5, 1)), new RGBA(0, 0, 255, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(60, 1, 0.5, 1)), new RGBA(255, 255, 0, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(180, 1, 0.5, 1)), new RGBA(0, 255, 255, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(300, 1, 0.5, 1)), new RGBA(255, 0, 255, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(60, 1, 0.5, 1)), new RGBA(255, 255, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(180, 1, 0.5, 1)), new RGBA(0, 255, 255, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(300, 1, 0.5, 1)), new RGBA(255, 0, 255, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 0.753, 1)), new RGBA(192, 192, 192, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 0.753, 1)), new RGBA(192, 192, 192, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 0.502, 1)), new RGBA(128, 128, 128, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 1, 0.251, 1)), new RGBA(128, 0, 0, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(60, 1, 0.251, 1)), new RGBA(128, 128, 0, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(120, 1, 0.251, 1)), new RGBA(0, 128, 0, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(300, 1, 0.251, 1)), new RGBA(128, 0, 128, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(180, 1, 0.251, 1)), new RGBA(0, 128, 128, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(240, 1, 0.251, 1)), new RGBA(0, 0, 128, 255));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 0.502, 1)), new RGBA(128, 128, 128, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 1, 0.251, 1)), new RGBA(128, 0, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(60, 1, 0.251, 1)), new RGBA(128, 128, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(120, 1, 0.251, 1)), new RGBA(0, 128, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(300, 1, 0.251, 1)), new RGBA(128, 0, 128, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(180, 1, 0.251, 1)), new RGBA(0, 128, 128, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(240, 1, 0.251, 1)), new RGBA(0, 0, 128, 1));
});
test('HSLA.fromRGBA', function () {
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 0, 0, 0)), new HSLA(0, 0, 0, 0));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 0, 0, 255)), new HSLA(0, 0, 0, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(255, 255, 255, 255)), new HSLA(0, 0, 1, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 0, 0, 1)), new HSLA(0, 0, 0, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(255, 255, 255, 1)), new HSLA(0, 0, 1, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(255, 0, 0, 255)), new HSLA(0, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 255, 0, 255)), new HSLA(120, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 0, 255, 255)), new HSLA(240, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(255, 0, 0, 1)), new HSLA(0, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 255, 0, 1)), new HSLA(120, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 0, 255, 1)), new HSLA(240, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(255, 255, 0, 255)), new HSLA(60, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 255, 255, 255)), new HSLA(180, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(255, 0, 255, 255)), new HSLA(300, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(255, 255, 0, 1)), new HSLA(60, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 255, 255, 1)), new HSLA(180, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(255, 0, 255, 1)), new HSLA(300, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(192, 192, 192, 255)), new HSLA(0, 0, 0.753, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(192, 192, 192, 1)), new HSLA(0, 0, 0.753, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(128, 128, 128, 255)), new HSLA(0, 0, 0.502, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(128, 0, 0, 255)), new HSLA(0, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(128, 128, 0, 255)), new HSLA(60, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 128, 0, 255)), new HSLA(120, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(128, 0, 128, 255)), new HSLA(300, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 128, 128, 255)), new HSLA(180, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 0, 128, 255)), new HSLA(240, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(128, 128, 128, 1)), new HSLA(0, 0, 0.502, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(128, 0, 0, 1)), new HSLA(0, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(128, 128, 0, 1)), new HSLA(60, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 128, 0, 1)), new HSLA(120, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(128, 0, 128, 1)), new HSLA(300, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 128, 128, 1)), new HSLA(180, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 0, 128, 1)), new HSLA(240, 1, 0.251, 1));
});
});
suite('HSVA', () => {
test('HSVA.toRGBA', function () {
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 0, 0)), new RGBA(0, 0, 0, 0));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 0, 1)), new RGBA(0, 0, 0, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 1, 1)), new RGBA(255, 255, 255, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 0, 1)), new RGBA(0, 0, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 1, 1)), new RGBA(255, 255, 255, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 1, 1, 1)), new RGBA(255, 0, 0, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(120, 1, 1, 1)), new RGBA(0, 255, 0, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(240, 1, 1, 1)), new RGBA(0, 0, 255, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 1, 1, 1)), new RGBA(255, 0, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(120, 1, 1, 1)), new RGBA(0, 255, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(240, 1, 1, 1)), new RGBA(0, 0, 255, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(60, 1, 1, 1)), new RGBA(255, 255, 0, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(180, 1, 1, 1)), new RGBA(0, 255, 255, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(300, 1, 1, 1)), new RGBA(255, 0, 255, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(60, 1, 1, 1)), new RGBA(255, 255, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(180, 1, 1, 1)), new RGBA(0, 255, 255, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(300, 1, 1, 1)), new RGBA(255, 0, 255, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 0.753, 1)), new RGBA(192, 192, 192, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 0.753, 1)), new RGBA(192, 192, 192, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 0.502, 1)), new RGBA(128, 128, 128, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 1, 0.502, 1)), new RGBA(128, 0, 0, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(60, 1, 0.502, 1)), new RGBA(128, 128, 0, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(120, 1, 0.502, 1)), new RGBA(0, 128, 0, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(300, 1, 0.502, 1)), new RGBA(128, 0, 128, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(180, 1, 0.502, 1)), new RGBA(0, 128, 128, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(240, 1, 0.502, 1)), new RGBA(0, 0, 128, 255));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 0.502, 1)), new RGBA(128, 128, 128, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 1, 0.502, 1)), new RGBA(128, 0, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(60, 1, 0.502, 1)), new RGBA(128, 128, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(120, 1, 0.502, 1)), new RGBA(0, 128, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(300, 1, 0.502, 1)), new RGBA(128, 0, 128, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(180, 1, 0.502, 1)), new RGBA(0, 128, 128, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(240, 1, 0.502, 1)), new RGBA(0, 0, 128, 1));
});
test('HSVA.fromRGBA', () => {
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 0, 0, 0)), new HSVA(0, 0, 0, 0));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 0, 0, 255)), new HSVA(0, 0, 0, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(255, 255, 255, 255)), new HSVA(0, 0, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 0, 0, 1)), new HSVA(0, 0, 0, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(255, 255, 255, 1)), new HSVA(0, 0, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(255, 0, 0, 255)), new HSVA(0, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 255, 0, 255)), new HSVA(120, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 0, 255, 255)), new HSVA(240, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(255, 0, 0, 1)), new HSVA(0, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 255, 0, 1)), new HSVA(120, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 0, 255, 1)), new HSVA(240, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(255, 255, 0, 255)), new HSVA(60, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 255, 255, 255)), new HSVA(180, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(255, 0, 255, 255)), new HSVA(300, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(255, 255, 0, 1)), new HSVA(60, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 255, 255, 1)), new HSVA(180, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(255, 0, 255, 1)), new HSVA(300, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(192, 192, 192, 255)), new HSVA(0, 0, 0.753, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(192, 192, 192, 1)), new HSVA(0, 0, 0.753, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(128, 128, 128, 255)), new HSVA(0, 0, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(128, 0, 0, 255)), new HSVA(0, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(128, 128, 0, 255)), new HSVA(60, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 128, 0, 255)), new HSVA(120, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(128, 0, 128, 255)), new HSVA(300, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 128, 128, 255)), new HSVA(180, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 0, 128, 255)), new HSVA(240, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(128, 128, 128, 1)), new HSVA(0, 0, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(128, 0, 0, 1)), new HSVA(0, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(128, 128, 0, 1)), new HSVA(60, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 128, 0, 1)), new HSVA(120, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(128, 0, 128, 1)), new HSVA(300, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 128, 128, 1)), new HSVA(180, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 0, 128, 1)), new HSVA(240, 1, 0.502, 1));
});
});
@ -192,44 +192,44 @@ suite('Color', () => {
assert.deepEqual(Color.Format.CSS.parseHex('#0102030'), null);
// somewhat valid
assert.deepEqual(Color.Format.CSS.parseHex('#FFFFG0').rgba, new RGBA(255, 255, 0, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#FFFFg0').rgba, new RGBA(255, 255, 0, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#-FFF00').rgba, new RGBA(15, 255, 0, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#FFFFG0').rgba, new RGBA(255, 255, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#FFFFg0').rgba, new RGBA(255, 255, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#-FFF00').rgba, new RGBA(15, 255, 0, 1));
// valid
assert.deepEqual(Color.Format.CSS.parseHex('#000000').rgba, new RGBA(0, 0, 0, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#FFFFFF').rgba, new RGBA(255, 255, 255, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#000000').rgba, new RGBA(0, 0, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#FFFFFF').rgba, new RGBA(255, 255, 255, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#FF0000').rgba, new RGBA(255, 0, 0, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#00FF00').rgba, new RGBA(0, 255, 0, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#0000FF').rgba, new RGBA(0, 0, 255, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#FF0000').rgba, new RGBA(255, 0, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#00FF00').rgba, new RGBA(0, 255, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0000FF').rgba, new RGBA(0, 0, 255, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#FFFF00').rgba, new RGBA(255, 255, 0, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#00FFFF').rgba, new RGBA(0, 255, 255, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#FF00FF').rgba, new RGBA(255, 0, 255, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#FFFF00').rgba, new RGBA(255, 255, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#00FFFF').rgba, new RGBA(0, 255, 255, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#FF00FF').rgba, new RGBA(255, 0, 255, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#C0C0C0').rgba, new RGBA(192, 192, 192, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#C0C0C0').rgba, new RGBA(192, 192, 192, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#808080').rgba, new RGBA(128, 128, 128, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#800000').rgba, new RGBA(128, 0, 0, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#808000').rgba, new RGBA(128, 128, 0, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#008000').rgba, new RGBA(0, 128, 0, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#800080').rgba, new RGBA(128, 0, 128, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#008080').rgba, new RGBA(0, 128, 128, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#000080').rgba, new RGBA(0, 0, 128, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#808080').rgba, new RGBA(128, 128, 128, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#800000').rgba, new RGBA(128, 0, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#808000').rgba, new RGBA(128, 128, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#008000').rgba, new RGBA(0, 128, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#800080').rgba, new RGBA(128, 0, 128, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#008080').rgba, new RGBA(0, 128, 128, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#000080').rgba, new RGBA(0, 0, 128, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#010203').rgba, new RGBA(1, 2, 3, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#040506').rgba, new RGBA(4, 5, 6, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#070809').rgba, new RGBA(7, 8, 9, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#0a0A0a').rgba, new RGBA(10, 10, 10, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#0b0B0b').rgba, new RGBA(11, 11, 11, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#0c0C0c').rgba, new RGBA(12, 12, 12, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#0d0D0d').rgba, new RGBA(13, 13, 13, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#0e0E0e').rgba, new RGBA(14, 14, 14, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#0f0F0f').rgba, new RGBA(15, 15, 15, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#a0A0a0').rgba, new RGBA(160, 160, 160, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#CFA').rgba, new RGBA(204, 255, 170, 255));
assert.deepEqual(Color.Format.CSS.parseHex('#CFA8').rgba, new RGBA(204, 255, 170, 136));
assert.deepEqual(Color.Format.CSS.parseHex('#010203').rgba, new RGBA(1, 2, 3, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#040506').rgba, new RGBA(4, 5, 6, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#070809').rgba, new RGBA(7, 8, 9, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0a0A0a').rgba, new RGBA(10, 10, 10, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0b0B0b').rgba, new RGBA(11, 11, 11, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0c0C0c').rgba, new RGBA(12, 12, 12, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0d0D0d').rgba, new RGBA(13, 13, 13, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0e0E0e').rgba, new RGBA(14, 14, 14, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0f0F0f').rgba, new RGBA(15, 15, 15, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#a0A0a0').rgba, new RGBA(160, 160, 160, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#CFA').rgba, new RGBA(204, 255, 170, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#CFA8').rgba, new RGBA(204, 255, 170, 0.533));
});
});
});

View file

@ -338,34 +338,16 @@ suite('Event utils', () => {
});
});
test('should emit when done - setTimeout', () => {
test('should emit when done - setTimeout', async () => {
let count = 0;
const event = fromPromise(TPromise.timeout(5));
const promise = TPromise.timeout(5);
const event = fromPromise(promise);
event(() => count++);
assert.equal(count, 0);
return TPromise.timeout(10).then(() => {
assert.equal(count, 1);
});
});
test('should emit when done - setTimeout (#2)', () => {
let count = 0;
const event = fromPromise(TPromise.timeout(30));
event(() => count++);
assert.equal(count, 0);
return TPromise.timeout(0).then(() => {
assert.equal(count, 0);
return TPromise.timeout(35).then(() => {
assert.equal(count, 1);
});
});
await promise;
assert.equal(count, 1);
});
});

View file

@ -5,6 +5,7 @@
'use strict';
import { BoundedMap, TrieMap, ResourceMap } from 'vs/base/common/map';
import * as assert from 'assert';
import URI from 'vs/base/common/uri';
@ -313,7 +314,7 @@ suite('Map', () => {
test('TrieMap - basics', function () {
const map = new TrieMap<number>(TrieMap.PathSplitter);
const map = new TrieMap<number>();
map.insert('/user/foo/bar', 1);
map.insert('/user/foo', 2);
@ -331,7 +332,7 @@ suite('Map', () => {
test('TrieMap - lookup', function () {
const map = new TrieMap<number>(TrieMap.PathSplitter);
const map = new TrieMap<number>();
map.insert('/user/foo/bar', 1);
map.insert('/user/foo', 2);
map.insert('/user/foo/flip/flop', 3);
@ -345,7 +346,7 @@ suite('Map', () => {
test('TrieMap - superstr', function () {
const map = new TrieMap<number>(TrieMap.PathSplitter);
const map = new TrieMap<number>();
map.insert('/user/foo/bar', 1);
map.insert('/user/foo', 2);
map.insert('/user/foo/flip/flop', 3);

View file

@ -138,7 +138,7 @@ function main(server: Server, initData: ISharedProcessInitData): void {
function setupIPC(hook: string): TPromise<Server> {
function setup(retry: boolean): TPromise<Server> {
return serve(hook).then<Server>(null, err => {
return serve(hook).then(null, err => {
if (!retry || platform.isWindows || err.code !== 'EADDRINUSE') {
return TPromise.wrapError(err);
}

View file

@ -511,10 +511,14 @@ export class CodeWindow implements ICodeWindow {
}
}
public reload(cli?: ParsedArgs): void {
public reload(configuration?: IWindowConfiguration, cli?: ParsedArgs): void {
// Inherit current properties but overwrite some
const configuration: IWindowConfiguration = objects.mixin({}, this.currentConfig);
// If config is not provided, copy our current one
if (!configuration) {
configuration = objects.mixin({}, this.currentConfig);
}
// Delete some properties we do not want during reload
delete configuration.filesToOpen;
delete configuration.filesToCreate;
delete configuration.filesToDiff;

View file

@ -19,7 +19,7 @@ import { IPathWithLineAndColumn, parseLineAndColumnAware } from 'vs/code/node/pa
import { ILifecycleService, UnloadReason, IWindowUnloadEvent } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ILogService } from 'vs/platform/log/common/log';
import { IWindowSettings, OpenContext, IPath, IWindowConfiguration, INativeOpenDialogOptions } from 'vs/platform/windows/common/windows';
import { IWindowSettings, OpenContext, IPath, IWindowConfiguration, INativeOpenDialogOptions, ReadyState } from 'vs/platform/windows/common/windows';
import { getLastActiveWindow, findBestWindowOrFolderForFile, findWindowOnWorkspace, findWindowOnExtensionDevelopmentPath, findWindowOnWorkspaceOrFolderPath } from 'vs/code/node/windowsFinder';
import CommonEvent, { Emitter } from 'vs/base/common/event';
import product from 'vs/platform/node/product';
@ -937,16 +937,16 @@ export class WindowsManager implements IWindowsMainService {
configuration.backupPath = path.join(this.environmentService.backupHome, options.emptyWindowBackupFolder);
}
let codeWindow: CodeWindow;
let window: CodeWindow;
if (!options.forceNewWindow) {
codeWindow = options.windowToUse || this.getLastActiveWindow();
if (codeWindow) {
codeWindow.focus();
window = options.windowToUse || this.getLastActiveWindow();
if (window) {
window.focus();
}
}
// New window
if (!codeWindow) {
if (!window) {
const windowConfig = this.configurationService.getConfiguration<IWindowSettings>('window');
const state = this.getNewWindowState(configuration);
@ -965,27 +965,27 @@ export class WindowsManager implements IWindowsMainService {
state.mode = WindowMode.Normal;
}
codeWindow = this.instantiationService.createInstance(CodeWindow, {
window = this.instantiationService.createInstance(CodeWindow, {
state,
extensionDevelopmentPath: configuration.extensionDevelopmentPath,
isExtensionTestHost: !!configuration.extensionTestsPath
});
// Add to our list of windows
WindowsManager.WINDOWS.push(codeWindow);
WindowsManager.WINDOWS.push(window);
// Indicate number change via event
this._onWindowsCountChanged.fire({ oldCount: WindowsManager.WINDOWS.length - 1, newCount: WindowsManager.WINDOWS.length });
// Window Events
codeWindow.win.webContents.removeAllListeners('devtools-reload-page'); // remove built in listener so we can handle this on our own
codeWindow.win.webContents.on('devtools-reload-page', () => this.reload(codeWindow));
codeWindow.win.webContents.on('crashed', () => this.onWindowError(codeWindow, WindowError.CRASHED));
codeWindow.win.on('unresponsive', () => this.onWindowError(codeWindow, WindowError.UNRESPONSIVE));
codeWindow.win.on('closed', () => this.onWindowClosed(codeWindow));
window.win.webContents.removeAllListeners('devtools-reload-page'); // remove built in listener so we can handle this on our own
window.win.webContents.on('devtools-reload-page', () => this.reload(window));
window.win.webContents.on('crashed', () => this.onWindowError(window, WindowError.CRASHED));
window.win.on('unresponsive', () => this.onWindowError(window, WindowError.UNRESPONSIVE));
window.win.on('closed', () => this.onWindowClosed(window));
// Lifecycle
this.lifecycleService.registerWindow(codeWindow);
this.lifecycleService.registerWindow(window);
}
// Existing window
@ -993,7 +993,7 @@ export class WindowsManager implements IWindowsMainService {
// Some configuration things get inherited if the window is being reused and we are
// in extension development host mode. These options are all development related.
const currentWindowConfig = codeWindow.config;
const currentWindowConfig = window.config;
if (!configuration.extensionDevelopmentPath && currentWindowConfig && !!currentWindowConfig.extensionDevelopmentPath) {
configuration.extensionDevelopmentPath = currentWindowConfig.extensionDevelopmentPath;
configuration.verbose = currentWindowConfig.verbose;
@ -1005,7 +1005,7 @@ export class WindowsManager implements IWindowsMainService {
}
// Only load when the window has not vetoed this
this.lifecycleService.unload(codeWindow, UnloadReason.LOAD).done(veto => {
this.lifecycleService.unload(window, UnloadReason.LOAD).done(veto => {
if (!veto) {
// Register window for backups
@ -1020,11 +1020,11 @@ export class WindowsManager implements IWindowsMainService {
}
// Load it
codeWindow.load(configuration);
window.load(configuration);
}
});
return codeWindow;
return window;
}
private getNewWindowState(configuration: IWindowConfiguration): INewWindowState {
@ -1156,7 +1156,7 @@ export class WindowsManager implements IWindowsMainService {
// Only reload when the window has not vetoed this
this.lifecycleService.unload(win, UnloadReason.RELOAD).done(veto => {
if (!veto) {
win.reload(cli);
win.reload(void 0, cli);
// Emit
this._onWindowReload.fire(win.id);
@ -1171,19 +1171,44 @@ export class WindowsManager implements IWindowsMainService {
});
}
public newWorkspace(window: CodeWindow = this.getLastActiveWindow()): void {
const folders = dialog.showOpenDialog(window ? window.win : void 0, {
buttonLabel: mnemonicLabel(localize({ key: 'select', comment: ['&& denotes a mnemonic'] }, "&&Select")),
title: localize('selectWorkspace', "Select Folders for Workspace"),
properties: ['multiSelections', 'openDirectory', 'createDirectory'],
defaultPath: this.getWorkspaceDialogDefaultPath(window ? (window.openedWorkspace || window.openedFolderPath) : void 0)
});
if (folders && folders.length) {
this.workspacesService.createWorkspace(folders.map(folder => URI.file(folder).toString(true /* encoding */))).then(workspace => {
this.open({ context: OpenContext.DIALOG, cli: this.environmentService.args, pathsToOpen: [workspace.configPath] });
});
public createAndOpenWorkspace(window: CodeWindow, folders?: string[], path?: string): TPromise<void> {
if (!window || !window.win || window.readyState !== ReadyState.READY) {
return TPromise.as(null); // return early if the window is not ready or disposed
}
return this.workspacesService.createWorkspace(folders).then(workspace => {
let savePromise: TPromise<IWorkspaceIdentifier>;
if (path) {
savePromise = this.workspacesService.saveWorkspace(workspace, path);
} else {
savePromise = TPromise.as(workspace);
}
return savePromise.then(workspace => {
window.focus();
// Only open workspace when the window has not vetoed this
return this.lifecycleService.unload(window, UnloadReason.RELOAD).done(veto => {
if (!veto) {
// Register window for backups and migrate current backups over
let backupPath: string;
if (window.config && !window.config.extensionDevelopmentPath) {
backupPath = this.backupService.registerWorkspaceBackupSync(workspace, window.config.backupPath);
}
// Craft a new window configuration to use for the transition
const configuration: IWindowConfiguration = mixin({}, window.config);
configuration.folderPath = void 0;
configuration.workspace = workspace;
configuration.backupPath = backupPath;
// Reload
window.reload(configuration);
}
});
});
});
}
public openWorkspace(window: CodeWindow = this.getLastActiveWindow()): void {
@ -1395,12 +1420,12 @@ export class WindowsManager implements IWindowsMainService {
return WindowsManager.WINDOWS.length;
}
private onWindowError(codeWindow: CodeWindow, error: WindowError): void {
private onWindowError(window: CodeWindow, error: WindowError): void {
this.logService.error(error === WindowError.CRASHED ? '[VS Code]: render process crashed!' : '[VS Code]: detected unresponsive');
// Unresponsive
if (error === WindowError.UNRESPONSIVE) {
dialog.showMessageBox(codeWindow.win, {
dialog.showMessageBox(window.win, {
title: product.nameLong,
type: 'warning',
buttons: [localize('reopen', "Reopen"), localize('wait', "Keep Waiting"), localize('close', "Close")],
@ -1408,22 +1433,22 @@ export class WindowsManager implements IWindowsMainService {
detail: localize('appStalledDetail', "You can reopen or close the window or keep waiting."),
noLink: true
}, result => {
if (!codeWindow.win) {
if (!window.win) {
return; // Return early if the window has been going down already
}
if (result === 0) {
codeWindow.reload();
window.reload();
} else if (result === 2) {
this.onBeforeWindowClose(codeWindow); // 'close' event will not be fired on destroy(), so run it manually
codeWindow.win.destroy(); // make sure to destroy the window as it is unresponsive
this.onBeforeWindowClose(window); // 'close' event will not be fired on destroy(), so run it manually
window.win.destroy(); // make sure to destroy the window as it is unresponsive
}
});
}
// Crashed
else {
dialog.showMessageBox(codeWindow.win, {
dialog.showMessageBox(window.win, {
title: product.nameLong,
type: 'warning',
buttons: [localize('reopen', "Reopen"), localize('close', "Close")],
@ -1431,15 +1456,15 @@ export class WindowsManager implements IWindowsMainService {
detail: localize('appCrashedDetail', "We are sorry for the inconvenience! You can reopen the window to continue where you left off."),
noLink: true
}, result => {
if (!codeWindow.win) {
if (!window.win) {
return; // Return early if the window has been going down already
}
if (result === 0) {
codeWindow.reload();
window.reload();
} else if (result === 1) {
this.onBeforeWindowClose(codeWindow); // 'close' event will not be fired on destroy(), so run it manually
codeWindow.win.destroy(); // make sure to destroy the window as it has crashed
this.onBeforeWindowClose(window); // 'close' event will not be fired on destroy(), so run it manually
window.win.destroy(); // make sure to destroy the window as it has crashed
}
});
}
@ -1508,9 +1533,9 @@ export class WindowsManager implements IWindowsMainService {
// If the user selected to exit from an extension development host window, do not quit, but just
// close the window unless this is the last window that is opened.
const codeWindow = this.getFocusedWindow();
if (codeWindow && codeWindow.isExtensionDevelopmentHost && this.getWindowCount() > 1) {
codeWindow.win.close();
const window = this.getFocusedWindow();
if (window && window.isExtensionDevelopmentHost && this.getWindowCount() > 1) {
window.win.close();
}
// Otherwise: normal quit

View file

@ -20,7 +20,7 @@ import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
import { IDisposable } from 'vs/base/common/lifecycle';
import { RenderedLinesCollection, ILine } from 'vs/editor/browser/view/viewLayer';
import { Range } from 'vs/editor/common/core/range';
import { RGBA } from 'vs/base/common/color';
import { RGBA8 } from "vs/editor/common/core/rgba";
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { GlobalMouseMoveMonitor, IStandardMouseMoveEventData, standardMouseMoveMerger } from 'vs/base/browser/globalMouseMoveMonitor';
import * as platform from 'vs/base/common/platform';
@ -386,7 +386,7 @@ class MinimapBuffers {
private readonly _buffers: [ImageData, ImageData];
private _lastUsedBuffer: number;
constructor(ctx: CanvasRenderingContext2D, WIDTH: number, HEIGHT: number, background: RGBA) {
constructor(ctx: CanvasRenderingContext2D, WIDTH: number, HEIGHT: number, background: RGBA8) {
this._backgroundFillData = MinimapBuffers._createBackgroundFillData(WIDTH, HEIGHT, background);
this._buffers = [
ctx.createImageData(WIDTH, HEIGHT),
@ -406,7 +406,7 @@ class MinimapBuffers {
return result;
}
private static _createBackgroundFillData(WIDTH: number, HEIGHT: number, background: RGBA): Uint8ClampedArray {
private static _createBackgroundFillData(WIDTH: number, HEIGHT: number, background: RGBA8): Uint8ClampedArray {
const backgroundR = background.r;
const backgroundG = background.g;
const backgroundB = background.b;
@ -830,7 +830,7 @@ export class Minimap extends ViewPart {
private static _renderLine(
target: ImageData,
backgroundColor: RGBA,
backgroundColor: RGBA8,
useLighterFont: boolean,
renderMinimap: RenderMinimap,
colorTracker: MinimapTokensColorTracker,

View file

@ -112,28 +112,30 @@ export class ShiftCommand implements ICommand {
if (contentStartVisibleColumn % tabSize !== 0) {
// The current line is "miss-aligned", so let's see if this is expected...
// This can only happen when it has trailing commas in the indent
let enterAction = LanguageConfigurationRegistry.getRawEnterActionAtPosition(model, lineNumber - 1, model.getLineMaxColumn(lineNumber - 1));
if (enterAction) {
extraSpaces = previousLineExtraSpaces;
if (enterAction.appendText) {
for (let j = 0, lenJ = enterAction.appendText.length; j < lenJ && extraSpaces < tabSize; j++) {
if (enterAction.appendText.charCodeAt(j) === CharCode.Space) {
extraSpaces++;
} else {
break;
if (model.isCheapToTokenize(lineNumber - 1)) {
let enterAction = LanguageConfigurationRegistry.getRawEnterActionAtPosition(model, lineNumber - 1, model.getLineMaxColumn(lineNumber - 1));
if (enterAction) {
extraSpaces = previousLineExtraSpaces;
if (enterAction.appendText) {
for (let j = 0, lenJ = enterAction.appendText.length; j < lenJ && extraSpaces < tabSize; j++) {
if (enterAction.appendText.charCodeAt(j) === CharCode.Space) {
extraSpaces++;
} else {
break;
}
}
}
}
if (enterAction.removeText) {
extraSpaces = Math.max(0, extraSpaces - enterAction.removeText);
}
// Act as if `prefixSpaces` is not part of the indentation
for (let j = 0; j < extraSpaces; j++) {
if (indentationEndIndex === 0 || lineText.charCodeAt(indentationEndIndex - 1) !== CharCode.Space) {
break;
if (enterAction.removeText) {
extraSpaces = Math.max(0, extraSpaces - enterAction.removeText);
}
// Act as if `prefixSpaces` is not part of the indentation
for (let j = 0; j < extraSpaces; j++) {
if (indentationEndIndex === 0 || lineText.charCodeAt(indentationEndIndex - 1) !== CharCode.Space) {
break;
}
indentationEndIndex--;
}
indentationEndIndex--;
}
}
}

View file

@ -1687,7 +1687,7 @@ namespace Config {
return this._runEditorHandler(focusedEditor, args);
}
// Ignore this action when user is focussed on an element that allows for entering text
// Ignore this action when user is focused on an element that allows for entering text
let activeElement = <HTMLElement>document.activeElement;
if (activeElement && ['input', 'textarea'].indexOf(activeElement.tagName.toLowerCase()) >= 0) {
document.execCommand(this._inputHandler);

View file

@ -223,7 +223,7 @@ export class TypeOperations {
let lineText = model.getLineContent(selection.startLineNumber);
if (/^\s*$/.test(lineText)) {
if (/^\s*$/.test(lineText) && model.isCheapToTokenize(selection.startLineNumber)) {
let goodIndent = this._goodIndentForLine(config, model, selection.startLineNumber);
goodIndent = goodIndent || '\t';
let possibleTypeText = config.normalizeIndentation(goodIndent);
@ -286,7 +286,7 @@ export class TypeOperations {
}
private static _enter(config: CursorConfiguration, model: ITokenizedModel, keepPosition: boolean, range: Range): ICommand {
if (model.getFirstInvalidLineNumber() < range.getStartPosition().lineNumber) {
if (!model.isCheapToTokenize(range.getStartPosition().lineNumber)) {
let lineText = model.getLineContent(range.startLineNumber);
let indentation = strings.getLeadingWhitespace(lineText).substring(0, range.startColumn - 1);
return TypeOperations._typeCommand(range, '\n' + config.normalizeIndentation(indentation), keepPosition);
@ -380,9 +380,8 @@ export class TypeOperations {
return false;
}
let firstInvalidLineNumber = model.getFirstInvalidLineNumber();
for (let i = 0, len = selections.length; i < len; i++) {
if (firstInvalidLineNumber < selections[i].getEndPosition().lineNumber) {
if (!model.isCheapToTokenize(selections[i].getEndPosition().lineNumber)) {
return false;
}
}
@ -528,6 +527,11 @@ export class TypeOperations {
}
}
if (!model.isCheapToTokenize(position.lineNumber)) {
// Do not force tokenization
return false;
}
model.forceTokenization(position.lineNumber);
const lineTokens = model.getLineTokens(position.lineNumber);
@ -607,8 +611,7 @@ export class TypeOperations {
}
private static _isTypeInterceptorElectricChar(config: CursorConfiguration, model: ITokenizedModel, selections: Selection[]) {
let firstInvalidLineNumber = model.getFirstInvalidLineNumber();
if (selections.length === 1 && firstInvalidLineNumber >= selections[0].getEndPosition().lineNumber) {
if (selections.length === 1 && model.isCheapToTokenize(selections[0].getEndPosition().lineNumber)) {
return true;
}
return false;

View file

@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
/**
* A very VM friendly rgba datastructure.
* Please don't touch unless you take a look at the IR.
*/
export class RGBA8 {
_rgba8Brand: void;
/**
* Red: integer in [0-255]
*/
public readonly r: number;
/**
* Green: integer in [0-255]
*/
public readonly g: number;
/**
* Blue: integer in [0-255]
*/
public readonly b: number;
/**
* Alpha: integer in [0-255]
*/
public readonly a: number;
constructor(r: number, g: number, b: number, a: number) {
this.r = RGBA8._clampInt_0_255(r);
this.g = RGBA8._clampInt_0_255(g);
this.b = RGBA8._clampInt_0_255(b);
this.a = RGBA8._clampInt_0_255(a);
}
public static equals(a: RGBA8, b: RGBA8): boolean {
return (
a.r === b.r
&& a.g === b.g
&& a.b === b.b
&& a.a === b.a
);
}
private static _clampInt_0_255(c: number): number {
if (c < 0) {
return 0;
}
if (c > 255) {
return 255;
}
return c | 0;
}
}

View file

@ -820,10 +820,19 @@ export interface ITokenizedModel extends ITextModel {
forceTokenization(lineNumber: number): void;
/**
* Get the line number of the first line whose tokens might be inaccurate.
* If it is cheap, force tokenization information for `lineNumber` to be accurate.
* This is based on a heuristic.
* @internal
*/
getFirstInvalidLineNumber(): number;
tokenizeIfCheap(lineNumber: number): void;
/**
* Check if calling `forceTokenization` for this `lineNumber` will be cheap (time-wise).
* This is based on a heuristic.
* @internal
*/
isCheapToTokenize(lineNumber: number): boolean;
/**
* Get the tokens for the line `lineNumber`.
* The tokens might be inaccurate. Use `forceTokenization` to ensure accurate tokens.

View file

@ -169,10 +169,6 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
return result;
}
public getFirstInvalidLineNumber(): number {
return this._invalidLineStartIndex + 1;
}
public forceTokenization(lineNumber: number): void {
if (lineNumber < 1 || lineNumber > this.getLineCount()) {
throw new Error('Illegal value ' + lineNumber + ' for `lineNumber`');
@ -183,6 +179,17 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
});
}
public isCheapToTokenize(lineNumber: number): boolean {
const firstInvalidLineNumber = this._invalidLineStartIndex + 1;
return (firstInvalidLineNumber >= lineNumber);
}
public tokenizeIfCheap(lineNumber: number): void {
if (this.isCheapToTokenize(lineNumber)) {
this.forceTokenization(lineNumber);
}
}
public getLineTokens(lineNumber: number): LineTokens {
if (lineNumber < 1 || lineNumber > this.getLineCount()) {
throw new Error('Illegal value ' + lineNumber + ' for `lineNumber`');

View file

@ -1,182 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { LineToken } from 'vs/editor/common/core/lineTokens';
import { Position } from 'vs/editor/common/core/position';
import { StandardTokenType } from 'vs/editor/common/modes';
export interface ITokenInfo {
readonly type: StandardTokenType;
readonly lineNumber: number;
readonly startColumn: number;
readonly endColumn: number;
}
export interface ITokenIterator {
hasNext(): boolean;
next(): ITokenInfo;
hasPrev(): boolean;
prev(): ITokenInfo;
}
class TokenInfo implements ITokenInfo {
_tokenInfoBrand: void;
readonly _actual: LineToken;
public readonly lineNumber: number;
public readonly startColumn: number;
public readonly endColumn: number;
public readonly type: StandardTokenType;
constructor(actual: LineToken, lineNumber: number) {
this._actual = actual;
this.lineNumber = lineNumber;
this.startColumn = this._actual.startOffset + 1;
this.endColumn = this._actual.endOffset + 1;
this.type = this._actual.tokenType;
}
}
function findClosestNonEmptyLine(model: editorCommon.ITokenizedModel, position: Position): Position {
const lineNumber = position.lineNumber;
if (model.getLineMaxColumn(lineNumber) !== 1) {
return position;
}
const lineCount = model.getLineCount();
// we need to go up or down
let distance = 1;
while (true) {
let aboveLineNumber = lineNumber - distance;
let belowLineNumber = lineNumber + distance;
if (aboveLineNumber < 1 && belowLineNumber > lineCount) {
// No more lines above or below
break;
}
if (aboveLineNumber >= 1) {
let aboveMaxColumn = model.getLineMaxColumn(aboveLineNumber);
if (aboveMaxColumn !== 1) {
// bingo!
return new Position(aboveLineNumber, aboveMaxColumn);
}
}
if (belowLineNumber <= lineCount) {
let belowMaxColumn = model.getLineMaxColumn(belowLineNumber);
if (belowMaxColumn !== 1) {
// bingo!
return new Position(belowLineNumber, 1);
}
}
distance++;
}
return null;
}
export class TokenIterator implements ITokenIterator {
private _model: editorCommon.ITokenizedModel;
private _lineCount: number;
private _prev: TokenInfo;
private _next: TokenInfo;
constructor(model: editorCommon.ITokenizedModel, position: Position) {
this._model = model;
this._lineCount = this._model.getLineCount();
this._prev = null;
this._next = null;
position = findClosestNonEmptyLine(model, position);
if (position) {
this._model.forceTokenization(position.lineNumber);
let lineTokens = this._model.getLineTokens(position.lineNumber);
let currentToken = lineTokens.findTokenAtOffset(position.column - 1);
if (currentToken) {
this._prev = this._next = new TokenInfo(currentToken, position.lineNumber);
}
}
}
private _advanceNext(): void {
if (!this._next) {
return;
}
let lineNumber = this._next.lineNumber;
let next = this._next._actual.next();
while (!next && lineNumber < this._lineCount) {
lineNumber++;
this._model.forceTokenization(lineNumber);
let currentLineTokens = this._model.getLineTokens(lineNumber);
next = currentLineTokens.firstToken();
}
this._prev = this._next;
if (next) {
this._next = new TokenInfo(next, lineNumber);
} else {
this._next = null;
}
}
private _advancePrev(): void {
if (!this._prev) {
return;
}
let lineNumber = this._prev.lineNumber;
let prev = this._prev._actual.prev();
while (!prev && lineNumber > 1) {
lineNumber--;
this._model.forceTokenization(lineNumber);
let currentLineTokens = this._model.getLineTokens(lineNumber);
prev = currentLineTokens.lastToken();
}
this._next = this._prev;
if (prev) {
this._prev = new TokenInfo(prev, lineNumber);
} else {
this._prev = null;
}
}
public hasNext(): boolean {
return this._next !== null;
}
public next(): ITokenInfo {
const result = this._next;
this._advanceNext();
return result;
}
public hasPrev(): boolean {
return this._prev !== null;
}
public prev(): ITokenInfo {
const result = this._prev;
this._advancePrev();
return result;
}
public _invalidate() {
// replace all public functions with errors
var errorFn = function (): any {
throw new Error('iteration isn\'t valid anymore');
};
this.hasNext = errorFn;
this.next = errorFn;
this.hasPrev = errorFn;
this.prev = errorFn;
}
}

View file

@ -6,7 +6,7 @@
import { ColorId, TokenizationRegistry } from 'vs/editor/common/modes';
import Event, { Emitter } from 'vs/base/common/event';
import { RGBA } from 'vs/base/common/color';
import { RGBA8 } from "vs/editor/common/core/rgba";
export class MinimapTokensColorTracker {
private static _INSTANCE: MinimapTokensColorTracker = null;
@ -17,7 +17,7 @@ export class MinimapTokensColorTracker {
return this._INSTANCE;
}
private _colors: RGBA[];
private _colors: RGBA8[];
private _backgroundIsLight: boolean;
private _onDidChange = new Emitter<void>();
@ -41,14 +41,16 @@ export class MinimapTokensColorTracker {
}
this._colors = [null];
for (let colorId = 1; colorId < colorMap.length; colorId++) {
this._colors[colorId] = colorMap[colorId].rgba;
const source = colorMap[colorId].rgba;
// Use a VM friendly data-type
this._colors[colorId] = new RGBA8(source.r, source.g, source.b, Math.round(source.a * 255));
}
let backgroundLuminosity = colorMap[ColorId.DefaultBackground].getRelativeLuminance();
this._backgroundIsLight = (backgroundLuminosity >= 0.5);
this._onDidChange.fire(void 0);
}
public getColor(colorId: ColorId): RGBA {
public getColor(colorId: ColorId): RGBA8 {
if (colorId < 1 || colorId >= this._colors.length) {
// background color (basically invisible)
colorId = ColorId.DefaultBackground;
@ -121,7 +123,7 @@ export class MinimapCharRenderer {
return (chCode % Constants.CHAR_COUNT);
}
public x2RenderChar(target: ImageData, dx: number, dy: number, chCode: number, color: RGBA, backgroundColor: RGBA, useLighterFont: boolean): void {
public x2RenderChar(target: ImageData, dx: number, dy: number, chCode: number, color: RGBA8, backgroundColor: RGBA8, useLighterFont: boolean): void {
if (dx + Constants.x2_CHAR_WIDTH > target.width || dy + Constants.x2_CHAR_HEIGHT > target.height) {
console.warn('bad render request outside image data');
return;
@ -198,7 +200,7 @@ export class MinimapCharRenderer {
}
}
public x1RenderChar(target: ImageData, dx: number, dy: number, chCode: number, color: RGBA, backgroundColor: RGBA, useLighterFont: boolean): void {
public x1RenderChar(target: ImageData, dx: number, dy: number, chCode: number, color: RGBA8, backgroundColor: RGBA8, useLighterFont: boolean): void {
if (dx + Constants.x1_CHAR_WIDTH > target.width || dy + Constants.x1_CHAR_HEIGHT > target.height) {
console.warn('bad render request outside image data');
return;
@ -235,7 +237,7 @@ export class MinimapCharRenderer {
}
}
public x2BlockRenderChar(target: ImageData, dx: number, dy: number, color: RGBA, backgroundColor: RGBA, useLighterFont: boolean): void {
public x2BlockRenderChar(target: ImageData, dx: number, dy: number, color: RGBA8, backgroundColor: RGBA8, useLighterFont: boolean): void {
if (dx + Constants.x2_CHAR_WIDTH > target.width || dy + Constants.x2_CHAR_HEIGHT > target.height) {
console.warn('bad render request outside image data');
return;
@ -307,7 +309,7 @@ export class MinimapCharRenderer {
}
}
public x1BlockRenderChar(target: ImageData, dx: number, dy: number, color: RGBA, backgroundColor: RGBA, useLighterFont: boolean): void {
public x1BlockRenderChar(target: ImageData, dx: number, dy: number, color: RGBA8, backgroundColor: RGBA8, useLighterFont: boolean): void {
if (dx + Constants.x1_CHAR_WIDTH > target.width || dy + Constants.x1_CHAR_HEIGHT > target.height) {
console.warn('bad render request outside image data');
return;

View file

@ -47,7 +47,7 @@ export class ColorPickerHeader extends Disposable {
private onDidChangeColor(color: Color): void {
this.pickedColorNode.style.backgroundColor = Color.Format.CSS.format(color);
dom.toggleClass(this.pickedColorNode, 'light', color.rgba.a < 128 ? this.backgroundColor.isLighter() : color.isLighter());
dom.toggleClass(this.pickedColorNode, 'light', color.rgba.a < 0.5 ? this.backgroundColor.isLighter() : color.isLighter());
this.onDidChangeFormatter();
}
@ -277,7 +277,7 @@ class OpacityStrip extends Strip {
private onDidChangeColor(color: Color): void {
const { r, g, b } = color.rgba;
const opaque = new Color(new RGBA(r, g, b, 255));
const opaque = new Color(new RGBA(r, g, b, 1));
const transparent = new Color(new RGBA(r, g, b, 0));
this.overlay.style.background = `linear-gradient(to bottom, ${opaque} 0%, ${transparent} 100%)`;

View file

@ -32,7 +32,7 @@ function getPropertyValue(color: Color, variable: string): number | undefined {
case 'blue':
return color.rgba.b / 255;
case 'alpha':
return color.rgba.a / 255;
return color.rgba.a;
case 'hue':
return color.hsla.h / 360;
case 'saturation':
@ -56,7 +56,7 @@ function createPropertyNode(variable: string, fractionDigits: number, type: stri
min = typeof min === 'number' ? min : 0;
max = typeof max === 'number' ? max : 255;
return (normalize(value, min, max) | 0).toString();
return (normalize(value, min, max).toFixed(0)).toString();
} else if (type === 'x' || type === 'X') {
min = typeof min === 'number' ? min : 0;
max = typeof max === 'number' ? max : 255;

View file

@ -5,7 +5,7 @@
'use strict';
import * as assert from 'assert';
import { Color, RGBA } from 'vs/base/common/color';
import { Color, RGBA, HSLA } from 'vs/base/common/color';
import { ColorFormatter } from 'vs/editor/contrib/colorPicker/common/colorFormatter';
suite('ColorFormatter', () => {
@ -63,4 +63,12 @@ suite('ColorFormatter', () => {
const hsla = new ColorFormatter('hsla({hue:d[0-360]}, {saturation:d[0-100]}%, {luminance:d[0-100]}%, {alpha})');
assert.equal(hsla.format(color), 'hsla(30, 100%, 50%, 1)');
});
test('bug#32323', () => {
const color = new Color(new HSLA(121, 0.45, 0.29, 0.61));
const rgba = color.rgba;
const color2 = new Color(new RGBA(rgba.r, rgba.g, rgba.b, rgba.a));
const hsla = new ColorFormatter('hsla({hue:d[0-360]}, {saturation:d[0-100]}%, {luminance:d[0-100]}%, {alpha})');
assert.equal(hsla.format(color2), 'hsla(121, 45%, 29%, 0.61)');
});
});

View file

@ -135,7 +135,7 @@ export class BlockCommentCommand implements editorCommon.ICommand {
var endLineNumber = this._selection.endLineNumber;
var endColumn = this._selection.endColumn;
model.forceTokenization(startLineNumber);
model.tokenizeIfCheap(startLineNumber);
let languageId = model.getLanguageIdAtPosition(startLineNumber, startColumn);
let config = LanguageConfigurationRegistry.getComments(languageId);
if (!config || !config.blockCommentStartToken || !config.blockCommentEndToken) {

View file

@ -64,7 +64,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
*/
public static _gatherPreflightCommentStrings(model: editorCommon.ITokenizedModel, startLineNumber: number, endLineNumber: number): ILinePreflightData[] {
model.forceTokenization(startLineNumber);
model.tokenizeIfCheap(startLineNumber);
const languageId = model.getLanguageIdAtPosition(startLineNumber, 1);
const config = LanguageConfigurationRegistry.getComments(languageId);
@ -266,7 +266,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
* Given an unsuccessful analysis, delegate to the block comment command
*/
private _executeBlockComment(model: editorCommon.ITokenizedModel, builder: editorCommon.IEditOperationBuilder, s: Selection): void {
model.forceTokenization(s.startLineNumber);
model.tokenizeIfCheap(s.startLineNumber);
let languageId = model.getLanguageIdAtPosition(s.startLineNumber, s.startColumn);
let config = LanguageConfigurationRegistry.getComments(languageId);
if (!config || !config.blockCommentStartToken || !config.blockCommentEndToken) {

View file

@ -25,7 +25,7 @@ import { FIND_IDS, MATCHES_LIMIT } from 'vs/editor/contrib/find/common/findModel
import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/common/findState';
import { Range } from 'vs/editor/common/core/range';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { CONTEXT_FIND_INPUT_FOCUSSED } from 'vs/editor/contrib/find/common/findController';
import { CONTEXT_FIND_INPUT_FOCUSED } from 'vs/editor/contrib/find/common/findController';
import { ITheme, registerThemingParticipant, IThemeService } from 'vs/platform/theme/common/themeService';
import { Color } from 'vs/base/common/color';
import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
@ -105,7 +105,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
private _isReplaceVisible: boolean;
private _focusTracker: dom.IFocusTracker;
private _findInputFocussed: IContextKey<boolean>;
private _findInputFocused: IContextKey<boolean>;
private _viewZone: FindWidgetViewZone;
private _viewZoneId: number;
@ -192,10 +192,10 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
this._updateToggleSelectionFindButton();
}
}));
this._findInputFocussed = CONTEXT_FIND_INPUT_FOCUSSED.bindTo(contextKeyService);
this._findInputFocused = CONTEXT_FIND_INPUT_FOCUSED.bindTo(contextKeyService);
this._focusTracker = this._register(dom.trackFocus(this._findInput.inputBox.inputElement));
this._focusTracker.addFocusListener(() => {
this._findInputFocussed.set(true);
this._findInputFocused.set(true);
if (this._toggleSelectionFind.checked) {
let selection = this._codeEditor.getSelection();
@ -212,7 +212,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
}
});
this._focusTracker.addBlurListener(() => {
this._findInputFocussed.set(false);
this._findInputFocused.set(false);
});
this._codeEditor.addOverlayWidget(this);

View file

@ -39,7 +39,7 @@ export interface IFindStartOptions {
export const CONTEXT_FIND_WIDGET_VISIBLE = new RawContextKey<boolean>('findWidgetVisible', false);
export const CONTEXT_FIND_WIDGET_NOT_VISIBLE: ContextKeyExpr = CONTEXT_FIND_WIDGET_VISIBLE.toNegated();
export const CONTEXT_FIND_INPUT_FOCUSSED = new RawContextKey<boolean>('findInputFocussed', false);
export const CONTEXT_FIND_INPUT_FOCUSED = new RawContextKey<boolean>('findInputFocussed', false);
export class CommonFindController extends Disposable implements editorCommon.IEditorContribution {
@ -1131,7 +1131,7 @@ export class ShowNextFindTermAction extends MatchFindAction {
precondition: CONTEXT_FIND_WIDGET_VISIBLE,
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
kbExpr: ContextKeyExpr.and(CONTEXT_FIND_INPUT_FOCUSSED, EditorContextKeys.focus),
kbExpr: ContextKeyExpr.and(CONTEXT_FIND_INPUT_FOCUSED, EditorContextKeys.focus),
primary: ShowNextFindTermKeybinding.primary,
mac: ShowNextFindTermKeybinding.mac,
win: ShowNextFindTermKeybinding.win,
@ -1156,7 +1156,7 @@ export class ShpwPreviousFindTermAction extends MatchFindAction {
precondition: CONTEXT_FIND_WIDGET_VISIBLE,
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
kbExpr: ContextKeyExpr.and(CONTEXT_FIND_INPUT_FOCUSSED, EditorContextKeys.focus),
kbExpr: ContextKeyExpr.and(CONTEXT_FIND_INPUT_FOCUSED, EditorContextKeys.focus),
primary: ShowPreviousFindTermKeybinding.primary,
mac: ShowPreviousFindTermKeybinding.mac,
win: ShowPreviousFindTermKeybinding.win,

View file

@ -41,10 +41,9 @@ function getDefinitions<T>(
const promises = provider.map((provider, idx) => {
return asWinJsPromise((token) => {
return provide(provider, model, position, token);
}).then(result => {
return result;
}, err => {
}).then(undefined, err => {
onUnexpectedExternalError(err);
return null;
});
});
return outputResults(promises);

View file

@ -103,7 +103,6 @@ export class DefinitionAction extends EditorAction {
}, (err) => {
// report an error
messageService.show(Severity.Error, err);
return false;
});
}

Some files were not shown because too many files have changed in this diff Show more