merge with master

This commit is contained in:
isidor 2016-11-24 11:34:13 +01:00
commit 72574a9b42
982 changed files with 24949 additions and 10534 deletions

View file

@ -5,9 +5,6 @@ os:
- linux
- osx
env:
- VSCODE_BUILD_VERBOSE=true
notifications:
email: false
@ -41,11 +38,11 @@ install:
- ./scripts/npm.sh install
script:
- gulp hygiene
- gulp electron
- gulp compile
- gulp optimize-vscode
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./scripts/test.sh --coverage; else ./scripts/test.sh; fi
- gulp hygiene --silent
- gulp electron --silent
- gulp compile --silent
- gulp optimize-vscode --silent
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./scripts/test.sh --reporter dot --coverage; else ./scripts/test.sh --reporter dot; fi
- ./scripts/test-integration.sh
after_success:

37
.vscode/launch.json vendored
View file

@ -2,9 +2,9 @@
"version": "0.1.0",
"configurations": [
{
"name": "Unit Tests",
"type": "node",
"request": "launch",
"name": "Unit Tests",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"runtimeExecutable": "${execPath}",
"stopOnEntry": false,
@ -13,76 +13,73 @@
"999999"
],
"cwd": "${workspaceRoot}",
"runtimeArgs": [],
"env": {
"ELECTRON_RUN_AS_NODE": "true"
},
"sourceMaps": true,
"outDir": "${workspaceRoot}/out"
"outFiles": [ "${workspaceRoot}/out/**/*.js" ]
},
{
"name": "Attach to Extension Host",
"type": "node",
"request": "attach",
"name": "Attach to Extension Host",
"port": 5870,
"sourceMaps": true,
"outDir": "${workspaceRoot}/out"
"outFiles": [ "${workspaceRoot}/out/**/*.js" ]
},
{
"name": "Attach to Shared Process",
"type": "node",
"request": "attach",
"name": "Attach to Shared Process",
"port": 5871,
"sourceMaps": true,
"outDir": "${workspaceRoot}/out"
"outFiles": [ "${workspaceRoot}/out/**/*.js" ]
},
{
"name": "Attach to CLI Process",
"type": "node",
"request": "attach",
"name": "Attach to CLI Process",
"port": 5874,
"sourceMaps": true,
"outDir": "${workspaceRoot}/out"
"outFiles": [ "${workspaceRoot}/out/**/*.js" ]
},
{
"name": "VSCode API Tests",
"type": "extensionHost",
"request": "launch",
"name": "VSCode API Tests",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceRoot}/extensions/vscode-api-tests/testWorkspace",
"--extensionDevelopmentPath=${workspaceRoot}/extensions/vscode-api-tests",
"--extensionTestsPath=${workspaceRoot}/extensions/vscode-api-tests/out"
],
"stopOnEntry": false,
"sourceMaps": true,
"outDir": "${workspaceRoot}/out"
"outFiles": [ "${workspaceRoot}/out/**/*.js" ]
},
{
"name": "VSCode Tokenizer Tests",
"type": "extensionHost",
"request": "launch",
"name": "VSCode Tokenizer Tests",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceRoot}/extensions/vscode-colorize-tests/test",
"--extensionDevelopmentPath=${workspaceRoot}/extensions/vscode-colorize-tests",
"--extensionTestsPath=${workspaceRoot}/extensions/vscode-colorize-tests/out"
],
"stopOnEntry": false,
"sourceMaps": true,
"outDir": "${workspaceRoot}/out"
"outFiles": [ "${workspaceRoot}/out/**/*.js" ]
},
{
"name": "Attach to VSCode",
"type": "chrome",
"request": "attach",
"name": "Attach to VSCode",
"port": 9222,
"sourceMaps": true
},
{
"name": "Launch VSCode",
"type": "chrome",
"request": "launch",
"name": "Launch VSCode",
"windows": {
"runtimeExecutable": "${workspaceRoot}/scripts/code.bat"
},
@ -95,17 +92,15 @@
"sourceMaps": true
},
{
"name": "Debug monaco",
"type": "node",
"request": "launch",
"name": "Debug monaco",
"program": "${workspaceRoot}/build/lib/monaco.js",
"stopOnEntry": false,
"args": [],
"cwd": "${workspaceRoot}/build/lib"
// ,
// "port": 5870,
// "sourceMaps": true,
// "outDir": "${workspaceRoot}/out"
// "outFiles": [ "${workspaceRoot}/out/**/*.js" ]
}
]
}

View file

@ -68,7 +68,7 @@
},
{
"name": "chromium",
"version": "52.0.2743.82",
"version": "53.0.2785.143",
"repositoryURL": "http://www.chromium.org/Home",
"licenseDetail": [
"BSD License",
@ -104,7 +104,7 @@
},
{
"name": "libchromiumcontent",
"version": "52.0.2743.82",
"version": "53.0.2785.143",
"license": "MIT",
"repositoryURL": "https://github.com/electron/libchromiumcontent",
"isProd": true
@ -117,7 +117,7 @@
},
{
"name": "electron",
"version": "1.3.8",
"version": "1.4.6",
"license": "MIT",
"repositoryURL": "https://github.com/electron/electron",
"isProd": true

View file

@ -4,8 +4,8 @@ environment:
install:
- ps: Install-Product node 6.6.0 x64
- npm install -g npm
- npm install -g gulp mocha
- npm install -g npm --silent
- npm install -g gulp mocha --silent
build_script:
- .\scripts\npm.bat install --force

View file

@ -77,7 +77,7 @@ const tasks = compilations.map(function(tsconfigFile) {
sourceMappingURL: !build ? null : f => `${ baseUrl }/${ f.relative }.map`,
addComment: !!build,
includeContent: !!build,
sourceRoot: file => '../'.repeat(file.relative.split(path.sep).length) + 'src'
sourceRoot: '../src'
}))
.pipe(tsFilter.restore)
.pipe(build ? nlsDev.createAdditionalLanguageFiles(languages, i18n, out) : es.through())

View file

@ -12,6 +12,15 @@ const gulptslint = require('gulp-tslint');
const tsfmt = require('typescript-formatter');
const tslint = require('tslint');
/**
* Hygiene works by creating cascading subsets of all our files and
* passing them through a sequence of checks. Here are the current subsets,
* named according to the checks performed on them. Each subset contains
* the following one, as described in mathematical notation:
*
* all eol indentation copyright typescript
*/
const all = [
'*',
'build/**/*',
@ -43,7 +52,6 @@ const indentationFilter = [
'!**/lib/**',
'!**/*.d.ts',
'!**/*.d.ts.recipe',
'!extensions/typescript/server/**',
'!test/assert.js',
'!**/package.json',
'!**/npm-shrinkwrap.json',
@ -67,27 +75,29 @@ const copyrightFilter = [
'!**/*.json',
'!**/*.html',
'!**/*.template',
'!**/test/**',
'!**/*.md',
'!**/*.bat',
'!**/*.cmd',
'!resources/win32/bin/code.js',
'!**/*.xml',
'!**/*.sh',
'!**/*.txt',
'!**/*.xpm',
'!extensions/markdown/media/tomorrow.css'
'!**/*.opts',
'!**/*.disabled',
'!resources/win32/bin/code.js',
'!extensions/markdown/media/tomorrow.css',
'!extensions/html/server/src/modes/typescript/*'
];
const tslintFilter = [
'src/**/*.ts',
'extensions/**/*.ts',
'!**/*.d.ts',
'!**/fixtures/**',
'!**/typings/**',
'!src/vs/base/**/*.test.ts',
'!**/node_modules/**',
'!extensions/typescript/test/colorize-fixtures/**',
'!extensions/vscode-api-tests/testWorkspace/**',
'!src/vs/workbench/**/*.test.ts',
'!extensions/**/*.test.ts'
];
@ -105,7 +115,7 @@ function reportFailures(failures) {
const line = position.lineAndCharacter ? position.lineAndCharacter.line : position.line;
const character = position.lineAndCharacter ? position.lineAndCharacter.character : position.character;
console.error(`${ name }:${ line + 1}:${ character + 1 }:${ failure.failure }`);
console.error(`${name}:${line + 1}:${character + 1}:${failure.failure}`);
});
}
@ -178,7 +188,7 @@ const hygiene = exports.hygiene = (some, options) => {
});
});
const tsl = es.through(function(file) {
const tsl = es.through(function (file) {
const configuration = tslint.findConfiguration(null, '.');
const options = { configuration, formatter: 'json', rulesDirectory: 'build/lib/tslint' };
const contents = file.contents.toString('utf8');

View file

@ -39,12 +39,12 @@ const nodeModules = ['electron', 'original-fs']
// Build
const builtInExtensions = [
{ name: 'ms-vscode.node-debug', version: '1.7.8' },
{ name: 'ms-vscode.node-debug', version: '1.8.3' },
{ name: 'ms-vscode.node-debug2', version: '1.8.1' }
];
const vscodeEntryPoints = _.flatten([
buildfile.entrypoint('vs/workbench/workbench.main'),
buildfile.entrypoint('vs/workbench/electron-browser/workbench.main'),
buildfile.base,
buildfile.workbench,
buildfile.code
@ -66,6 +66,7 @@ const vscodeResources = [
'out-build/vs/workbench/parts/git/**/*.html',
'out-build/vs/workbench/parts/git/**/*.sh',
'out-build/vs/workbench/parts/html/browser/webview.html',
'out-build/vs/workbench/parts/html/browser/webview-pre.js',
'out-build/vs/**/markdown.css',
'out-build/vs/workbench/parts/tasks/**/*.json',
'out-build/vs/workbench/parts/terminal/electron-browser/terminalProcess.js',
@ -185,8 +186,8 @@ function packageTask(platform, arch, opts) {
const out = opts.minified ? 'out-vscode-min' : 'out-vscode';
const checksums = computeChecksums(out, [
'vs/workbench/workbench.main.js',
'vs/workbench/workbench.main.css',
'vs/workbench/electron-browser/workbench.main.js',
'vs/workbench/electron-browser/workbench.main.css',
'vs/workbench/electron-browser/bootstrap/index.html',
'vs/workbench/electron-browser/bootstrap/index.js'
]);
@ -289,7 +290,6 @@ function packageTask(platform, arch, opts) {
if (platform === 'win32') {
result = es.merge(result, gulp.src('resources/win32/bin/code.js', { base: 'resources/win32' }));
result = es.merge(result, gulp.src('resources/win32/bin/cat.exe', { base: 'resources/win32' }));
result = es.merge(result, gulp.src('resources/win32/bin/code.cmd', { base: 'resources/win32' })
.pipe(replace('@@NAME@@', product.nameShort))

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.
*--------------------------------------------------------------------------------------------*/
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var path_1 = require('path');
var Lint = require('tslint/lib/lint');
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
_super.apply(this, arguments);
}
Rule.prototype.apply = function (sourceFile) {
return this.applyWithWalker(new ImportPatterns(sourceFile, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var ImportPatterns = (function (_super) {
__extends(ImportPatterns, _super);
function ImportPatterns(file, opts) {
_super.call(this, file, opts);
this.imports = Object.create(null);
}
ImportPatterns.prototype.visitImportDeclaration = function (node) {
var path = node.moduleSpecifier.getText();
// remove quotes
path = path.slice(1, -1);
if (path[0] === '.') {
path = path_1.join(path_1.dirname(node.getSourceFile().fileName), path);
}
if (this.imports[path]) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Duplicate imports for '" + path + "'."));
}
this.imports[path] = true;
};
return ImportPatterns;
}(Lint.RuleWalker));

View file

@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as ts from 'typescript';
import { join, dirname } from 'path';
import * as Lint from 'tslint/lib/lint';
export class Rule extends Lint.Rules.AbstractRule {
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new ImportPatterns(sourceFile, this.getOptions()));
}
}
class ImportPatterns extends Lint.RuleWalker {
private imports: { [path: string]: boolean; } = Object.create(null);
constructor(file: ts.SourceFile, opts: Lint.IOptions) {
super(file, opts);
}
protected visitImportDeclaration(node: ts.ImportDeclaration): void {
let path = node.moduleSpecifier.getText();
// remove quotes
path = path.slice(1, -1);
if (path[0] === '.') {
path = join(dirname(node.getSourceFile().fileName), path);
}
if (this.imports[path]) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Duplicate imports for '${path}'.`));
}
this.imports[path] = true;
}
}

View file

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Lint = require('tslint/lib/lint');
var minimatch = require('minimatch');
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
_super.apply(this, arguments);
}
Rule.prototype.apply = function (sourceFile) {
var configs = this.getOptions().ruleArguments;
for (var _i = 0, configs_1 = configs; _i < configs_1.length; _i++) {
var config = configs_1[_i];
if (minimatch(sourceFile.fileName, config.target)) {
return this.applyWithWalker(new ImportPatterns(sourceFile, this.getOptions(), config));
}
}
return [];
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var ImportPatterns = (function (_super) {
__extends(ImportPatterns, _super);
function ImportPatterns(file, opts, _config) {
_super.call(this, file, opts);
this._config = _config;
}
ImportPatterns.prototype.visitImportDeclaration = function (node) {
var path = node.moduleSpecifier.getText();
// remove quotes
path = path.slice(1, -1);
// ignore relative paths
if (path[0] === '.') {
return;
}
if (!minimatch(path, this._config.restrictions)) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Imports violates '" + this._config.restrictions + "'-restriction."));
}
};
return ImportPatterns;
}(Lint.RuleWalker));

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 * as ts from 'typescript';
import * as Lint from 'tslint/lib/lint';
import * as minimatch from 'minimatch';
interface ImportPatternsConfig {
target: string;
restrictions: string;
}
export class Rule extends Lint.Rules.AbstractRule {
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
const configs = <ImportPatternsConfig[]>this.getOptions().ruleArguments;
for (const config of configs) {
if (minimatch(sourceFile.fileName, config.target)) {
return this.applyWithWalker(new ImportPatterns(sourceFile, this.getOptions(), config));
}
}
return [];
}
}
class ImportPatterns extends Lint.RuleWalker {
constructor(file: ts.SourceFile, opts: Lint.IOptions, private _config: ImportPatternsConfig) {
super(file, opts);
}
protected visitImportDeclaration(node: ts.ImportDeclaration): void {
let path = node.moduleSpecifier.getText();
// remove quotes
path = path.slice(1, -1);
// ignore relative paths
if (path[0] === '.') {
return;
}
if (!minimatch(path, this._config.restrictions)) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Imports violates '${this._config.restrictions}'-restriction.`));
}
}
}

View file

@ -0,0 +1,78 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Lint = require('tslint/lib/lint');
var path_1 = require('path');
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
_super.apply(this, arguments);
}
Rule.prototype.apply = function (sourceFile) {
var parts = path_1.dirname(sourceFile.fileName).split(/\\|\//);
var ruleArgs = this.getOptions().ruleArguments[0];
var config;
for (var i = parts.length - 1; i >= 0; i--) {
if (ruleArgs[parts[i]]) {
config = {
allowed: new Set(ruleArgs[parts[i]]).add(parts[i]),
disallowed: new Set()
};
Object.keys(ruleArgs).forEach(function (key) {
if (!config.allowed.has(key)) {
config.disallowed.add(key);
}
});
break;
}
}
if (!config) {
return [];
}
return this.applyWithWalker(new LayeringRule(sourceFile, config, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var LayeringRule = (function (_super) {
__extends(LayeringRule, _super);
function LayeringRule(file, config, opts) {
_super.call(this, file, opts);
this._config = config;
}
LayeringRule.prototype.visitImportDeclaration = function (node) {
var path = node.moduleSpecifier.getText();
// remove quotes
path = path.slice(1, -1);
if (path[0] === '.') {
path = path_1.join(path_1.dirname(node.getSourceFile().fileName), path);
}
var parts = path_1.dirname(path).split(/\\|\//);
for (var i = parts.length - 1; i >= 0; i--) {
var part = parts[i];
if (this._config.allowed.has(part)) {
// GOOD - same layer
return;
}
if (this._config.disallowed.has(part)) {
// BAD - wrong layer
var message = "Bad layering. You are not allowed to access '" + part + "' from here, allowed layers are: [" + LayeringRule._print(this._config.allowed) + "]";
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), message));
return;
}
}
};
LayeringRule._print = function (set) {
var r = [];
set.forEach(function (e) { return r.push(e); });
return r.join(', ');
};
return LayeringRule;
}(Lint.RuleWalker));

View file

@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as ts from 'typescript';
import * as Lint from 'tslint/lib/lint';
import { join, dirname } from 'path';
interface Config {
allowed: Set<string>;
disallowed: Set<string>;
}
export class Rule extends Lint.Rules.AbstractRule {
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
const parts = dirname(sourceFile.fileName).split(/\\|\//);
let ruleArgs = this.getOptions().ruleArguments[0];
let config: Config;
for (let i = parts.length - 1; i >= 0; i--) {
if (ruleArgs[parts[i]]) {
config = {
allowed: new Set<string>(<string[]>ruleArgs[parts[i]]).add(parts[i]),
disallowed: new Set<string>()
};
Object.keys(ruleArgs).forEach(key => {
if (!config.allowed.has(key)) {
config.disallowed.add(key);
}
});
break;
}
}
if (!config) {
return [];
}
return this.applyWithWalker(new LayeringRule(sourceFile, config, this.getOptions()));
}
}
class LayeringRule extends Lint.RuleWalker {
private _config: Config;
constructor(file: ts.SourceFile, config: Config, opts: Lint.IOptions) {
super(file, opts);
this._config = config;
}
protected visitImportDeclaration(node: ts.ImportDeclaration): void {
let path = node.moduleSpecifier.getText();
// remove quotes
path = path.slice(1, -1);
if (path[0] === '.') {
path = join(dirname(node.getSourceFile().fileName), path);
}
const parts = dirname(path).split(/\\|\//);
for (let i = parts.length - 1; i >= 0; i--) {
const part = parts[i];
if (this._config.allowed.has(part)) {
// GOOD - same layer
return;
}
if (this._config.disallowed.has(part)) {
// BAD - wrong layer
const message = `Bad layering. You are not allowed to access '${part}' from here, allowed layers are: [${LayeringRule._print(this._config.allowed)}]`;
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), message));
return;
}
}
}
static _print(set: Set<string>): string {
let r: string[] = [];
set.forEach(e => r.push(e));
return r.join(', ');
}
}

View file

@ -0,0 +1,8 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"es2015"
]
}
}

View file

@ -98,15 +98,15 @@ function skipDirectories() {
}
exports.skipDirectories = skipDirectories;
function cleanNodeModule(name, excludes, includes) {
var glob = function (path) { return '**/node_modules/' + name + (path ? '/' + path : ''); };
var toGlob = function (path) { return '**/node_modules/' + name + (path ? '/' + path : ''); };
var negate = function (str) { return '!' + str; };
var allFilter = _filter(glob('**'), { restore: true });
var globs = [glob('**')].concat(excludes.map(_.compose(negate, glob)));
var allFilter = _filter(toGlob('**'), { restore: true });
var globs = [toGlob('**')].concat(excludes.map(_.compose(negate, toGlob)));
var input = es.through();
var nodeModuleInput = input.pipe(allFilter);
var output = nodeModuleInput.pipe(_filter(globs));
if (includes) {
var includeGlobs = includes.map(glob);
var includeGlobs = includes.map(toGlob);
output = es.merge(output, nodeModuleInput.pipe(_filter(includeGlobs)));
}
output = output.pipe(allFilter.restore);

View file

@ -6,6 +6,19 @@
const cp = require('child_process');
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
function npmInstall(location) {
const result = cp.spawnSync(npm, ['install'], {
cwd: location ,
stdio: 'inherit'
});
if (result.error || result.status !== 0) {
process.exit(1);
}
}
npmInstall('extensions'); // node modules shared by all extensions
const extensions = [
'vscode-api-tests',
'vscode-colorize-tests',
@ -20,13 +33,4 @@ const extensions = [
'html'
];
extensions.forEach(extension => {
const result = cp.spawnSync(npm, ['install'], {
cwd: `extensions/${extension}`,
stdio: 'inherit'
});
if (result.error || result.status !== 0) {
process.exit(1);
}
});
extensions.forEach(extension => npmInstall(`extensions/${extension}`));

View file

@ -55,7 +55,7 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
Name: "addcontextmenufiles"; Description: "{cm:AddContextMenuFiles,{#NameShort}}"; GroupDescription: "{cm:Other}"; Flags: unchecked
Name: "addcontextmenufolders"; Description: "{cm:AddContextMenuFolders,{#NameShort}}"; GroupDescription: "{cm:Other}"; Flags: unchecked
Name: "associatewithfiles"; Description: "{cm:AssociateWithFiles,{#NameShort}}"; GroupDescription: "{cm:Other}"
Name: "associatewithfiles"; Description: "{cm:AssociateWithFiles,{#NameShort}}"; GroupDescription: "{cm:Other}"; Flags: unchecked
Name: "addtopath"; Description: "{cm:AddToPath}"; GroupDescription: "{cm:Other}"
Name: "runcode"; Description: "{cm:RunAfter,{#NameShort}}"; GroupDescription: "{cm:Other}"; Check: WizardSilent

View file

@ -18,9 +18,10 @@
"scopeName": "source.coffee",
"path": "./syntaxes/coffeescript.json"
}],
"debuggers": [{
"type": "node",
"enableBreakpointsFor": { "languageIds": ["coffeescript"] }
}]
"breakpoints": [
{
"language": "coffeescript"
}
]
}
}

View file

@ -421,8 +421,8 @@
"c": "Vehicle",
"t": "class.coffee.entity.inherited-class.meta.other",
"r": {
"dark_plus": ".vs-dark .token rgb(212, 212, 212)",
"light_plus": ".vs .token rgb(0, 0, 0)",
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.other.inherited-class rgb(78, 201, 176)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.other.inherited-class rgb(38, 127, 153)",
"dark_vs": ".vs-dark .token rgb(212, 212, 212)",
"light_vs": ".vs .token rgb(0, 0, 0)",
"hc_black": ".hc-black .token rgb(255, 255, 255)"

View file

@ -44,12 +44,22 @@ function registerKeybindingsCompletions(): vscode.Disposable {
});
}
function updateLaunchJsonDecorations(editor: vscode.TextEditor) {
function newCompletionItem(text: string, range: vscode.Range) {
const item = new vscode.CompletionItem(JSON.stringify(text));
item.kind = vscode.CompletionItemKind.Value;
item.textEdit = {
range,
newText: item.label
};
return item;
}
function updateLaunchJsonDecorations(editor: vscode.TextEditor | undefined) {
if (!editor || path.basename(editor.document.fileName) !== 'launch.json') {
return;
}
const ranges = [];
const ranges: vscode.Range[] = [];
let addPropertyAndValue = false;
visit(editor.document.getText(), {
onObjectProperty: (property, offset, length) => {
@ -68,13 +78,3 @@ function updateLaunchJsonDecorations(editor: vscode.TextEditor) {
editor.setDecorations(decoration, ranges);
}
function newCompletionItem(text: string, range: vscode.Range, documentation?: string) {
const item = new vscode.CompletionItem(JSON.stringify(text));
item.kind = vscode.CompletionItemKind.Value;
item.documentation = documentation;
item.textEdit = {
range,
newText: item.label
};
return item;
}

View file

@ -3,9 +3,10 @@
"noLib": true,
"target": "es5",
"module": "commonjs",
"outDir": "./out"
"outDir": "./out",
"strictNullChecks": true
},
"exclude": [
"node_modules"
]
}
}

View file

@ -5,7 +5,6 @@
'use strict';
import { window, workspace, DecorationOptions, DecorationRenderOptions, Disposable, Range, TextDocument, TextEditor } from 'vscode';
import { isEmbeddedContentUri, getHostDocumentUri } from './embeddedContentUri';
const MAX_DECORATORS = 500;
@ -64,9 +63,8 @@ export function activateColorDecorations(decoratorProvider: (uri: string) => The
if (triggerUpdate) {
pendingUpdateRequests[documentUriStr] = setTimeout(() => {
// check if the document is in use by an active editor
let contentHostUri = isEmbeddedContentUri(documentUri) ? getHostDocumentUri(documentUri) : documentUriStr;
window.visibleTextEditors.forEach(editor => {
if (editor.document && contentHostUri === editor.document.uri.toString()) {
if (editor.document && documentUriStr === editor.document.uri.toString()) {
updateDecorationForEditor(editor, documentUriStr);
}
});

View file

@ -1,27 +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 { Uri } from 'vscode';
export const EMBEDDED_CONTENT_SCHEME = 'embedded-content';
export function isEmbeddedContentUri(virtualDocumentUri: Uri): boolean {
return virtualDocumentUri.scheme === EMBEDDED_CONTENT_SCHEME;
}
export function getEmbeddedContentUri(parentDocumentUri: string, embeddedLanguageId: string): Uri {
return new Uri().with({ scheme: EMBEDDED_CONTENT_SCHEME, authority: embeddedLanguageId, path: '/' + encodeURIComponent(parentDocumentUri) + '.' + embeddedLanguageId });
};
export function getHostDocumentUri(virtualDocumentUri: Uri): string {
let languageId = virtualDocumentUri.authority;
let path = virtualDocumentUri.path.substring(1, virtualDocumentUri.path.length - languageId.length - 1); // remove leading '/' and new file extension
return decodeURIComponent(path);
};
export function getEmbeddedLanguageId(virtualDocumentUri: Uri): string {
return virtualDocumentUri.authority;
}

View file

@ -3,9 +3,9 @@
"version": "1.0.0",
"dependencies": {
"vscode-css-languageservice": {
"version": "1.1.0",
"version": "2.0.0-next.4",
"from": "vscode-css-languageservice@next",
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-1.1.0.tgz"
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.0.0-next.4.tgz"
},
"vscode-jsonrpc": {
"version": "2.3.2-next.5",
@ -25,19 +25,14 @@
}
},
"vscode-languageserver-types": {
"version": "1.0.3",
"from": "vscode-languageserver-types@>=1.0.3 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.3.tgz"
"version": "1.0.5-next.1",
"from": "vscode-languageserver-types@>=1.0.5-next.1 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.5-next.1.tgz"
},
"vscode-nls": {
"version": "1.0.7",
"from": "vscode-nls@>=1.0.4 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-1.0.7.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"
}
}
}

View file

@ -8,9 +8,8 @@
"node": "*"
},
"dependencies": {
"vscode-css-languageservice": "^1.1.0",
"vscode-languageserver": "^2.4.0-next.12",
"vscode-uri": "^1.0.0"
"vscode-css-languageservice": "^2.0.0-next.4",
"vscode-languageserver": "^2.4.0-next.12"
},
"scripts": {
"compile": "gulp compile-extension:css-server",

View file

@ -11,8 +11,6 @@ import {
import { getCSSLanguageService, getSCSSLanguageService, getLESSLanguageService, LanguageSettings, LanguageService, Stylesheet } from 'vscode-css-languageservice';
import { getLanguageModelCache } from './languageModelCache';
import Uri from 'vscode-uri';
import { isEmbeddedContentUri, getHostDocumentUri } from './embeddedContentUri';
namespace ColorSymbolRequest {
export const type: RequestType<string, Range[], any> = { get method() { return 'css/colorSymbols'; } };
@ -127,9 +125,7 @@ function validateTextDocument(textDocument: TextDocument): void {
let stylesheet = stylesheets.get(textDocument);
let diagnostics = getLanguageService(textDocument).doValidation(textDocument, stylesheet);
// Send the computed diagnostics to VSCode.
let uri = Uri.parse(textDocument.uri);
let diagnosticsTarget = isEmbeddedContentUri(uri) ? getHostDocumentUri(uri) : textDocument.uri;
connection.sendDiagnostics({ uri: diagnosticsTarget, diagnostics });
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
}
connection.onCompletion(textDocumentPosition => {

View file

@ -1,27 +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 Uri from 'vscode-uri';
export const EMBEDDED_CONTENT_SCHEME = 'embedded-content';
export function isEmbeddedContentUri(virtualDocumentUri: Uri): boolean {
return virtualDocumentUri.scheme === EMBEDDED_CONTENT_SCHEME;
}
export function getEmbeddedContentUri(parentDocumentUri: string, embeddedLanguageId: string): Uri {
return Uri.from({ scheme: EMBEDDED_CONTENT_SCHEME, authority: embeddedLanguageId, path: '/' + encodeURIComponent(parentDocumentUri) + '.' + embeddedLanguageId });
};
export function getHostDocumentUri(virtualDocumentUri: Uri): string {
let languageId = virtualDocumentUri.authority;
let path = virtualDocumentUri.path.substring(1, virtualDocumentUri.path.length - languageId.length - 1); // remove leading '/' and new file extension
return decodeURIComponent(path);
};
export function getEmbeddedLanguageId(virtualDocumentUri: Uri): string {
return virtualDocumentUri.authority;
}

View file

@ -3,8 +3,6 @@
"noLib": true,
"target": "es5",
"module": "commonjs",
"sourceMap": true,
"sourceRoot": "../src",
"outDir": "./out"
},
"exclude": [

View file

@ -2,27 +2,28 @@
"transition property": {
"prefix": "transition",
"body": [
"-webkit-transition: ${property} ${duration} ${timing-function} ${delay};",
"-moz-transition: ${property} ${duration} ${timing-function} ${delay};",
"transition: ${property} ${duration} ${timing-function} ${delay};"
"-webkit-transition: ${1:property} ${2:duration} ${3:timing-function} ${4:delay};",
"-moz-transition: ${1:property} ${2:duration} ${3:timing-function} ${4:delay};",
"transition: ${1:property} ${2:duration} ${3:timing-function} ${4:delay};"
],
"description": "The transition property across browsers"
},
"border": {
"prefix": "border",
"body": [
"border: ${width} ${border-style} ${color};$0"
"border: ${1:width} ${2:border-style} ${3:color};$0"
],
"description": "[width] [border-style] [color]"
},
"gradient": {
"prefix": "gradient",
"body": [
"background-image: -webkit-gradient(linear, left top, left bottom, from(${start-color}), to(${end-color}));",
"background-image: -webkit-linear-gradient(top, ${start-color}, ${end-color});",
"background-image: -moz-linear-gradient(top, ${start-color}, ${end-color});",
"background-image: linear-gradient(to bottom, ${start-color}, ${end-color});"
"background-image: -webkit-gradient(linear, left top, left bottom, from(${1:start-color}), to(${2:end-color}));",
"background-image: -webkit-linear-gradient(top, ${1:start-color}, ${2:end-color});",
"background-image: -moz-linear-gradient(top, ${1:start-color}, ${2:end-color});",
"background-image: linear-gradient(to bottom, ${1:start-color}, ${2:end-color});"
],
"description": "Set the 'background-image' property to a linear gradient"
}
}

View file

@ -2,10 +2,5 @@
"name": "extension-editing",
"version": "0.0.1",
"dependencies": {
"typescript": {
"version": "1.8.10",
"from": "typescript@>=1.8.10 <2.0.0",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-1.8.10.tgz"
}
}
}

View file

@ -13,13 +13,9 @@
],
"main": "./out/extension",
"scripts": {
"postinstall": "node ./postinstall",
"compile": "gulp compile-extension:extension-editing",
"watch": "gulp watch-extension:extension-editing"
},
"dependencies": {
"typescript": "^1.8.10"
},
"contributes": {
"jsonValidation": [
{

View file

@ -1,23 +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';
const fs = require('fs');
const path = require('path');
// delete unused typescript stuff
const root = path.dirname(require.resolve('typescript'));
for (let name of fs.readdirSync(root)) {
if (name !== 'typescript.d.ts' && name !== 'typescript.js') {
try {
fs.unlinkSync(path.join(root, name));
console.log(`removed '${path.join(root, name)}'`);
} catch (e) {
console.warn(e);
}
}
}

View file

@ -83,7 +83,7 @@ namespace ast {
let end = Number.MAX_VALUE;
for (let name of dottedName.split('.')) {
let idx: number;
let idx: number = -1;
while ((idx = identifiers.indexOf(name, idx + 1)) >= 0) {
let myStart = spans[2 * idx];
let myEnd = spans[2 * idx + 1];

View file

@ -24,6 +24,14 @@
"sourceMaps": true,
"outDir": "${workspaceRoot}/client/out/test",
"preLaunchTask": "npm"
},
{
"name": "Attach Language Server",
"type": "node",
"request": "attach",
"port": 6004,
"sourceMaps": true,
"outDir": "${workspaceRoot}/server/out"
}
]
}

View file

@ -0,0 +1,95 @@
/*---------------------------------------------------------------------------------------------
* 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 { window, workspace, DecorationOptions, DecorationRenderOptions, Disposable, Range, TextDocument, TextEditor } from 'vscode';
const MAX_DECORATORS = 500;
let decorationType: DecorationRenderOptions = {
before: {
contentText: ' ',
border: 'solid 0.1em #000',
margin: '0.1em 0.2em 0 0.2em',
width: '0.8em',
height: '0.8em'
},
dark: {
before: {
border: 'solid 0.1em #eee'
}
}
};
export function activateColorDecorations(decoratorProvider: (uri: string) => Thenable<Range[]>, supportedLanguages: { [id: string]: boolean }): Disposable {
let disposables: Disposable[] = [];
let colorsDecorationType = window.createTextEditorDecorationType(decorationType);
disposables.push(colorsDecorationType);
let pendingUpdateRequests: { [key: string]: NodeJS.Timer; } = {};
// we care about all visible editors
window.visibleTextEditors.forEach(editor => {
if (editor.document) {
triggerUpdateDecorations(editor.document);
}
});
// to get visible one has to become active
window.onDidChangeActiveTextEditor(editor => {
if (editor) {
triggerUpdateDecorations(editor.document);
}
}, null, disposables);
workspace.onDidChangeTextDocument(event => triggerUpdateDecorations(event.document), null, disposables);
workspace.onDidOpenTextDocument(triggerUpdateDecorations, null, disposables);
workspace.onDidCloseTextDocument(triggerUpdateDecorations, null, disposables);
workspace.textDocuments.forEach(triggerUpdateDecorations);
function triggerUpdateDecorations(document: TextDocument) {
let triggerUpdate = supportedLanguages[document.languageId];
let documentUri = document.uri;
let documentUriStr = documentUri.toString();
let timeout = pendingUpdateRequests[documentUriStr];
if (typeof timeout !== 'undefined') {
clearTimeout(timeout);
triggerUpdate = true; // force update, even if languageId is not supported (anymore)
}
if (triggerUpdate) {
pendingUpdateRequests[documentUriStr] = setTimeout(() => {
// check if the document is in use by an active editor
window.visibleTextEditors.forEach(editor => {
if (editor.document && documentUriStr === editor.document.uri.toString()) {
updateDecorationForEditor(editor, documentUriStr);
}
});
delete pendingUpdateRequests[documentUriStr];
}, 500);
}
}
function updateDecorationForEditor(editor: TextEditor, contentUri: string) {
let document = editor.document;
decoratorProvider(contentUri).then(ranges => {
let decorations = ranges.slice(0, MAX_DECORATORS).map(range => {
let color = document.getText(range);
return <DecorationOptions>{
range: range,
renderOptions: {
before: {
backgroundColor: color
}
}
};
});
editor.setDecorations(colorsDecorationType, decorations);
});
}
return Disposable.from(...disposables);
}

View file

@ -1,124 +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 { workspace, Uri, EventEmitter, Disposable, TextDocument } from 'vscode';
import { LanguageClient, RequestType, NotificationType } from 'vscode-languageclient';
import { getEmbeddedContentUri, getEmbeddedLanguageId, getHostDocumentUri, isEmbeddedContentUri, EMBEDDED_CONTENT_SCHEME } from './embeddedContentUri';
interface EmbeddedContentParams {
uri: string;
embeddedLanguageId: string;
}
interface EmbeddedContent {
content: string;
version: number;
}
namespace EmbeddedContentRequest {
export const type: RequestType<EmbeddedContentParams, EmbeddedContent, any> = { get method() { return 'embedded/content'; } };
}
export interface EmbeddedDocuments extends Disposable {
getEmbeddedContentUri: (parentDocumentUri: string, embeddedLanguageId: string) => Uri;
openEmbeddedContentDocument: (embeddedContentUri: Uri, expectedVersion: number) => Thenable<TextDocument>;
}
interface EmbeddedContentChangedParams {
uri: string;
version: number;
embeddedLanguageIds: string[];
}
namespace EmbeddedContentChangedNotification {
export const type: NotificationType<EmbeddedContentChangedParams> = { get method() { return 'embedded/contentchanged'; } };
}
export function initializeEmbeddedContentDocuments(parentDocumentSelector: string[], embeddedLanguages: { [languageId: string]: boolean }, client: LanguageClient): EmbeddedDocuments {
let toDispose: Disposable[] = [];
let embeddedContentChanged = new EventEmitter<Uri>();
// remember all open virtual documents with the version of the content
let openVirtualDocuments: { [uri: string]: number } = {};
// documents are closed after a time out or when collected.
toDispose.push(workspace.onDidCloseTextDocument(d => {
if (isEmbeddedContentUri(d.uri)) {
delete openVirtualDocuments[d.uri.toString()];
}
}));
// virtual document provider
toDispose.push(workspace.registerTextDocumentContentProvider(EMBEDDED_CONTENT_SCHEME, {
provideTextDocumentContent: uri => {
if (isEmbeddedContentUri(uri)) {
let contentRequestParms = { uri: getHostDocumentUri(uri), embeddedLanguageId: getEmbeddedLanguageId(uri) };
return client.sendRequest(EmbeddedContentRequest.type, contentRequestParms).then(content => {
if (content) {
openVirtualDocuments[uri.toString()] = content.version;
return content.content;
} else {
delete openVirtualDocuments[uri.toString()];
return '';
}
});
}
return '';
},
onDidChange: embeddedContentChanged.event
}));
// diagnostics for embedded contents
client.onNotification(EmbeddedContentChangedNotification.type, p => {
for (let languageId in embeddedLanguages) {
if (p.embeddedLanguageIds.indexOf(languageId) !== -1) {
// open the document so that validation is triggered in the embedded mode
let virtualUri = getEmbeddedContentUri(p.uri, languageId);
openEmbeddedContentDocument(virtualUri, p.version);
}
}
});
function ensureContentUpdated(virtualURI: Uri, expectedVersion: number) {
let virtualURIString = virtualURI.toString();
let virtualDocVersion = openVirtualDocuments[virtualURIString];
if (isDefined(virtualDocVersion) && virtualDocVersion !== expectedVersion) {
return new Promise<void>((resolve, reject) => {
let subscription = workspace.onDidChangeTextDocument(d => {
if (d.document.uri.toString() === virtualURIString) {
subscription.dispose();
resolve();
}
});
embeddedContentChanged.fire(virtualURI);
});
}
return Promise.resolve();
};
function openEmbeddedContentDocument(virtualURI: Uri, expectedVersion: number): Thenable<TextDocument> {
return ensureContentUpdated(virtualURI, expectedVersion).then(_ => {
return workspace.openTextDocument(virtualURI).then(document => {
if (expectedVersion === openVirtualDocuments[virtualURI.toString()]) {
return document;
}
return void 0;
});
});
};
return {
getEmbeddedContentUri,
openEmbeddedContentDocument,
dispose: Disposable.from(...toDispose).dispose
};
}
function isDefined(o: any) {
return typeof o !== 'undefined';
}

View file

@ -1,27 +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 { Uri } from 'vscode';
export const EMBEDDED_CONTENT_SCHEME = 'embedded-content';
export function isEmbeddedContentUri(virtualDocumentUri: Uri): boolean {
return virtualDocumentUri.scheme === EMBEDDED_CONTENT_SCHEME;
}
export function getEmbeddedContentUri(parentDocumentUri: string, embeddedLanguageId: string): Uri {
return new Uri().with({ scheme: EMBEDDED_CONTENT_SCHEME, authority: embeddedLanguageId, path: '/' + encodeURIComponent(parentDocumentUri) + '.' + embeddedLanguageId });
};
export function getHostDocumentUri(virtualDocumentUri: Uri): string {
let languageId = virtualDocumentUri.authority;
let path = virtualDocumentUri.path.substring(1, virtualDocumentUri.path.length - languageId.length - 1); // remove leading '/' and new file extension
return decodeURIComponent(path);
};
export function getEmbeddedLanguageId(virtualDocumentUri: Uri): string {
return virtualDocumentUri.authority;
}

View file

@ -6,35 +6,16 @@
import * as path from 'path';
import { languages, workspace, ExtensionContext, IndentAction, commands, CompletionList, Hover } from 'vscode';
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, Position, RequestType, Protocol2Code, Code2Protocol } from 'vscode-languageclient';
import { CompletionList as LSCompletionList, Hover as LSHover } from 'vscode-languageserver-types';
import { languages, workspace, ExtensionContext, IndentAction } from 'vscode';
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, Range, RequestType, Protocol2Code } from 'vscode-languageclient';
import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared';
import { initializeEmbeddedContentDocuments } from './embeddedContentDocuments';
import { activateColorDecorations } from './colorDecorators';
import * as nls from 'vscode-nls';
let localize = nls.loadMessageBundle();
interface EmbeddedCompletionParams {
uri: string;
version: number;
embeddedLanguageId: string;
position: Position;
}
namespace EmbeddedCompletionRequest {
export const type: RequestType<EmbeddedCompletionParams, LSCompletionList, any> = { get method() { return 'embedded/completion'; } };
}
interface EmbeddedHoverParams {
uri: string;
version: number;
embeddedLanguageId: string;
position: Position;
}
namespace EmbeddedHoverRequest {
export const type: RequestType<EmbeddedHoverParams, LSHover, any> = { get method() { return 'embedded/hover'; } };
namespace ColorSymbolRequest {
export const type: RequestType<string, Range[], any> = { get method() { return 'css/colorSymbols'; } };
}
export function activate(context: ExtensionContext) {
@ -52,13 +33,13 @@ export function activate(context: ExtensionContext) {
};
let documentSelector = ['html', 'handlebars', 'razor'];
let embeddedLanguages = { 'css': true };
let embeddedLanguages = { css: true, javascript: true };
// Options to control the language client
let clientOptions: LanguageClientOptions = {
documentSelector,
synchronize: {
configurationSection: ['html'], // Synchronize the setting section 'html' to the server
configurationSection: ['html', 'css', 'javascript'], // the settings to synchronize
},
initializationOptions: {
embeddedLanguages,
@ -67,56 +48,20 @@ 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);
let embeddedDocuments = initializeEmbeddedContentDocuments(documentSelector, embeddedLanguages, client);
context.subscriptions.push(embeddedDocuments);
client.onRequest(EmbeddedCompletionRequest.type, params => {
let position = Protocol2Code.asPosition(params.position);
let virtualDocumentURI = embeddedDocuments.getEmbeddedContentUri(params.uri, params.embeddedLanguageId);
return embeddedDocuments.openEmbeddedContentDocument(virtualDocumentURI, params.version).then(document => {
if (document) {
return commands.executeCommand<CompletionList>('vscode.executeCompletionItemProvider', virtualDocumentURI, position).then(completionList => {
if (completionList) {
return {
isIncomplete: completionList.isIncomplete,
items: completionList.items.map(Code2Protocol.asCompletionItem)
};
}
return { isIncomplete: true, items: [] };
});
}
return { isIncomplete: true, items: [] };
});
});
client.onRequest(EmbeddedHoverRequest.type, params => {
let position = Protocol2Code.asPosition(params.position);
let virtualDocumentURI = embeddedDocuments.getEmbeddedContentUri(params.uri, params.embeddedLanguageId);
return embeddedDocuments.openEmbeddedContentDocument(virtualDocumentURI, params.version).then(document => {
if (document) {
return commands.executeCommand<Hover[]>('vscode.executeHoverProvider', virtualDocumentURI, position).then(hover => {
if (hover && hover.length > 0) {
return <LSHover>{
contents: hover[0].contents,
range: Code2Protocol.asRange(hover[0].range)
};
}
return void 0;
});
}
return void 0;
});
});
let client = new LanguageClient('html', localize('htmlserver.name', 'HTML Language Server'), serverOptions, clientOptions, true);
let disposable = client.start();
// Push the disposable to the context's subscriptions so that the
// client can be deactivated on extension deactivation
context.subscriptions.push(disposable);
let colorRequestor = (uri: string) => {
return client.sendRequest(ColorSymbolRequest.type, uri).then(ranges => ranges.map(Protocol2Code.asRange));
};
disposable = activateColorDecorations(colorRequestor, { html: true, handlebars: true, razor: true });
context.subscriptions.push(disposable);
languages.setLanguageConfiguration('html', {
wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\$\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s]+)/g,
onEnterRules: [

View file

@ -8,14 +8,14 @@
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-2.4.0.tgz"
},
"vscode-languageclient": {
"version": "2.6.0-next.1",
"from": "vscode-languageclient@>=2.6.0-next.1 <3.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-2.6.0-next.1.tgz"
"version": "2.6.4-next.1",
"from": "vscode-languageclient@next",
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-2.6.4-next.1.tgz"
},
"vscode-languageserver-types": {
"version": "1.0.4-next.2",
"from": "vscode-languageserver-types@>=1.0.4-next.2 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.4-next.2.tgz"
"version": "1.0.5-next.1",
"from": "vscode-languageserver-types@next",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.5-next.1.tgz"
},
"vscode-nls": {
"version": "1.0.7",

View file

@ -15,8 +15,8 @@
"compile": "gulp compile-extension:html-client && gulp compile-extension:html-server",
"postinstall": "cd server && npm install",
"update-grammar": "node ../../build/npm/update-grammar.js textmate/html.tmbundle Syntaxes/HTML.plist ./syntaxes/html.json",
"install-client-next": "npm install vscode-languageclient@next -f -S",
"install-client-local": "npm install ../../../vscode-languageserver-node/client -f -S"
"install-client-next": "npm install vscode-languageserver-types@next -f -S && npm install vscode-languageclient@next -f -S",
"install-client-local": "npm install ../../../vscode-languageserver-node/types -f -S && npm install ../../../vscode-languageserver-node/client -f -S"
},
"contributes": {
"languages": [
@ -143,8 +143,8 @@
}
},
"dependencies": {
"vscode-languageclient": "^2.6.0-next.1",
"vscode-languageserver-types": "^1.0.4",
"vscode-languageclient": "^2.6.4-next.1",
"vscode-languageserver-types": "^1.0.5-next.1",
"vscode-nls": "^1.0.7"
}
}
}

View file

@ -0,0 +1,6 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "definitelytyped",
"repositoryURL": "https://github.com/DefinitelyTyped/DefinitelyTyped",
"license": "MIT"
}]

3249
extensions/html/server/lib/jquery.d.ts vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -2,10 +2,15 @@
"name": "vscode-html-languageserver",
"version": "1.0.0",
"dependencies": {
"vscode-css-languageservice": {
"version": "2.0.0-next.3",
"from": "vscode-css-languageservice@next",
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.0.0-next.3.tgz"
},
"vscode-html-languageservice": {
"version": "1.0.0-next.9",
"version": "1.0.1-next.4",
"from": "vscode-html-languageservice@next",
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-1.0.0-next.9.tgz"
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-1.0.1-next.4.tgz"
},
"vscode-jsonrpc": {
"version": "2.4.0",
@ -13,12 +18,14 @@
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-2.4.0.tgz"
},
"vscode-languageserver": {
"version": "2.6.0-next.3",
"from": "vscode-languageserver@>=2.6.0-next.3 <3.0.0"
"version": "2.6.2-next.1",
"from": "vscode-languageserver@next",
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-2.6.2-next.1.tgz"
},
"vscode-languageserver-types": {
"version": "1.0.4-next.2",
"from": "vscode-languageserver-types@>=1.0.4-next.1 <2.0.0"
"version": "1.0.5-next.1",
"from": "vscode-languageserver-types@>=1.0.5-next.1 <2.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-1.0.5-next.1.tgz"
},
"vscode-nls": {
"version": "1.0.7",

View file

@ -8,17 +8,19 @@
"node": "*"
},
"dependencies": {
"vscode-html-languageservice": "^1.0.0-next.9",
"vscode-languageserver": "^2.6.0-next.3",
"vscode-css-languageservice": "^2.0.0-next.3",
"vscode-html-languageservice": "^1.0.1-next.4",
"vscode-languageserver": "^2.6.2-next.1",
"vscode-nls": "^1.0.4",
"vscode-uri": "^1.0.0"
},
"scripts": {
"compile": "gulp compile-extension:json-server",
"watch": "gulp watch-extension:json-server",
"install-service-next": "npm install vscode-html-languageservice@next -f -S",
"install-service-local": "npm install ../../../../vscode-html-languageservice -f -S",
"install-service-next": "npm install vscode-css-languageservice@next -f -S && npm install vscode-html-languageservice@next -f -S",
"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"
"install-server-local": "npm install ../../../../vscode-languageserver-node/server -f -S",
"test": "mocha"
}
}

View file

@ -1,125 +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 { TextDocument, Position, HTMLDocument, Node, LanguageService, TokenType } from 'vscode-html-languageservice';
export function getEmbeddedLanguageAtPosition(languageService: LanguageService, document: TextDocument, htmlDocument: HTMLDocument, position: Position): string {
let offset = document.offsetAt(position);
let node = htmlDocument.findNodeAt(offset);
if (node && node.children.length === 0) {
let embeddedContent = getEmbeddedContentForNode(languageService, document, node);
if (embeddedContent && embeddedContent.start <= offset && offset <= embeddedContent.end) {
return embeddedContent.languageId;
}
}
return null;
}
export function hasEmbeddedContent(languageService: LanguageService, document: TextDocument, htmlDocument: HTMLDocument, embeddedLanguages: { [languageId: string]: boolean }): string[] {
let embeddedLanguageIds: { [languageId: string]: boolean } = {};
function collectEmbeddedLanguages(node: Node): void {
let c = getEmbeddedContentForNode(languageService, document, node);
if (c && embeddedLanguages[c.languageId] && !isWhitespace(document.getText().substring(c.start, c.end))) {
embeddedLanguageIds[c.languageId] = true;
}
node.children.forEach(collectEmbeddedLanguages);
}
htmlDocument.roots.forEach(collectEmbeddedLanguages);
return Object.keys(embeddedLanguageIds);
}
export function getEmbeddedContent(languageService: LanguageService, document: TextDocument, htmlDocument: HTMLDocument, languageId: string): string {
let contents = [];
function collectEmbeddedNodes(node: Node): void {
let c = getEmbeddedContentForNode(languageService, document, node);
if (c && c.languageId === languageId) {
contents.push(c);
}
node.children.forEach(collectEmbeddedNodes);
}
htmlDocument.roots.forEach(collectEmbeddedNodes);
let currentPos = 0;
let oldContent = document.getText();
let result = '';
for (let c of contents) {
result = substituteWithWhitespace(result, currentPos, c.start, oldContent);
result += oldContent.substring(c.start, c.end);
currentPos = c.end;
}
result = substituteWithWhitespace(result, currentPos, oldContent.length, oldContent);
return result;
}
function substituteWithWhitespace(result, start, end, oldContent) {
let accumulatedWS = 0;
for (let i = start; i < end; i++) {
let ch = oldContent[i];
if (ch === '\n' || ch === '\r') {
// only write new lines, skip the whitespace
accumulatedWS = 0;
result += ch;
} else {
accumulatedWS++;
}
}
result = append(result, ' ', accumulatedWS);
return result;
}
function append(result: string, str: string, n: number): string {
while (n) {
if (n & 1) {
result += str;
}
n >>= 1;
str += str;
}
return result;
}
function getEmbeddedContentForNode(languageService: LanguageService, document: TextDocument, node: Node): { languageId: string, start: number, end: number } {
if (node.tag === 'style') {
let scanner = languageService.createScanner(document.getText().substring(node.start, node.end));
let token = scanner.scan();
while (token !== TokenType.EOS) {
if (token === TokenType.Styles) {
return { languageId: 'css', start: node.start + scanner.getTokenOffset(), end: node.start + scanner.getTokenEnd() };
}
token = scanner.scan();
}
} else if (node.tag === 'script') {
let scanner = languageService.createScanner(document.getText().substring(node.start, node.end));
let token = scanner.scan();
let isTypeAttribute = false;
let languageId = 'javascript';
while (token !== TokenType.EOS) {
if (token === TokenType.AttributeName) {
isTypeAttribute = scanner.getTokenText() === 'type';
} else if (token === TokenType.AttributeValue) {
if (isTypeAttribute) {
if (/["'](text|application)\/(java|ecma)script["']/.test(scanner.getTokenText())) {
languageId = 'javascript';
} else {
languageId = void 0;
}
}
isTypeAttribute = false;
} else if (token === TokenType.Script) {
return { languageId, start: node.start + scanner.getTokenOffset(), end: node.start + scanner.getTokenEnd() };
}
token = scanner.scan();
}
}
return void 0;
}
function isWhitespace(str: string) {
return str.match(/^\s*$/);
}

View file

@ -4,14 +4,11 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {
createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, FormattingOptions, RequestType, NotificationType,
CompletionList, Position, Hover
} from 'vscode-languageserver';
import { createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, RequestType } from 'vscode-languageserver';
import { DocumentContext } from 'vscode-html-languageservice';
import { TextDocument, Diagnostic, DocumentLink, Range, TextEdit, SymbolInformation } from 'vscode-languageserver-types';
import { getLanguageModes, LanguageModes } from './modes/languageModes';
import { HTMLDocument, getLanguageService, CompletionConfiguration, HTMLFormatConfiguration, DocumentContext, TextDocument } from 'vscode-html-languageservice';
import { getLanguageModelCache } from './languageModelCache';
import { getEmbeddedContent, getEmbeddedLanguageAtPosition, hasEmbeddedContent } from './embeddedSupport';
import * as url from 'url';
import * as path from 'path';
import uri from 'vscode-uri';
@ -19,50 +16,8 @@ import uri from 'vscode-uri';
import * as nls from 'vscode-nls';
nls.config(process.env['VSCODE_NLS_CONFIG']);
interface EmbeddedCompletionParams {
uri: string;
version: number;
embeddedLanguageId: string;
position: Position;
}
namespace EmbeddedCompletionRequest {
export const type: RequestType<EmbeddedCompletionParams, CompletionList, any> = { get method() { return 'embedded/completion'; } };
}
interface EmbeddedHoverParams {
uri: string;
version: number;
embeddedLanguageId: string;
position: Position;
}
namespace EmbeddedHoverRequest {
export const type: RequestType<EmbeddedCompletionParams, Hover, any> = { get method() { return 'embedded/hover'; } };
}
interface EmbeddedContentParams {
uri: string;
embeddedLanguageId: string;
}
interface EmbeddedContent {
content: string;
version: number;
}
namespace EmbeddedContentRequest {
export const type: RequestType<EmbeddedContentParams, EmbeddedContent, any> = { get method() { return 'embedded/content'; } };
}
interface EmbeddedContentChangedParams {
uri: string;
version: number;
embeddedLanguageIds: string[];
}
namespace EmbeddedContentChangedNotification {
export const type: NotificationType<EmbeddedContentChangedParams> = { get method() { return 'embedded/contentchanged'; } };
namespace ColorSymbolRequest {
export const type: RequestType<string, Range[], any> = { get method() { return 'css/colorSymbols'; } };
}
// Create a connection for the server
@ -78,54 +33,50 @@ let documents: TextDocuments = new TextDocuments();
// for open, change and close text document events
documents.listen(connection);
let htmlDocuments = getLanguageModelCache<HTMLDocument>(10, 60, document => getLanguageService().parseHTMLDocument(document));
documents.onDidClose(e => {
htmlDocuments.onDocumentRemoved(e.document);
});
connection.onShutdown(() => {
htmlDocuments.dispose();
});
let workspacePath: string;
let embeddedLanguages: { [languageId: string]: boolean };
var languageModes: LanguageModes;
// 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
connection.onInitialize((params: InitializeParams): InitializeResult => {
let initializationOptions = params.initializationOptions;
workspacePath = params.rootPath;
embeddedLanguages = params.initializationOptions.embeddedLanguages;
languageModes = getLanguageModes(initializationOptions ? initializationOptions.embeddedLanguages : { css: true, javascript: true });
documents.onDidClose(e => {
languageModes.onDocumentRemoved(e.document);
});
connection.onShutdown(() => {
languageModes.dispose();
});
return {
capabilities: {
// Tell the client that the server works in FULL text document sync mode
textDocumentSync: documents.syncKind,
completionProvider: { resolveProvider: false, triggerCharacters: ['.', ':', '<', '"', '=', '/'] },
completionProvider: { resolveProvider: true, triggerCharacters: ['.', ':', '<', '"', '=', '/'] },
hoverProvider: true,
documentHighlightProvider: true,
documentRangeFormattingProvider: params.initializationOptions['format.enable'],
documentLinkProvider: true
documentRangeFormattingProvider: initializationOptions && initializationOptions['format.enable'],
documentLinkProvider: true,
documentSymbolProvider: true,
definitionProvider: true,
signatureHelpProvider: { triggerCharacters: ['('] },
referencesProvider: true
}
};
});
// create the JSON language service
var languageService = getLanguageService();
// The settings interface describes the server relevant settings part
interface Settings {
html: LanguageSettings;
}
interface LanguageSettings {
suggest: CompletionConfiguration;
format: HTMLFormatConfiguration;
}
let languageSettings: LanguageSettings;
// The settings have changed. Is send on server activation as well.
connection.onDidChangeConfiguration((change) => {
var settings = <Settings>change.settings;
languageSettings = settings.html;
languageModes.getAllModes().forEach(m => {
if (m.configure) {
m.configure(change.settings);
}
});
documents.all().forEach(triggerValidation);
});
let pendingValidationRequests: { [uri: string]: NodeJS.Timer } = {};
@ -140,10 +91,7 @@ documents.onDidChangeContent(change => {
// a document has closed: clear all diagnostics
documents.onDidClose(event => {
cleanPendingValidation(event.document);
//connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
if (embeddedLanguages) {
connection.sendNotification(EmbeddedContentChangedNotification.type, { uri: event.document.uri, version: event.document.version, embeddedLanguageIds: [] });
}
connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
});
function cleanPendingValidation(textDocument: TextDocument): void {
@ -163,94 +111,145 @@ function triggerValidation(textDocument: TextDocument): void {
}
function validateTextDocument(textDocument: TextDocument): void {
let htmlDocument = htmlDocuments.get(textDocument);
//let diagnostics = languageService.doValidation(textDocument, htmlDocument);
// Send the computed diagnostics to VSCode.
//connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
if (embeddedLanguages) {
let embeddedLanguageIds = hasEmbeddedContent(languageService, textDocument, htmlDocument, embeddedLanguages);
let p = { uri: textDocument.uri, version: textDocument.version, embeddedLanguageIds };
connection.sendNotification(EmbeddedContentChangedNotification.type, p);
let diagnostics: Diagnostic[] = [];
languageModes.getAllModesInDocument(textDocument).forEach(mode => {
if (mode.doValidation) {
pushAll(diagnostics, mode.doValidation(textDocument));
}
});
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
}
function pushAll<T>(to: T[], from: T[]) {
if (from) {
for (var i = 0; i < from.length; i++) {
to.push(from[i]);
}
}
}
connection.onCompletion(textDocumentPosition => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let htmlDocument = htmlDocuments.get(document);
let options = languageSettings && languageSettings.suggest;
let list = languageService.doComplete(document, textDocumentPosition.position, htmlDocument, options);
if (list.items.length === 0 && embeddedLanguages) {
let embeddedLanguageId = getEmbeddedLanguageAtPosition(languageService, document, htmlDocument, textDocumentPosition.position);
if (embeddedLanguageId && embeddedLanguages[embeddedLanguageId]) {
return connection.sendRequest(EmbeddedCompletionRequest.type, { uri: document.uri, version: document.version, embeddedLanguageId, position: textDocumentPosition.position });
let mode = languageModes.getModeAtPosition(document, textDocumentPosition.position);
if (mode && mode.doComplete) {
return mode.doComplete(document, textDocumentPosition.position);
}
return { isIncomplete: true, items: [] };
});
connection.onCompletionResolve(item => {
let data = item.data;
if (data && data.languageId && data.uri) {
let mode = languageModes.getMode(data.languageId);
let document = documents.get(data.uri);
if (mode && mode.doResolve && document) {
return mode.doResolve(document, item);
}
}
return list;
return item;
});
connection.onHover(textDocumentPosition => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let htmlDocument = htmlDocuments.get(document);
let hover = languageService.doHover(document, textDocumentPosition.position, htmlDocument);
if (!hover && embeddedLanguages) {
let embeddedLanguageId = getEmbeddedLanguageAtPosition(languageService, document, htmlDocument, textDocumentPosition.position);
if (embeddedLanguageId && embeddedLanguages[embeddedLanguageId]) {
return connection.sendRequest(EmbeddedHoverRequest.type, { uri: document.uri, version: document.version, embeddedLanguageId, position: textDocumentPosition.position });
}
let mode = languageModes.getModeAtPosition(document, textDocumentPosition.position);
if (mode && mode.doHover) {
return mode.doHover(document, textDocumentPosition.position);
}
return hover;
});
connection.onRequest(EmbeddedContentRequest.type, parms => {
let document = documents.get(parms.uri);
if (document) {
let htmlDocument = htmlDocuments.get(document);
return { content: getEmbeddedContent(languageService, document, htmlDocument, parms.embeddedLanguageId), version: document.version };
}
return void 0;
return null;
});
connection.onDocumentHighlight(documentHighlightParams => {
let document = documents.get(documentHighlightParams.textDocument.uri);
let htmlDocument = htmlDocuments.get(document);
return languageService.findDocumentHighlights(document, documentHighlightParams.position, htmlDocument);
let mode = languageModes.getModeAtPosition(document, documentHighlightParams.position);
if (mode && mode.findDocumentHighlight) {
return mode.findDocumentHighlight(document, documentHighlightParams.position);
}
return [];
});
function merge(src: any, dst: any): any {
for (var key in src) {
if (src.hasOwnProperty(key)) {
dst[key] = src[key];
}
connection.onDefinition(definitionParams => {
let document = documents.get(definitionParams.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, definitionParams.position);
if (mode && mode.findDefinition) {
return mode.findDefinition(document, definitionParams.position);
}
return dst;
}
return [];
});
function getFormattingOptions(formatParams: FormattingOptions) {
let formatSettings = languageSettings && languageSettings.format;
if (!formatSettings) {
return formatParams;
connection.onReferences(referenceParams => {
let document = documents.get(referenceParams.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, referenceParams.position);
if (mode && mode.findReferences) {
return mode.findReferences(document, referenceParams.position);
}
return merge(formatParams, merge(formatSettings, {}));
}
return [];
});
connection.onSignatureHelp(signatureHelpParms => {
let document = documents.get(signatureHelpParms.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, signatureHelpParms.position);
if (mode && mode.doSignatureHelp) {
return mode.doSignatureHelp(document, signatureHelpParms.position);
}
return null;
});
connection.onDocumentRangeFormatting(formatParams => {
let document = documents.get(formatParams.textDocument.uri);
return languageService.format(document, formatParams.range, getFormattingOptions(formatParams.options));
let ranges = languageModes.getModesInRange(document, formatParams.range);
let result: TextEdit[] = [];
ranges.forEach(r => {
let mode = r.mode;
if (mode && mode.format && !r.attributeValue) {
let edits = mode.format(document, r, formatParams.options);
pushAll(result, edits);
}
});
return result;
});
connection.onDocumentLinks(documentLinkParam => {
let document = documents.get(documentLinkParam.textDocument.uri);
let documentContext: DocumentContext = {
resolveReference: ref => {
if (ref[0] === '/') {
if (workspacePath && ref[0] === '/') {
return uri.file(path.join(workspacePath, ref)).toString();
}
return url.resolve(document.uri, ref);
}
};
return languageService.findDocumentLinks(document, documentContext);
let links: DocumentLink[] = [];
languageModes.getAllModesInDocument(document).forEach(m => {
if (m.findDocumentLinks) {
pushAll(links, m.findDocumentLinks(document, documentContext));
}
});
return links;
});
connection.onDocumentSymbol(documentSymbolParms => {
let document = documents.get(documentSymbolParms.textDocument.uri);
let symbols: SymbolInformation[] = [];
languageModes.getAllModesInDocument(document).forEach(m => {
if (m.findDocumentSymbols) {
pushAll(symbols, m.findDocumentSymbols(document));
}
});
return symbols;
});
connection.onRequest(ColorSymbolRequest.type, uri => {
let ranges: Range[] = [];
let document = documents.get(uri);
if (document) {
languageModes.getAllModesInDocument(document).forEach(m => {
if (m.findColorSymbols) {
pushAll(ranges, m.findColorSymbols(document));
}
});
}
return ranges;
});
// Listen on the connection
connection.listen();

View file

@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------------------------
* 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 { LanguageModelCache, getLanguageModelCache } from '../languageModelCache';
import { TextDocument, Position } from 'vscode-languageserver-types';
import { getCSSLanguageService, Stylesheet } from 'vscode-css-languageservice';
import { LanguageMode } from './languageModes';
import { HTMLDocumentRegions, CSS_STYLE_RULE } from './embeddedSupport';
export function getCSSMode(documentRegions: LanguageModelCache<HTMLDocumentRegions>): LanguageMode {
let cssLanguageService = getCSSLanguageService();
let embeddedCSSDocuments = getLanguageModelCache<TextDocument>(10, 60, document => documentRegions.get(document).getEmbeddedDocument('css'));
let cssStylesheets = getLanguageModelCache<Stylesheet>(10, 60, document => cssLanguageService.parseStylesheet(document));
return {
getId() {
return 'css';
},
configure(options: any) {
cssLanguageService.configure(options && options.css);
},
doValidation(document: TextDocument) {
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.doValidation(embedded, cssStylesheets.get(embedded));
},
doComplete(document: TextDocument, position: Position) {
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.doComplete(embedded, position, cssStylesheets.get(embedded));
},
doHover(document: TextDocument, position: Position) {
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.doHover(embedded, position, cssStylesheets.get(embedded));
},
findDocumentHighlight(document: TextDocument, position: Position) {
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.findDocumentHighlights(embedded, position, cssStylesheets.get(embedded));
},
findDocumentSymbols(document: TextDocument) {
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.findDocumentSymbols(embedded, cssStylesheets.get(embedded)).filter(s => s.name !== CSS_STYLE_RULE);
},
findDefinition(document: TextDocument, position: Position) {
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.findDefinition(embedded, position, cssStylesheets.get(embedded));
},
findReferences(document: TextDocument, position: Position) {
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.findReferences(embedded, position, cssStylesheets.get(embedded));
},
findColorSymbols(document: TextDocument) {
let embedded = embeddedCSSDocuments.get(document);
return cssLanguageService.findColorSymbols(embedded, cssStylesheets.get(embedded));
},
onDocumentRemoved(document: TextDocument) {
embeddedCSSDocuments.onDocumentRemoved(document);
cssStylesheets.onDocumentRemoved(document);
},
dispose() {
embeddedCSSDocuments.dispose();
cssStylesheets.dispose();
}
};
};

View file

@ -0,0 +1,233 @@
/*---------------------------------------------------------------------------------------------
* 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 { TextDocument, Position, LanguageService, TokenType, Range } from 'vscode-html-languageservice';
export interface LanguageRange extends Range {
languageId: string;
attributeValue?: boolean;
}
export interface HTMLDocumentRegions {
getEmbeddedDocument(languageId: string): TextDocument;
getLanguageRanges(range: Range): LanguageRange[];
getLanguageAtPosition(position: Position): string;
getLanguagesInDocument(): string[];
getImportedScripts(): string[];
}
export var CSS_STYLE_RULE = '__';
interface EmbeddedRegion { languageId: string; start: number; end: number; attributeValue?: boolean; };
export function getDocumentRegions(languageService: LanguageService, document: TextDocument): HTMLDocumentRegions {
let regions: EmbeddedRegion[] = [];
let scanner = languageService.createScanner(document.getText());
let lastTagName: string;
let lastAttributeName: string;
let languageIdFromType: string;
let importedScripts = [];
let token = scanner.scan();
while (token !== TokenType.EOS) {
switch (token) {
case TokenType.StartTag:
lastTagName = scanner.getTokenText();
lastAttributeName = null;
languageIdFromType = 'javascript';
break;
case TokenType.Styles:
regions.push({ languageId: 'css', start: scanner.getTokenOffset(), end: scanner.getTokenEnd() });
break;
case TokenType.Script:
regions.push({ languageId: languageIdFromType, start: scanner.getTokenOffset(), end: scanner.getTokenEnd() });
break;
case TokenType.AttributeName:
lastAttributeName = scanner.getTokenText();
break;
case TokenType.AttributeValue:
if (lastAttributeName === 'src' && lastTagName.toLowerCase() === 'script') {
let value = scanner.getTokenText();
if (value[0] === '\'' || value[0] === '"') {
value = value.substr(1, value.length - 1);
}
importedScripts.push(value);
} else if (lastAttributeName === 'type' && lastTagName.toLowerCase() === 'script') {
if (/["'](text|application)\/(java|ecma)script["']/.test(scanner.getTokenText())) {
languageIdFromType = 'javascript';
} else {
languageIdFromType = void 0;
}
} else {
let attributelLanguageId = getAttributeLanguage(lastAttributeName);
if (attributelLanguageId) {
let start = scanner.getTokenOffset();
let end = scanner.getTokenEnd();
let firstChar = document.getText()[start];
if (firstChar === '\'' || firstChar === '"') {
start++;
end--;
}
regions.push({ languageId: attributelLanguageId, start, end, attributeValue: true });
}
}
lastAttributeName = null;
break;
}
token = scanner.scan();
}
return {
getLanguageRanges: (range: Range) => getLanguageRanges(document, regions, range),
getEmbeddedDocument: (languageId: string) => getEmbeddedDocument(document, regions, languageId),
getLanguageAtPosition: (position: Position) => getLanguageAtPosition(document, regions, position),
getLanguagesInDocument: () => getLanguagesInDocument(document, regions),
getImportedScripts: () => importedScripts
};
}
function getLanguageRanges(document: TextDocument, regions: EmbeddedRegion[], range: Range): LanguageRange[] {
let result: LanguageRange[] = [];
let currentPos = range ? range.start : Position.create(0, 0);
let currentOffset = range ? document.offsetAt(range.start) : 0;
let endOffset = range ? document.offsetAt(range.end) : document.getText().length;
for (let region of regions) {
if (region.end > currentOffset && region.start < endOffset) {
let start = Math.max(region.start, currentOffset);
let startPos = document.positionAt(start);
if (currentOffset < region.start) {
result.push({
start: currentPos,
end: startPos,
languageId: 'html'
});
}
let end = Math.min(region.end, endOffset);
let endPos = document.positionAt(end);
if (end > region.start) {
result.push({
start: startPos,
end: endPos,
languageId: region.languageId,
attributeValue: region.attributeValue
});
}
currentOffset = end;
currentPos = endPos;
}
}
if (currentOffset < endOffset) {
let endPos = range ? range.end : document.positionAt(endOffset);
result.push({
start: currentPos,
end: endPos,
languageId: 'html'
});
}
return result;
}
function getLanguagesInDocument(document: TextDocument, regions: EmbeddedRegion[]): string[] {
let result = [];
for (let region of regions) {
if (result.indexOf(region.languageId) === -1) {
result.push(region.languageId);
if (result.length === 3) {
return result;
}
}
}
result.push('html');
return result;
}
function getLanguageAtPosition(document: TextDocument, regions: EmbeddedRegion[], position: Position): string {
let offset = document.offsetAt(position);
for (let region of regions) {
if (region.start <= offset) {
if (offset <= region.end) {
return region.languageId;
}
} else {
break;
}
}
return 'html';
}
function getEmbeddedDocument(document: TextDocument, contents: EmbeddedRegion[], languageId: string): TextDocument {
let currentPos = 0;
let oldContent = document.getText();
let result = '';
let lastSuffix = '';
for (let c of contents) {
if (c.languageId === languageId) {
result = substituteWithWhitespace(result, currentPos, c.start, oldContent, lastSuffix, getPrefix(c));
result += oldContent.substring(c.start, c.end);
currentPos = c.end;
lastSuffix = getSuffix(c);
}
}
result = substituteWithWhitespace(result, currentPos, oldContent.length, oldContent, lastSuffix, '');
return TextDocument.create(document.uri, languageId, document.version, result);
}
function getPrefix(c: EmbeddedRegion) {
if (c.attributeValue) {
switch (c.languageId) {
case 'css': return CSS_STYLE_RULE + '{';
}
}
return '';
}
function getSuffix(c: EmbeddedRegion) {
if (c.attributeValue) {
switch (c.languageId) {
case 'css': return '}';
case 'javascript': return ';';
}
}
return '';
}
function substituteWithWhitespace(result: string, start: number, end: number, oldContent: string, before: string, after: string) {
let accumulatedWS = 0;
result += before;
for (let i = start + before.length; i < end; i++) {
let ch = oldContent[i];
if (ch === '\n' || ch === '\r') {
// only write new lines, skip the whitespace
accumulatedWS = 0;
result += ch;
} else {
accumulatedWS++;
}
}
result = append(result, ' ', accumulatedWS - after.length);
result += after;
return result;
}
function append(result: string, str: string, n: number): string {
while (n > 0) {
if (n & 1) {
result += str;
}
n >>= 1;
str += str;
}
return result;
}
function getAttributeLanguage(attributeName: string): string {
let match = attributeName.match(/^(style)$|^(on\w+)$/i);
if (!match) {
return null;
}
return match[1] ? 'css' : 'javascript';
}

View file

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------------------------
* 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 { 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';
export function getHTMLMode(htmlLanguageService: HTMLLanguageService): LanguageMode {
let settings: any = {};
let htmlDocuments = getLanguageModelCache<HTMLDocument>(10, 60, document => htmlLanguageService.parseHTMLDocument(document));
return {
getId() {
return 'html';
},
configure(options: any) {
settings = options && options.html;
},
doComplete(document: TextDocument, position: Position) {
let options = settings && settings.html && settings.html.suggest;
return htmlLanguageService.doComplete(document, position, htmlDocuments.get(document), options);
},
doHover(document: TextDocument, position: Position) {
return htmlLanguageService.doHover(document, position, htmlDocuments.get(document));
},
findDocumentHighlight(document: TextDocument, position: Position) {
return htmlLanguageService.findDocumentHighlights(document, position, htmlDocuments.get(document));
},
findDocumentLinks(document: TextDocument, documentContext: DocumentContext) {
return htmlLanguageService.findDocumentLinks(document, documentContext);
},
format(document: TextDocument, range: Range, formatParams: FormattingOptions) {
let formatSettings = settings && settings.format;
if (!formatSettings) {
formatSettings = formatParams;
} else {
formatSettings = merge(formatParams, merge(formatSettings, {}));
}
return htmlLanguageService.format(document, range, formatSettings);
},
onDocumentRemoved(document: TextDocument) {
htmlDocuments.onDocumentRemoved(document);
},
dispose() {
htmlDocuments.dispose();
}
};
};
function merge(src: any, dst: any): any {
for (var key in src) {
if (src.hasOwnProperty(key)) {
dst[key] = src[key];
}
}
return dst;
}

View file

@ -0,0 +1,366 @@
/*---------------------------------------------------------------------------------------------
* 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 { 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 { getWordAtText } from '../utils/words';
import { HTMLDocumentRegions } from './embeddedSupport';
import * as ts from 'typescript';
import { join } from 'path';
const FILE_NAME = 'vscode://javascript/1'; // the same 'file' is used for all contents
const JQUERY_D_TS = join(__dirname, '../../lib/jquery.d.ts');
const JS_WORD_REGEX = /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g;
export function getJavascriptMode(documentRegions: LanguageModelCache<HTMLDocumentRegions>): LanguageMode {
let jsDocuments = getLanguageModelCache<TextDocument>(10, 60, document => documentRegions.get(document).getEmbeddedDocument('javascript'));
let compilerOptions = { allowNonTsExtensions: true, allowJs: true, target: ts.ScriptTarget.Latest };
let currentTextDocument: TextDocument;
let host = {
getCompilationSettings: () => compilerOptions,
getScriptFileNames: () => [FILE_NAME, JQUERY_D_TS],
getScriptVersion: (fileName: string) => {
if (fileName === FILE_NAME) {
return String(currentTextDocument.version);
}
return '1'; // default lib an jquery.d.ts are static
},
getScriptSnapshot: (fileName: string) => {
let text = fileName === FILE_NAME ? currentTextDocument.getText() : ts.sys.readFile(fileName);
return {
getText: (start, end) => text.substring(start, end),
getLength: () => text.length,
getChangeRange: () => void 0
};
},
getCurrentDirectory: () => '',
getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options)
};
let jsLanguageService = ts.createLanguageService(host);
let settings: any = {};
return {
getId() {
return 'html';
},
configure(options: any) {
settings = options && options.javascript;
},
doValidation(document: TextDocument): Diagnostic[] {
currentTextDocument = jsDocuments.get(document);
const diagnostics = jsLanguageService.getSyntacticDiagnostics(FILE_NAME);
return diagnostics.map(diag => {
return {
range: convertRange(currentTextDocument, diag),
severity: DiagnosticSeverity.Error,
message: ts.flattenDiagnosticMessageText(diag.messageText, '\n')
};
});
},
doComplete(document: TextDocument, position: Position): CompletionList {
currentTextDocument = jsDocuments.get(document);
let offset = currentTextDocument.offsetAt(position);
let completions = jsLanguageService.getCompletionsAtPosition(FILE_NAME, offset);
if (!completions) {
return { isIncomplete: false, items: [] };
}
let replaceRange = convertRange(currentTextDocument, getWordAtText(currentTextDocument.getText(), offset, JS_WORD_REGEX));
return {
isIncomplete: false,
items: completions.entries.map(entry => {
return {
uri: document.uri,
position: position,
label: entry.name,
sortText: entry.sortText,
kind: convertKind(entry.kind),
textEdit: TextEdit.replace(replaceRange, entry.name),
data: { // data used for resolving item details (see 'doResolve')
languageId: 'javascript',
uri: document.uri,
offset: offset
}
};
})
};
},
doResolve(document: TextDocument, item: CompletionItem): CompletionItem {
currentTextDocument = jsDocuments.get(document);
let details = jsLanguageService.getCompletionEntryDetails(FILE_NAME, item.data.offset, item.label);
if (details) {
item.detail = ts.displayPartsToString(details.displayParts);
item.documentation = ts.displayPartsToString(details.documentation);
delete item.data;
}
return item;
},
doHover(document: TextDocument, position: Position): Hover {
currentTextDocument = jsDocuments.get(document);
let info = jsLanguageService.getQuickInfoAtPosition(FILE_NAME, currentTextDocument.offsetAt(position));
if (info) {
let contents = ts.displayPartsToString(info.displayParts);
return {
range: convertRange(currentTextDocument, info.textSpan),
contents: MarkedString.fromPlainText(contents)
};
}
return null;
},
doSignatureHelp(document: TextDocument, position: Position): SignatureHelp {
currentTextDocument = jsDocuments.get(document);
let signHelp = jsLanguageService.getSignatureHelpItems(FILE_NAME, currentTextDocument.offsetAt(position));
if (signHelp) {
let ret: SignatureHelp = {
activeSignature: signHelp.selectedItemIndex,
activeParameter: signHelp.argumentIndex,
signatures: []
};
signHelp.items.forEach(item => {
let signature: SignatureInformation = {
label: '',
documentation: null,
parameters: []
};
signature.label += ts.displayPartsToString(item.prefixDisplayParts);
item.parameters.forEach((p, i, a) => {
let label = ts.displayPartsToString(p.displayParts);
let parameter: ParameterInformation = {
label: label,
documentation: ts.displayPartsToString(p.documentation)
};
signature.label += label;
signature.parameters.push(parameter);
if (i < a.length - 1) {
signature.label += ts.displayPartsToString(item.separatorDisplayParts);
}
});
signature.label += ts.displayPartsToString(item.suffixDisplayParts);
ret.signatures.push(signature);
});
return ret;
};
return null;
},
findDocumentHighlight(document: TextDocument, position: Position): DocumentHighlight[] {
currentTextDocument = jsDocuments.get(document);
let occurrences = jsLanguageService.getOccurrencesAtPosition(FILE_NAME, currentTextDocument.offsetAt(position));
if (occurrences) {
return occurrences.map(entry => {
return {
range: convertRange(currentTextDocument, entry.textSpan),
kind: entry.isWriteAccess ? DocumentHighlightKind.Write : DocumentHighlightKind.Text
};
});
};
return null;
},
findDocumentSymbols(document: TextDocument): SymbolInformation[] {
currentTextDocument = jsDocuments.get(document);
let items = jsLanguageService.getNavigationBarItems(FILE_NAME);
if (items) {
let result: SymbolInformation[] = [];
let existing = {};
let collectSymbols = (item: ts.NavigationBarItem, containerLabel?: string) => {
let sig = item.text + item.kind + item.spans[0].start;
if (item.kind !== 'script' && !existing[sig]) {
let symbol: SymbolInformation = {
name: item.text,
kind: convertSymbolKind(item.kind),
location: {
uri: document.uri,
range: convertRange(currentTextDocument, item.spans[0])
},
containerName: containerLabel
};
existing[sig] = true;
result.push(symbol);
containerLabel = item.text;
}
if (item.childItems && item.childItems.length > 0) {
for (let child of item.childItems) {
collectSymbols(child, containerLabel);
}
}
};
items.forEach(item => collectSymbols(item));
return result;
}
return null;
},
findDefinition(document: TextDocument, position: Position): Definition {
currentTextDocument = jsDocuments.get(document);
let definition = jsLanguageService.getDefinitionAtPosition(FILE_NAME, currentTextDocument.offsetAt(position));
if (definition) {
return definition.filter(d => d.fileName === FILE_NAME).map(d => {
return {
uri: document.uri,
range: convertRange(currentTextDocument, d.textSpan)
};
});
}
return null;
},
findReferences(document: TextDocument, position: Position): Location[] {
currentTextDocument = jsDocuments.get(document);
let references = jsLanguageService.getReferencesAtPosition(FILE_NAME, currentTextDocument.offsetAt(position));
if (references) {
return references.filter(d => d.fileName === FILE_NAME).map(d => {
return {
uri: document.uri,
range: convertRange(currentTextDocument, d.textSpan)
};
});
}
return null;
},
format(document: TextDocument, range: Range, formatParams: FormattingOptions): TextEdit[] {
currentTextDocument = jsDocuments.get(document);
let initialIndentLevel = computeInitialIndent(document, range, formatParams) + 1;
let formatSettings = convertOptions(formatParams, settings && settings.format, initialIndentLevel);
let start = currentTextDocument.offsetAt(range.start);
let end = currentTextDocument.offsetAt(range.end);
let edits = jsLanguageService.getFormattingEditsForRange(FILE_NAME, start, end, formatSettings);
if (edits) {
let result = [];
for (let edit of edits) {
if (edit.span.start >= start && edit.span.start + edit.span.length <= end) {
result.push({
range: convertRange(currentTextDocument, edit.span),
newText: edit.newText
});
}
}
return result;
}
return null;
},
onDocumentRemoved(document: TextDocument) {
jsDocuments.onDocumentRemoved(document);
},
dispose() {
jsLanguageService.dispose();
jsDocuments.dispose();
}
};
};
function convertRange(document: TextDocument, span: { start: number, length: number }): Range {
let startPosition = document.positionAt(span.start);
let endPosition = document.positionAt(span.start + span.length);
return Range.create(startPosition, endPosition);
}
function convertKind(kind: string): CompletionItemKind {
switch (kind) {
case 'primitive type':
case 'keyword':
return CompletionItemKind.Keyword;
case 'var':
case 'local var':
return CompletionItemKind.Variable;
case 'property':
case 'getter':
case 'setter':
return CompletionItemKind.Field;
case 'function':
case 'method':
case 'construct':
case 'call':
case 'index':
return CompletionItemKind.Function;
case 'enum':
return CompletionItemKind.Enum;
case 'module':
return CompletionItemKind.Module;
case 'class':
return CompletionItemKind.Class;
case 'interface':
return CompletionItemKind.Interface;
case 'warning':
return CompletionItemKind.File;
}
return CompletionItemKind.Property;
}
function convertSymbolKind(kind: string): SymbolKind {
switch (kind) {
case 'var':
case 'local var':
case 'const':
return SymbolKind.Variable;
case 'function':
case 'local function':
return SymbolKind.Function;
case 'enum':
return SymbolKind.Enum;
case 'module':
return SymbolKind.Module;
case 'class':
return SymbolKind.Class;
case 'interface':
return SymbolKind.Interface;
case 'method':
return SymbolKind.Method;
case 'property':
case 'getter':
case 'setter':
return SymbolKind.Property;
}
return SymbolKind.Variable;
}
function convertOptions(options: FormattingOptions, formatSettings: any, initialIndentLevel: number): ts.FormatCodeOptions {
return {
ConvertTabsToSpaces: options.insertSpaces,
TabSize: options.tabSize,
IndentSize: options.tabSize,
IndentStyle: ts.IndentStyle.Smart,
NewLineCharacter: '\n',
BaseIndentSize: options.tabSize * initialIndentLevel,
InsertSpaceAfterCommaDelimiter: Boolean(!formatSettings || formatSettings.insertSpaceAfterCommaDelimiter),
InsertSpaceAfterSemicolonInForStatements: Boolean(!formatSettings || formatSettings.insertSpaceAfterSemicolonInForStatements),
InsertSpaceBeforeAndAfterBinaryOperators: Boolean(!formatSettings || formatSettings.insertSpaceBeforeAndAfterBinaryOperators),
InsertSpaceAfterKeywordsInControlFlowStatements: Boolean(!formatSettings || formatSettings.insertSpaceAfterKeywordsInControlFlowStatements),
InsertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean(!formatSettings || formatSettings.insertSpaceAfterFunctionKeywordForAnonymousFunctions),
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean(formatSettings && formatSettings.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis),
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean(formatSettings && formatSettings.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets),
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean(formatSettings && formatSettings.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces),
PlaceOpenBraceOnNewLineForControlBlocks: Boolean(formatSettings && formatSettings.placeOpenBraceOnNewLineForFunctions),
PlaceOpenBraceOnNewLineForFunctions: Boolean(formatSettings && formatSettings.placeOpenBraceOnNewLineForControlBlocks)
};
}
function computeInitialIndent(document: TextDocument, range: Range, options: FormattingOptions) {
let lineStart = document.offsetAt(Position.create(range.start.line, 0));
let content = document.getText();
let i = lineStart;
let nChars = 0;
let tabSize = options.tabSize || 4;
while (i < content.length) {
let ch = content.charAt(i);
if (ch === ' ') {
nChars++;
} else if (ch === '\t') {
nChars += tabSize;
} else {
break;
}
i++;
}
return Math.floor(nChars / tabSize);
}

View file

@ -0,0 +1,118 @@
/*---------------------------------------------------------------------------------------------
* 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 { getLanguageService as getHTMLLanguageService, DocumentContext } from 'vscode-html-languageservice';
import {
CompletionItem, Location, SignatureHelp, Definition, TextEdit, TextDocument, Diagnostic, DocumentLink, Range,
Hover, DocumentHighlight, CompletionList, Position, FormattingOptions, SymbolInformation
} from 'vscode-languageserver-types';
import { getLanguageModelCache, LanguageModelCache } from '../languageModelCache';
import { getDocumentRegions, HTMLDocumentRegions } from './embeddedSupport';
import { getCSSMode } from './cssMode';
import { getJavascriptMode } from './javascriptMode';
import { getHTMLMode } from './htmlMode';
export interface LanguageMode {
getId();
configure?: (options: any) => void;
doValidation?: (document: TextDocument) => Diagnostic[];
doComplete?: (document: TextDocument, position: Position) => CompletionList;
doResolve?: (document: TextDocument, item: CompletionItem) => CompletionItem;
doHover?: (document: TextDocument, position: Position) => Hover;
doSignatureHelp?: (document: TextDocument, position: Position) => SignatureHelp;
findDocumentHighlight?: (document: TextDocument, position: Position) => DocumentHighlight[];
findDocumentSymbols?: (document: TextDocument) => SymbolInformation[];
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[];
findColorSymbols?: (document: TextDocument) => Range[];
onDocumentRemoved(document: TextDocument): void;
dispose(): void;
}
export interface LanguageModes {
getModeAtPosition(document: TextDocument, position: Position): LanguageMode;
getModesInRange(document: TextDocument, range: Range): LanguageModeRange[];
getAllModes(): LanguageMode[];
getAllModesInDocument(document: TextDocument): LanguageMode[];
getMode(languageId: string): LanguageMode;
onDocumentRemoved(document: TextDocument): void;
dispose(): void;
}
export interface LanguageModeRange extends Range {
mode: LanguageMode;
attributeValue?: boolean;
}
export function getLanguageModes(supportedLanguages: { [languageId: string]: boolean; }): LanguageModes {
var htmlLanguageService = getHTMLLanguageService();
let documentRegions = getLanguageModelCache<HTMLDocumentRegions>(10, 60, document => getDocumentRegions(htmlLanguageService, document));
let modelCaches: LanguageModelCache<any>[] = [];
modelCaches.push(documentRegions);
let modes = {};
modes['html'] = getHTMLMode(htmlLanguageService);
if (supportedLanguages['css']) {
modes['css'] = getCSSMode(documentRegions);
}
if (supportedLanguages['javascript']) {
modes['javascript'] = getJavascriptMode(documentRegions);
}
return {
getModeAtPosition(document: TextDocument, position: Position): LanguageMode {
let languageId = documentRegions.get(document).getLanguageAtPosition(position);;
if (languageId) {
return modes[languageId];
}
return null;
},
getModesInRange(document: TextDocument, range: Range): LanguageModeRange[] {
return documentRegions.get(document).getLanguageRanges(range).map(r => {
return {
start: r.start,
end: r.end,
mode: modes[r.languageId],
attributeValue: r.attributeValue
};
});
},
getAllModesInDocument(document: TextDocument): LanguageMode[] {
return documentRegions.get(document).getLanguagesInDocument().map(languageId => modes[languageId]);
},
getAllModes(): LanguageMode[] {
let result = [];
for (let languageId in modes) {
let mode = modes[languageId];
if (mode) {
result.push(mode);
}
}
return result;
},
getMode(languageId: string): LanguageMode {
return modes[languageId];
},
onDocumentRemoved(document: TextDocument) {
modelCaches.forEach(mc => mc.onDocumentRemoved(document));
for (let mode in modes) {
modes[mode].onDocumentRemoved(document);
}
},
dispose(): void {
modelCaches.forEach(mc => mc.dispose());
modelCaches = [];
for (let mode in modes) {
modes[mode].dispose();
}
modes = {};
}
};
}

View file

@ -5,47 +5,60 @@
'use strict';
import * as assert from 'assert';
import * as embeddedSupport from '../embeddedSupport';
import {TextDocument} from 'vscode-languageserver-types';
import * as embeddedSupport from '../modes/embeddedSupport';
import { TextDocument } from 'vscode-languageserver-types';
import { getLanguageService } from 'vscode-html-languageservice';
suite('HTML Embedded Support', () => {
var htmlLanguageService = getLanguageService();
function assertEmbeddedLanguageId(value: string, expectedLanguageId: string): void {
function assertLanguageId(value: string, expectedLanguageId: string): void {
let offset = value.indexOf('|');
value = value.substr(0, offset) + value.substr(offset + 1);
let document = TextDocument.create('test://test/test.html', 'html', 0, value);
let position = document.positionAt(offset);
let ls = getLanguageService();
let htmlDoc = ls.parseHTMLDocument(document);
let languageId = embeddedSupport.getEmbeddedLanguageAtPosition(ls, document, htmlDoc, position);
let docRegions = embeddedSupport.getDocumentRegions(htmlLanguageService, document);
let languageId = docRegions.getLanguageAtPosition(position);
assert.equal(languageId, expectedLanguageId);
}
function assertEmbeddedLanguageContent(value: string, languageId: string, expectedContent: string): void {
let document = TextDocument.create('test://test/test.html', 'html', 0, value);
let ls = getLanguageService();
let htmlDoc = ls.parseHTMLDocument(document);
let content = embeddedSupport.getEmbeddedContent(ls, document, htmlDoc, languageId);
assert.equal(content, expectedContent);
let docRegions = embeddedSupport.getDocumentRegions(htmlLanguageService, document);
let content = docRegions.getEmbeddedDocument(languageId);
assert.equal(content.getText(), expectedContent);
}
test('Styles', function (): any {
assertEmbeddedLanguageId('|<html><style>foo { }</style></html>', void 0);
assertEmbeddedLanguageId('<html|><style>foo { }</style></html>', void 0);
assertEmbeddedLanguageId('<html><st|yle>foo { }</style></html>', void 0);
assertEmbeddedLanguageId('<html><style>|foo { }</style></html>', 'css');
assertEmbeddedLanguageId('<html><style>foo| { }</style></html>', 'css');
assertEmbeddedLanguageId('<html><style>foo { }|</style></html>', 'css');
assertEmbeddedLanguageId('<html><style>foo { }</sty|le></html>', void 0);
assertLanguageId('|<html><style>foo { }</style></html>', 'html');
assertLanguageId('<html|><style>foo { }</style></html>', 'html');
assertLanguageId('<html><st|yle>foo { }</style></html>', 'html');
assertLanguageId('<html><style>|foo { }</style></html>', 'css');
assertLanguageId('<html><style>foo| { }</style></html>', 'css');
assertLanguageId('<html><style>foo { }|</style></html>', 'css');
assertLanguageId('<html><style>foo { }</sty|le></html>', 'html');
});
test('Style in attribute', function (): any {
assertLanguageId('<div id="xy" |style="color: red"/>', 'html');
assertLanguageId('<div id="xy" styl|e="color: red"/>', 'html');
assertLanguageId('<div id="xy" style=|"color: red"/>', 'html');
assertLanguageId('<div id="xy" style="|color: red"/>', 'css');
assertLanguageId('<div id="xy" style="color|: red"/>', 'css');
assertLanguageId('<div id="xy" style="color: red|"/>', 'css');
assertLanguageId('<div id="xy" style="color: red"|/>', 'html');
assertLanguageId('<div id="xy" style=\'color: r|ed\'/>', 'css');
assertLanguageId('<div id="xy" style|=color:red/>', 'html');
assertLanguageId('<div id="xy" style=|color:red/>', 'css');
assertLanguageId('<div id="xy" style=color:r|ed/>', 'css');
assertLanguageId('<div id="xy" style=color:red|/>', 'css');
assertLanguageId('<div id="xy" style=color:red/|>', 'html');
});
test('Style content', function (): any {
@ -54,28 +67,55 @@ suite('HTML Embedded Support', () => {
assertEmbeddedLanguageContent('<html><style>foo { }</style>Hello<style>foo { }</style></html>', 'css', ' foo { } foo { } ');
assertEmbeddedLanguageContent('<html>\n <style>\n foo { } \n </style>\n</html>\n', 'css', '\n \n foo { } \n \n\n');
assertEmbeddedLanguageContent('<div style="color: red"></div>', 'css', ' __{color: red} ');
assertEmbeddedLanguageContent('<div style=color:red></div>', 'css', ' __{color:red} ');
});
test('Scripts', function (): any {
assertEmbeddedLanguageId('|<html><script>var i = 0;</script></html>', void 0);
assertEmbeddedLanguageId('<html|><script>var i = 0;</script></html>', void 0);
assertEmbeddedLanguageId('<html><scr|ipt>var i = 0;</script></html>', void 0);
assertEmbeddedLanguageId('<html><script>|var i = 0;</script></html>', 'javascript');
assertEmbeddedLanguageId('<html><script>var| i = 0;</script></html>', 'javascript');
assertEmbeddedLanguageId('<html><script>var i = 0;|</script></html>', 'javascript');
assertEmbeddedLanguageId('<html><script>var i = 0;</scr|ipt></html>', void 0);
assertLanguageId('|<html><script>var i = 0;</script></html>', 'html');
assertLanguageId('<html|><script>var i = 0;</script></html>', 'html');
assertLanguageId('<html><scr|ipt>var i = 0;</script></html>', 'html');
assertLanguageId('<html><script>|var i = 0;</script></html>', 'javascript');
assertLanguageId('<html><script>var| i = 0;</script></html>', 'javascript');
assertLanguageId('<html><script>var i = 0;|</script></html>', 'javascript');
assertLanguageId('<html><script>var i = 0;</scr|ipt></html>', 'html');
assertEmbeddedLanguageId('<script type="text/javascript">var| i = 0;</script>', 'javascript');
assertEmbeddedLanguageId('<script type="text/ecmascript">var| i = 0;</script>', 'javascript');
assertEmbeddedLanguageId('<script type="application/javascript">var| i = 0;</script>', 'javascript');
assertEmbeddedLanguageId('<script type="application/ecmascript">var| i = 0;</script>', 'javascript');
assertEmbeddedLanguageId('<script type="application/typescript">var| i = 0;</script>', void 0);
assertEmbeddedLanguageId('<script type=\'text/javascript\'>var| i = 0;</script>', 'javascript');
assertLanguageId('<script type="text/javascript">var| i = 0;</script>', 'javascript');
assertLanguageId('<script type="text/ecmascript">var| i = 0;</script>', 'javascript');
assertLanguageId('<script type="application/javascript">var| i = 0;</script>', 'javascript');
assertLanguageId('<script type="application/ecmascript">var| i = 0;</script>', 'javascript');
assertLanguageId('<script type="application/typescript">var| i = 0;</script>', void 0);
assertLanguageId('<script type=\'text/javascript\'>var| i = 0;</script>', 'javascript');
});
test('Scripts in attribute', function (): any {
assertLanguageId('<div |onKeyUp="foo()" onkeydown=\'bar()\'/>', 'html');
assertLanguageId('<div onKeyUp=|"foo()" onkeydown=\'bar()\'/>', 'html');
assertLanguageId('<div onKeyUp="|foo()" onkeydown=\'bar()\'/>', 'javascript');
assertLanguageId('<div onKeyUp="foo(|)" onkeydown=\'bar()\'/>', 'javascript');
assertLanguageId('<div onKeyUp="foo()|" onkeydown=\'bar()\'/>', 'javascript');
assertLanguageId('<div onKeyUp="foo()"| onkeydown=\'bar()\'/>', 'html');
assertLanguageId('<div onKeyUp="foo()" onkeydown=|\'bar()\'/>', 'html');
assertLanguageId('<div onKeyUp="foo()" onkeydown=\'|bar()\'/>', 'javascript');
assertLanguageId('<div onKeyUp="foo()" onkeydown=\'bar()|\'/>', 'javascript');
assertLanguageId('<div onKeyUp="foo()" onkeydown=\'bar()\'|/>', 'html');
assertLanguageId('<DIV ONKEYUP|=foo()</DIV>', 'html');
assertLanguageId('<DIV ONKEYUP=|foo()</DIV>', 'javascript');
assertLanguageId('<DIV ONKEYUP=f|oo()</DIV>', 'javascript');
assertLanguageId('<DIV ONKEYUP=foo(|)</DIV>', 'javascript');
assertLanguageId('<DIV ONKEYUP=foo()|</DIV>', 'javascript');
assertLanguageId('<DIV ONKEYUP=foo()<|/DIV>', 'html');
assertLanguageId('<label data-content="|Checkbox"/>', 'html');
assertLanguageId('<label on="|Checkbox"/>', 'html');
});
test('Script content', function (): any {
assertEmbeddedLanguageContent('<html><script>var i = 0;</script></html>', 'javascript', ' var i = 0; ');
assertEmbeddedLanguageContent('<script type="text/javascript">var i = 0;</script>', 'javascript', ' var i = 0; ');
assertEmbeddedLanguageContent('<div onKeyUp="foo()" onkeydown="bar()"/>', 'javascript', ' foo(); bar(); ');
});
});

View file

@ -1,27 +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 assert from 'assert';
import {getEmbeddedContentUri, getEmbeddedLanguageId, getHostDocumentUri, isEmbeddedContentUri} from './embeddedContentUri';
suite('Embedded URI', () => {
test('URI', function (): any {
let resourceUri1 = 'file:///c%3A/workspaces/samples/foo.html';
let resourceUri2 = 'file://Users/joe/samples/foo.html';
let uri = getEmbeddedContentUri(resourceUri1, 'css');
assert(isEmbeddedContentUri(uri));
assert.equal(getEmbeddedLanguageId(uri), 'css');
assert.equal(getHostDocumentUri(uri), resourceUri1);
let uri2 = getEmbeddedContentUri(resourceUri2, 'css');
assert(isEmbeddedContentUri(uri2));
assert.equal(getEmbeddedLanguageId(uri2), 'css');
assert.equal(getHostDocumentUri(uri2), resourceUri2);
});
});

View file

@ -1,27 +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 Uri from 'vscode-uri';
export const EMBEDDED_CONTENT_SCHEME = 'embedded-content';
export function isEmbeddedContentUri(virtualDocumentUri: Uri): boolean {
return virtualDocumentUri.scheme === EMBEDDED_CONTENT_SCHEME;
}
export function getEmbeddedContentUri(parentDocumentUri: string, embeddedLanguageId: string): Uri {
return Uri.from({ scheme: EMBEDDED_CONTENT_SCHEME, authority: embeddedLanguageId, path: '/' + encodeURIComponent(parentDocumentUri) + '.' + embeddedLanguageId });
};
export function getHostDocumentUri(virtualDocumentUri: Uri): string {
let languageId = virtualDocumentUri.authority;
let path = virtualDocumentUri.path.substring(1, virtualDocumentUri.path.length - languageId.length - 1); // remove leading '/' and new file extension
return decodeURIComponent(path);
};
export function getEmbeddedLanguageId(virtualDocumentUri: Uri): string {
return virtualDocumentUri.authority;
}

View file

@ -0,0 +1,108 @@
/*---------------------------------------------------------------------------------------------
* 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 assert from 'assert';
import { getLanguageModes } from '../modes/languageModes';
import { TextDocument, Range, TextEdit, FormattingOptions } from 'vscode-languageserver-types';
suite('HTML Embedded Formatting', () => {
function assertFormat(value: string, expected: string, options?: any): void {
var languageModes = getLanguageModes({ css: true, javascript: true });
if (options) {
languageModes.getAllModes().forEach(m => m.configure(options));
}
let rangeStartOffset = value.indexOf('|');
let rangeEndOffset;
if (rangeStartOffset !== -1) {
value = value.substr(0, rangeStartOffset) + value.substr(rangeStartOffset + 1);
rangeEndOffset = value.indexOf('|');
value = value.substr(0, rangeEndOffset) + value.substr(rangeEndOffset + 1);
} else {
rangeStartOffset = 0;
rangeEndOffset = value.length;
}
let document = TextDocument.create('test://test/test.html', 'html', 0, value);
let range = Range.create(document.positionAt(rangeStartOffset), document.positionAt(rangeEndOffset));
let formatOptions = FormattingOptions.create(2, true);
let ranges = languageModes.getModesInRange(document, range);
let result: TextEdit[] = [];
ranges.forEach(r => {
let mode = r.mode;
if (mode && mode.format) {
let edits = mode.format(document, r, formatOptions);
pushAll(result, edits);
}
});
let actual = applyEdits(document, result);
assert.equal(actual, expected);
}
test('HTML only', function (): any {
assertFormat('<html><body><p>Hello</p></body></html>', '<html>\n\n<body>\n <p>Hello</p>\n</body>\n\n</html>');
assertFormat('|<html><body><p>Hello</p></body></html>|', '<html>\n\n<body>\n <p>Hello</p>\n</body>\n\n</html>');
assertFormat('<html>|<body><p>Hello</p></body>|</html>', '<html><body>\n <p>Hello</p>\n</body></html>');
});
test('HTML & Scripts', function (): any {
assertFormat('<html><head><script></script></head></html>', '<html>\n\n<head>\n <script></script>\n</head>\n\n</html>');
assertFormat('<html><head><script>var x=1;</script></head></html>', '<html>\n\n<head>\n <script>var x = 1;</script>\n</head>\n\n</html>');
assertFormat('<html><head><script>\nvar x=1;\n</script></head></html>', '<html>\n\n<head>\n <script>\n var x = 1;\n</script>\n</head>\n\n</html>');
assertFormat('<html><head>\n <script>\nvar x=1;\n</script></head></html>', '<html>\n\n<head>\n <script>\n var x = 1;\n</script>\n</head>\n\n</html>');
assertFormat('<html><head>\n <script>\nvar x=1;\nconsole.log("Hi");\n</script></head></html>', '<html>\n\n<head>\n <script>\n var x = 1;\n console.log("Hi");\n</script>\n</head>\n\n</html>');
assertFormat('<html><head>\n |<script>\nvar x=1;\n</script>|</head></html>', '<html><head>\n <script>\n var x = 1;\n</script></head></html>');
assertFormat('<html><head>\n <script>\n|var x=1;|\n</script></head></html>', '<html><head>\n <script>\n var x = 1;\n</script></head></html>');
});
test('HTML & Multiple Scripts', function (): any {
assertFormat('<html><head>\n<script>\nif(x){\nbar(); }\n</script><script>\nfunction(x){}\n</script></head></html>', '<html>\n\n<head>\n <script>\n if (x) {\n bar();\n }\n</script>\n<script>\n function(x) { }\n</script>\n</head>\n\n</html>');
});
test('HTML & Styles', function (): any {
assertFormat('<html><head>\n<style>\n.foo{display:none;}\n</style></head></html>', '<html>\n\n<head>\n <style>\n.foo{display:none;}\n</style>\n</head>\n\n</html>');
});
test('EndWithNewline', function (): any {
let options = {
html: {
format: {
endWithNewline : true
}
}
};
assertFormat('<html><body><p>Hello</p></body></html>', '<html>\n\n<body>\n <p>Hello</p>\n</body>\n\n</html>\n', options);
assertFormat('<html>|<body><p>Hello</p></body>|</html>', '<html><body>\n <p>Hello</p>\n</body></html>', options);
assertFormat('<html><head><script>\nvar x=1;\n</script></head></html>', '<html>\n\n<head>\n <script>\n var x = 1;\n</script>\n</head>\n\n</html>\n', options);
});
});
function pushAll<T>(to: T[], from: T[]) {
if (from) {
for (var i = 0; i < from.length; i++) {
to.push(from[i]);
}
}
}
function applyEdits(document: TextDocument, edits: TextEdit[]): string {
let text = document.getText();
let sortedEdits = edits.sort((a, b) => document.offsetAt(b.range.start) - document.offsetAt(a.range.start));
let lastOffset = text.length;
sortedEdits.forEach(e => {
let startOffset = document.offsetAt(e.range.start);
let endOffset = document.offsetAt(e.range.end);
assert.ok(startOffset <= endOffset);
assert.ok(endOffset <= lastOffset);
text = text.substring(0, startOffset) + e.newText + text.substring(endOffset, text.length);
lastOffset = startOffset;
});
return text;
}

View file

@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------------------------
* 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 assert from 'assert';
import { getJavascriptMode } from '../modes/javascriptMode';
import { TextDocument, Range, TextEdit, FormattingOptions } from 'vscode-languageserver-types';
import { getLanguageModelCache } from '../languageModelCache';
import { getLanguageService } from 'vscode-html-languageservice';
import * as embeddedSupport from '../modes/embeddedSupport';
suite('HTML Javascript Support', () => {
var htmlLanguageService = getLanguageService();
function assertCompletions(value: string, expectedProposals: string[]): void {
let offset = value.indexOf('|');
value = value.substr(0, offset) + value.substr(offset + 1);
let document = TextDocument.create('test://test/test.html', 'html', 0, value);
let documentRegions = getLanguageModelCache<embeddedSupport.HTMLDocumentRegions>(10, 60, document => embeddedSupport.getDocumentRegions(htmlLanguageService, document));
var mode = getJavascriptMode(documentRegions);
let position = document.positionAt(offset);
let list = mode.doComplete(document, position);
assert.ok(list);
let actualLabels = list.items.map(c => c.label).sort();
for (let expected of expectedProposals) {
assert.ok(actualLabels.indexOf(expected) !== -1, 'Not found:' + expected + ' is ' + actualLabels.join(', '));
}
}
test('Completions', function (): any {
assertCompletions('<html><script>window.|</script></html>', ['location']);
assertCompletions('<html><script>$.|</script></html>', ['getJSON']);
});
});

View file

@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------------------------
* 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 assert from 'assert';
import * as words from '../utils/words';
suite('Words', () => {
let wordRegex = /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g;
function assertWord(value: string, expected: string): void {
let offset = value.indexOf('|');
value = value.substr(0, offset) + value.substr(offset + 1);
let actualRange = words.getWordAtText(value, offset, wordRegex);
assert(actualRange.start <= offset);
assert(actualRange.start + actualRange.length >= offset);
assert.equal(value.substr(actualRange.start, actualRange.length), expected);
}
test('Basic', function (): any {
assertWord('|var x1 = new F<A>(a, b);', 'var');
assertWord('v|ar x1 = new F<A>(a, b);', 'var');
assertWord('var| x1 = new F<A>(a, b);', 'var');
assertWord('var |x1 = new F<A>(a, b);', 'x1');
assertWord('var x1| = new F<A>(a, b);', 'x1');
assertWord('var x1 = new |F<A>(a, b);', 'F');
assertWord('var x1 = new F<|A>(a, b);', 'A');
assertWord('var x1 = new F<A>(|a, b);', 'a');
assertWord('var x1 = new F<A>(a, b|);', 'b');
assertWord('var x1 = new F<A>(a, b)|;', '');
assertWord('var x1 = new F<A>(a, b)|;|', '');
assertWord('var x1 = | new F<A>(a, b)|;|', '');
});
test('Multiline', function (): any {
assertWord('console.log("hello");\n|var x1 = new F<A>(a, b);', 'var');
assertWord('console.log("hello");\n|\nvar x1 = new F<A>(a, b);', '');
assertWord('console.log("hello");\n\r |var x1 = new F<A>(a, b);', 'var');
});
});

View file

@ -0,0 +1,35 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
export function getWordAtText(text: string, offset: number, wordDefinition: RegExp): { start: number, length: number } {
let lineStart = offset;
while (lineStart > 0 && !isNewlineCharacter(text.charCodeAt(lineStart - 1))) {
lineStart--;
}
let offsetInLine = offset - lineStart;
let lineText = text.substr(lineStart);
// make a copy of the regex as to not keep the state
let flags = wordDefinition.ignoreCase ? 'gi' : 'g';
wordDefinition = new RegExp(wordDefinition.source, flags);
let match = wordDefinition.exec(lineText);
while (match && match.index + match[0].length < offsetInLine) {
match = wordDefinition.exec(lineText);
}
if (match && match.index <= offsetInLine) {
return { start: match.index + lineStart, length: match[0].length };
}
return { start: offset, length: 0 };
}
const CR = '\r'.charCodeAt(0);
const NL = '\n'.charCodeAt(0);
function isNewlineCharacter(charCode: number) {
return charCode === CR || charCode === NL;
}

View file

@ -3,8 +3,6 @@
"noLib": true,
"target": "es5",
"module": "commonjs",
"sourceMap": true,
"sourceRoot": "../src",
"outDir": "./out"
},
"exclude": [

View file

@ -12,9 +12,9 @@
},
{
"id": "properties",
"extensions": [ ".properties", ".gitconfig" ],
"extensions": [ ".properties", ".gitconfig", ".cfg", ".conf" ],
"filenames": [ "config", ".gitattributes", ".gitconfig", "gitconfig", ".editorconfig" ],
"aliases": [ "properties", "properties" ],
"aliases": [ "Properties", "properties" ],
"configuration": "./properties.language-configuration.json"
}],
"grammars": [{

View file

@ -19,4 +19,24 @@
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
]
},{
"name": "textmate/javadoc.tmbundle",
"version": "0.0.0",
"license": "TextMate Bundle License",
"repositoryURL": "https://github.com/textmate/javadoc.tmbundle",
"licenseDetail": [
"Copyright (c) textmate-javadoc.tmbundle project authors",
"",
"If not otherwise specified (see below), files in this repository fall under the following license:",
"",
"Permission to copy, use, modify, sell and distribute this",
"software is granted. This software is provided \"as is\" without",
"express or implied warranty, and with no claim as to its",
"suitability for any purpose.",
"",
"An exception is made for files in readable text which contain their own license information,",
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added",
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
]
}]

View file

@ -4,7 +4,7 @@
"publisher": "vscode",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js textmate/java.tmbundle Syntaxes/Java.plist ./syntaxes/java.json"
"update-grammar": "node ../../build/npm/update-grammar.js textmate/java.tmbundle Syntaxes/Java.plist ./syntaxes/java.tmLanguage.json && node ../../build/npm/update-grammar.js textmate/javadoc.tmbundle Syntaxes/JavaDoc.tmLanguage ./syntaxes/javadoc.tmLanguage.json"
},
"contributes": {
"languages": [{
@ -16,7 +16,10 @@
"grammars": [{
"language": "java",
"scopeName": "source.java",
"path": "./syntaxes/java.json"
"path": "./syntaxes/java.tmLanguage.json"
},{
"scopeName": "text.html.javadoc",
"path": "./syntaxes/javadoc.tmLanguage.json"
}]
}
}

View file

@ -0,0 +1,432 @@
{
"fileTypes": [],
"name": "JavaDoc",
"patterns": [
{
"begin": "(/\\*\\*)\\s*$",
"beginCaptures": {
"1": {
"name": "punctuation.definition.comment.begin.javadoc"
}
},
"contentName": "text.html",
"end": "\\*/",
"endCaptures": {
"0": {
"name": "punctuation.definition.comment.end.javadoc"
}
},
"name": "comment.block.documentation.javadoc",
"patterns": [
{
"include": "#inline"
},
{
"begin": "((\\@)param)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.param.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.param.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)return)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.return.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.return.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)throws)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.throws.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.throws.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)exception)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.exception.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.exception.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)author)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.author.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.author.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)version)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.version.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.version.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)see)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.see.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.see.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)since)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.since.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.since.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)serial)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.serial.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.serial.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)serialField)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.serialField.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.serialField.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)serialData)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.serialData.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.serialData.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"begin": "((\\@)deprecated)",
"beginCaptures": {
"1": {
"name": "keyword.other.documentation.deprecated.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"end": "(?=^\\s*\\*?\\s*@|\\*/)",
"name": "meta.documentation.tag.deprecated.javadoc",
"patterns": [
{
"include": "#inline"
}
]
},
{
"captures": {
"1": {
"name": "keyword.other.documentation.custom.javadoc"
},
"2": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"match": "((\\@)\\S+)\\s"
}
]
}
],
"repository": {
"inline": {
"patterns": [
{
"include": "#inline-formatting"
},
{
"comment": "This prevents < characters in commented source from starting\n\t\t\t\t\t\t\t\ta tag that will not end. List of allowed tags taken from\n\t\t\t\t\t\t\t\tjava checkstyle.",
"match": "<(?!(a|abbr|acronym|address|area|b|bdo|big|blockquote|br|caption|cite|code|colgroup|dd|del|div|dfn|dl|dt|em|fieldset|font|h1toh6|hr|i|img|ins|kbd|li|ol|p|pre|q|samp|small|span|strong|sub|sup|table|tbody|td|tfoot|th|thread|tr|tt|u|ul)\\b[^>]*>)"
},
{
"include": "text.html.basic"
},
{
"match": "((https?|s?ftp|ftps|file|smb|afp|nfs|(x-)?man|gopher|txmt)://|mailto:)[-:@a-zA-Z0-9_.,~%+/?=&#;]+(?<![-.,?:#;])",
"name": "markup.underline.link"
}
]
},
"inline-formatting": {
"patterns": [
{
"begin": "(\\{)((\\@)code)",
"beginCaptures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.code.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"contentName": "markup.raw.code.javadoc",
"end": "\\}",
"endCaptures": {
"0": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"name": "meta.tag.template.code.javadoc",
"patterns": []
},
{
"begin": "(\\{)((\\@)literal)",
"beginCaptures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.literal.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
}
},
"contentName": "markup.raw.literal.javadoc",
"end": "\\}",
"endCaptures": {
"0": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"name": "meta.tag.template.literal.javadoc",
"patterns": []
},
{
"captures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.docRoot.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
},
"4": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"match": "(\\{)((\\@)docRoot)(\\})",
"name": "meta.tag.template.docRoot.javadoc"
},
{
"captures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.inheritDoc.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
},
"4": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"match": "(\\{)((\\@)inheritDoc)(\\})",
"name": "meta.tag.template.inheritDoc.javadoc"
},
{
"captures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.link.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
},
"4": {
"name": "markup.underline.link.javadoc"
},
"5": {
"name": "string.other.link.title.javadoc"
},
"6": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"match": "(\\{)((\\@)link)(?:\\s+(\\S+?))?(?:\\s+(.+?))?\\s*(\\})",
"name": "meta.tag.template.link.javadoc"
},
{
"captures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.linkplain.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
},
"4": {
"name": "markup.underline.linkplain.javadoc"
},
"5": {
"name": "string.other.link.title.javadoc"
},
"6": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"match": "(\\{)((\\@)linkplain)(?:\\s+(\\S+?))?(?:\\s+(.+?))?\\s*(\\})",
"name": "meta.tag.template.linkplain.javadoc"
},
{
"captures": {
"1": {
"name": "punctuation.definition.tag.begin.javadoc"
},
"2": {
"name": "keyword.other.documentation.directive.value.javadoc"
},
"3": {
"name": "punctuation.definition.keyword.javadoc"
},
"4": {
"name": "variable.other.javadoc"
},
"5": {
"name": "punctuation.definition.tag.end.javadoc"
}
},
"match": "(\\{)((\\@)value)\\s*(\\S+?)?\\s*(\\})",
"name": "meta.tag.template.value.javadoc"
}
]
}
},
"scopeName": "text.html.javadoc",
"uuid": "64BB98A4-59D4-474E-9091-C1E1D04BDD03",
"version": "https://github.com/textmate/javadoc.tmbundle/commit/5276d7a93f0cf53b7d425c39c6968b09ea9f2d40"
}

View file

@ -440,8 +440,8 @@
}
},
{
"c": "/*",
"t": "block.body.class.comment.definition.java.meta.punctuation",
"c": "/**",
"t": "begin.block.body.class.comment.definition.documentation.java.javadoc.meta.punctuation",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.comment rgb(96, 139, 78)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.comment rgb(0, 128, 0)",
@ -451,8 +451,8 @@
}
},
{
"c": "*",
"t": "block.body.class.comment.java.meta",
"c": "\t * ",
"t": "block.body.class.comment.documentation.html.java.javadoc.meta.text",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.comment rgb(96, 139, 78)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.comment rgb(0, 128, 0)",
@ -462,8 +462,30 @@
}
},
{
"c": "\t * @param args",
"t": "block.body.class.comment.java.meta",
"c": "@",
"t": "block.body.class.comment.definition.documentation.html.java.javadoc.keyword.meta.other.param.punctuation.tag.text",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.punctuation.definition.tag rgb(128, 128, 128)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.punctuation.definition.tag rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.punctuation.definition.tag rgb(128, 128, 128)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.punctuation.definition.tag rgb(128, 0, 0)",
"hc_black": ".hc-black.vscode-theme-defaults-themes-hc_black-json .token.punctuation.definition.tag rgb(128, 128, 128)"
}
},
{
"c": "param",
"t": "block.body.class.comment.documentation.html.java.javadoc.keyword.meta.other.param.tag.text",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.keyword rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.keyword rgb(0, 0, 255)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.keyword rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.keyword rgb(0, 0, 255)",
"hc_black": ".hc-black.vscode-theme-defaults-themes-hc_black-json .token.keyword rgb(86, 156, 214)"
}
},
{
"c": " args",
"t": "block.body.class.comment.documentation.html.java.javadoc.meta.param.tag.text",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.comment rgb(96, 139, 78)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.comment rgb(0, 128, 0)",
@ -474,7 +496,7 @@
},
{
"c": "\t ",
"t": "block.body.class.comment.java.meta",
"t": "block.body.class.comment.documentation.html.java.javadoc.meta.param.tag.text",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.comment rgb(96, 139, 78)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.comment rgb(0, 128, 0)",
@ -485,7 +507,7 @@
},
{
"c": "*/",
"t": "block.body.class.comment.definition.java.meta.punctuation",
"t": "block.body.class.comment.definition.documentation.end.java.javadoc.meta.punctuation",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.comment rgb(96, 139, 78)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.comment rgb(0, 128, 0)",

View file

@ -4,8 +4,8 @@
"body": [
"define([",
"\t'require',",
"\t'${dependency}'",
"], function(require, ${factory}) {",
"\t'${1:dependency}'",
"], function(require, ${2:factory}) {",
"\t'use strict';",
"\t$0",
"});"
@ -15,8 +15,8 @@
"For Loop": {
"prefix": "for",
"body": [
"for (var ${index} = 0; ${index} < ${array}.length; ${index}++) {",
"\tvar ${element} = ${array}[${index}];",
"for (var ${1:index} = 0; ${1:index} < ${2:array}.length; ${1:index}++) {",
"\tvar ${3:element} = ${2:array}[${1:index}];",
"\t$0",
"}"
],
@ -25,7 +25,7 @@
"For-Each Loop": {
"prefix": "foreach",
"body": [
"${array}.forEach(function(${element}) {",
"${1:array}.forEach(function(${2:element}) {",
"\t$0",
"}, this);"
],
@ -34,9 +34,9 @@
"For-In Loop": {
"prefix": "forin",
"body": [
"for (var ${key} in ${object}) {",
"\tif (${object}.hasOwnProperty(${key})) {",
"\t\tvar ${element} = ${object}[${key}];",
"for (var ${1:key} in ${2:object}) {",
"\tif (${2:object}.hasOwnProperty(${1:key})) {",
"\t\tvar ${3:element} = ${2:object}[${1:key}];",
"\t\t$0",
"\t}",
"}"
@ -46,7 +46,7 @@
"Function Statement": {
"prefix": "function",
"body": [
"function ${name}(${params}) {",
"function ${1:name}(${2:params}) {",
"\t$0",
"}"
],
@ -55,7 +55,7 @@
"If Statement": {
"prefix": "if",
"body": [
"if (${condition}) {",
"if (${1:condition}) {",
"\t$0",
"}"
],
@ -64,7 +64,7 @@
"If-Else Statement": {
"prefix": "ifelse",
"body": [
"if (${condition}) {",
"if (${1:condition}) {",
"\t$0",
"} else {",
"\t",
@ -75,15 +75,15 @@
"New Statement": {
"prefix": "new",
"body": [
"var ${name} = new ${type}(${arguments});$0"
"var ${1:name} = new ${2:type}(${3:arguments});$0"
],
"description": "New Statement"
},
"Switch Statement": {
"prefix": "switch",
"body": [
"switch (${key}) {",
"\tcase ${value}:",
"switch (${1:key}) {",
"\tcase ${2:value}:",
"\t\t$0",
"\t\tbreak;",
"",
@ -96,7 +96,7 @@
"While Statement": {
"prefix": "while",
"body": [
"while (${condition}) {",
"while (${1:condition}) {",
"\t$0",
"}"
],
@ -107,16 +107,16 @@
"body": [
"do {",
"\t$0",
"} while (${condition});"
"} while (${1:condition});"
],
"description": "Do-While Statement"
},
"Try-Catch Statement":{
"Try-Catch Statement": {
"prefix": "trycatch",
"body": [
"try {",
"\t$0",
"} catch (${error}) {",
"} catch (${1:error}) {",
"\t",
"}"
],
@ -127,7 +127,7 @@
"body": [
"setTimeout(function() {",
"\t$0",
"}, ${timeout});"
"}, ${1:timeout});"
],
"description": "Set Timeout Function"
},

View file

@ -4,8 +4,8 @@
"body": [
"define([",
"\t'require',",
"\t'${dependency}'",
"], function(require, ${factory}) {",
"\t'${1:dependency}'",
"], function(require, ${2:factory}) {",
"\t'use strict';",
"\t$0",
"});"
@ -15,8 +15,8 @@
"For Loop": {
"prefix": "for",
"body": [
"for (var ${index} = 0; ${index} < ${array}.length; ${index}++) {",
"\tvar ${element} = ${array}[${index}];",
"for (var ${1:index} = 0; ${1:index} < ${2:array}.length; ${1:index}++) {",
"\tvar ${3:element} = ${2:array}[${1:index}];",
"\t$0",
"}"
],
@ -25,7 +25,7 @@
"For-Each Loop": {
"prefix": "foreach",
"body": [
"${array}.forEach(function(${element}) {",
"${1:array}.forEach(function(${2:element}) {",
"\t$0",
"}, this);"
],
@ -34,9 +34,9 @@
"For-In Loop": {
"prefix": "forin",
"body": [
"for (var ${key} in ${object}) {",
"\tif (${object}.hasOwnProperty(${key})) {",
"\t\tvar ${element} = ${object}[${key}];",
"for (var ${1:key} in ${2:object}) {",
"\tif (${2:object}.hasOwnProperty(${1:key})) {",
"\t\tvar ${3:element} = ${2:object}[${1:key}];",
"\t\t$0",
"\t}",
"}"
@ -46,7 +46,7 @@
"Function Statement": {
"prefix": "function",
"body": [
"function ${name}(${params}) {",
"function ${1:name}(${2:params}) {",
"\t$0",
"}"
],
@ -55,7 +55,7 @@
"If Statement": {
"prefix": "if",
"body": [
"if (${condition}) {",
"if (${1:condition}) {",
"\t$0",
"}"
],
@ -64,7 +64,7 @@
"If-Else Statement": {
"prefix": "ifelse",
"body": [
"if (${condition}) {",
"if (${1:condition}) {",
"\t$0",
"} else {",
"\t",
@ -75,15 +75,15 @@
"New Statement": {
"prefix": "new",
"body": [
"var ${name} = new ${type}(${arguments});$0"
"var ${1:name} = new ${2:type}(${3:arguments});$0"
],
"description": "New Statement"
},
"Switch Statement": {
"prefix": "switch",
"body": [
"switch (${key}) {",
"\tcase ${value}:",
"switch (${1:key}) {",
"\tcase ${2:value}:",
"\t\t$0",
"\t\tbreak;",
"",
@ -96,7 +96,7 @@
"While Statement": {
"prefix": "while",
"body": [
"while (${condition}) {",
"while (${1:condition}) {",
"\t$0",
"}"
],
@ -107,16 +107,16 @@
"body": [
"do {",
"\t$0",
"} while (${condition});"
"} while (${1:condition});"
],
"description": "Do-While Statement"
},
"Try-Catch Statement":{
"Try-Catch Statement": {
"prefix": "trycatch",
"body": [
"try {",
"\t$0",
"} catch (${error}) {",
"} catch (${2:error}) {",
"\t",
"}"
],
@ -127,7 +127,7 @@
"body": [
"setTimeout(function() {",
"\t$0",
"}, ${timeout});"
"}, ${1:timeout});"
],
"description": "Set Timeout Function"
},

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { MarkedString, CompletionItemKind, CompletionItem, DocumentSelector } from 'vscode';
import { MarkedString, CompletionItemKind, CompletionItem, DocumentSelector, SnippetString } from 'vscode';
import { IJSONContribution, ISuggestionsCollector } from './jsonContributions';
import { XHRRequest } from 'request-light';
import { Location } from 'jsonc-parser';
@ -32,16 +32,16 @@ export class BowerJSONContribution implements IJSONContribution {
public collectDefaultSuggestions(resource: string, collector: ISuggestionsCollector): Thenable<any> {
let defaultValue = {
'name': '{{name}}',
'description': '{{description}}',
'authors': ['{{author}}'],
'version': '{{1.0.0}}',
'main': '{{pathToMain}}',
'name': '${1:name}',
'description': '${2:description}',
'authors': ['${3:author}'],
'version': '${4:1.0.0}',
'main': '${5:pathToMain}',
'dependencies': {}
};
let proposal = new CompletionItem(localize('json.bower.default', 'Default bower.json'));
proposal.kind = CompletionItemKind.Class;
proposal.insertText = JSON.stringify(defaultValue, null, '\t');
proposal.insertText = new SnippetString(JSON.stringify(defaultValue, null, '\t'));
collector.add(proposal);
return Promise.resolve(null);
}
@ -62,11 +62,11 @@ export class BowerJSONContribution implements IJSONContribution {
for (let i = 0; i < results.length; i++) {
let name = results[i].name;
let description = results[i].description || '';
let insertText = JSON.stringify(name);
let insertText = new SnippetString().appendText(JSON.stringify(name));
if (addValue) {
insertText += ': "{{latest}}"';
insertText.appendText(': ').appendPlaceholder('latest');
if (!isLast) {
insertText += ',';
insertText.appendText(',');
}
}
let proposal = new CompletionItem(name);
@ -91,11 +91,11 @@ export class BowerJSONContribution implements IJSONContribution {
});
} else {
this.topRanked.forEach((name) => {
let insertText = JSON.stringify(name);
let insertText = new SnippetString().appendText(JSON.stringify(name));
if (addValue) {
insertText += ': "{{latest}}"';
insertText.appendText(': ').appendPlaceholder('latest');
if (!isLast) {
insertText += ',';
insertText.appendText(',');
}
}
@ -180,4 +180,4 @@ export class BowerJSONContribution implements IJSONContribution {
}
return null;
}
}
}

View file

@ -12,7 +12,7 @@ import { XHRRequest } from 'request-light';
import {
CompletionItem, CompletionItemProvider, CompletionList, TextDocument, Position, Hover, HoverProvider,
CancellationToken, Range, TextEdit, MarkedString, DocumentSelector, languages, Disposable
CancellationToken, Range, MarkedString, DocumentSelector, languages, Disposable
} from 'vscode';
export interface ISuggestionsCollector {
@ -109,7 +109,7 @@ export class JSONCompletionItemProvider implements CompletionItemProvider {
add: (suggestion: CompletionItem) => {
if (!proposed[suggestion.label]) {
proposed[suggestion.label] = true;
suggestion.textEdit = TextEdit.replace(overwriteRange, suggestion.insertText);
suggestion.range = overwriteRange;
items.push(suggestion);
}
},
@ -160,4 +160,4 @@ export class JSONCompletionItemProvider implements CompletionItemProvider {
}
return nextToken === SyntaxKind.CloseBraceToken || nextToken === SyntaxKind.EOF;
}
}
}

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { MarkedString, CompletionItemKind, CompletionItem, DocumentSelector } from 'vscode';
import { MarkedString, CompletionItemKind, CompletionItem, DocumentSelector, SnippetString } from 'vscode';
import { IJSONContribution, ISuggestionsCollector } from './jsonContributions';
import { XHRRequest } from 'request-light';
import { Location } from 'jsonc-parser';
@ -33,16 +33,16 @@ export class PackageJSONContribution implements IJSONContribution {
public collectDefaultSuggestions(fileName: string, result: ISuggestionsCollector): Thenable<any> {
let defaultValue = {
'name': '{{name}}',
'description': '{{description}}',
'author': '{{author}}',
'version': '{{1.0.0}}',
'main': '{{pathToMain}}',
'name': '${1:name}',
'description': '${2:description}',
'authors': '${3:author}',
'version': '${4:1.0.0}',
'main': '${5:pathToMain}',
'dependencies': {}
};
let proposal = new CompletionItem(localize('json.package.default', 'Default package.json'));
proposal.kind = CompletionItemKind.Module;
proposal.insertText = JSON.stringify(defaultValue, null, '\t');
proposal.insertText = new SnippetString(JSON.stringify(defaultValue, null, '\t'));
result.add(proposal);
return Promise.resolve(null);
}
@ -65,11 +65,11 @@ export class PackageJSONContribution implements IJSONContribution {
let keys = results[i].key;
if (Array.isArray(keys) && keys.length > 0) {
let name = keys[0];
let insertText = JSON.stringify(name);
let insertText = new SnippetString().appendText(JSON.stringify(name));
if (addValue) {
insertText += ': "{{*}}"';
insertText.appendText(': ').appendPlaceholder('*');
if (!isLast) {
insertText += ',';
insertText.appendText(',');
}
}
let proposal = new CompletionItem(name);
@ -97,11 +97,11 @@ export class PackageJSONContribution implements IJSONContribution {
});
} else {
this.mostDependedOn.forEach((name) => {
let insertText = JSON.stringify(name);
let insertText = new SnippetString().appendText(JSON.stringify(name));
if (addValue) {
insertText += ': "{{*}}"';
insertText.appendText(': ').appendPlaceholder('*');
if (!isLast) {
insertText += ',';
insertText.appendText(',');
}
}
let proposal = new CompletionItem(name);
@ -221,4 +221,4 @@ export class PackageJSONContribution implements IJSONContribution {
}
return null;
}
}
}

View file

@ -1064,6 +1064,9 @@
{
"include": "#indexer-declaration"
},
{
"include": "#indexer-mapped-type-declaration"
},
{
"include": "#field-declaration"
},
@ -1269,6 +1272,38 @@
}
]
},
"indexer-mapped-type-declaration": {
"name": "meta.indexer.mappedtype.declaration.js",
"begin": "(?:(?<!\\.|\\$)\\b(readonly)\\s*)?(\\[)\\s*([_$[:alpha:]][_$[:alnum:]]*)\\s+(in)\\s+",
"beginCaptures": {
"1": {
"name": "storage.modifier.js"
},
"2": {
"name": "meta.brace.square.js"
},
"3": {
"name": "entity.name.type.js"
},
"4": {
"name": "keyword.operator.expression.in.js"
}
},
"end": "(\\])\\s*(\\?\\s*)?|$",
"endCaptures": {
"1": {
"name": "meta.brace.square.js"
},
"2": {
"name": "keyword.operator.optional.js"
}
},
"patterns": [
{
"include": "#type"
}
]
},
"function-declaration": {
"name": "meta.function.js",
"begin": "(?<!\\.|\\$)\\b(?:(export)\\s+)?(?:(async)\\s+)?(function\\b)(?:\\s*(\\*))?(?:(?:\\s+|(?<=\\*))([_$[:alpha:]][_$[:alnum:]]*))?\\s*",
@ -2780,7 +2815,7 @@
},
{
"name": "string.regex.js",
"begin": "/(?![/*])(?=(?:[^/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+/(?![/*])[gimy]*(?!\\s*[a-zA-Z0-9_$]))",
"begin": "(?<![_$[:alnum:]])/(?![/*])(?=(?:[^/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+/(?![/*])[gimy]*(?!\\s*[a-zA-Z0-9_$]))",
"beginCaptures": {
"0": {
"name": "punctuation.definition.string.begin.js"
@ -3571,5 +3606,5 @@
]
}
},
"version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/4d0bdebb93aadc25ecbb903ebc897e9cd5fab69c"
"version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/b5ce6b5632711b9230a33213874b818d994acab9"
}

View file

@ -6,9 +6,8 @@
import { MarkedString, CompletionItemKind, CompletionItem } from 'vscode-languageserver';
import Strings = require('../utils/strings');
import { XHRResponse, getErrorStatusDescription } from 'request-light';
import { XHRResponse, getErrorStatusDescription, xhr } from 'request-light';
import { JSONWorkerContribution, JSONPath, CompletionsCollector } from 'vscode-json-languageservice';
import { xhr } from 'request-light';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();

View file

@ -97,12 +97,13 @@
"command": "markdown.showPreview",
"key": "shift+ctrl+v",
"mac": "shift+cmd+v",
"when": "!terminalFocus"
"when": "editorFocus"
},
{
"command": "markdown.showPreviewToSide",
"key": "ctrl+k v",
"mac": "cmd+k v"
"mac": "cmd+k v",
"when": "editorFocus"
}
],
"snippets": [
@ -120,6 +121,11 @@
"type": ["array"],
"default": [],
"description": "A list of URLs or local paths to CSS style sheets to use from the markdown preview. Relative paths are interpreted relative to the folder open in the explorer. If there is no open folder, they are interpreted relative to the location of the markdown file. All '\\' need to be written as '\\\\'."
},
"markdown.previewFrontMatter": {
"type": ["string"],
"default": "hide",
"description": "Sets how YAML front matter should be rendered in the markdown preview. 'hide' removes the front matter. Otherwise, the front matter is treated as markdown content"
}
}
}

View file

@ -1,82 +1,71 @@
{
"Insert bold text": {
"prefix": "bold",
"body": "**${text}**${}",
"body": "**${1:text}**${}",
"description": "Insert bold text"
},
"Insert italic text": {
"prefix": "italic",
"body": "*${text}*${}",
"body": "*${1:text}*${}",
"description": "Insert italic text"
},
"Insert quoted text": {
"prefix": "quote",
"body": "> ${text}",
"body": "> ${1:text}",
"description": "Insert quoted text"
},
"Insert code": {
"prefix": "code",
"body": "`${text}`${}",
"body": "`${1:text}`${}",
"description": "Insert code"
},
"Insert fenced code block": {
"prefix": "fenced codeblock",
"body": [
"```${language}",
"```${1:language}",
"$0",
"```"
],
"description": "Insert fenced code block"
},
"Insert heading": {
"prefix": "heading",
"body": "# ${text}",
"body": "# ${1:text}",
"description": "Insert heading"
},
"Insert unordered list": {
"prefix": "unordered list",
"body": [
"- ${first}",
"- ${second}",
"- ${third}",
"- ${1:first}",
"- ${2:second}",
"- ${3:third}",
"$0"
],
"description": "Insert unordered list"
},
"Insert ordered list": {
"prefix": "ordered list",
"body": [
"1. ${first}",
"2. ${second}",
"3. ${third}",
"1. ${1:first}",
"2. ${2:second}",
"3. ${3:third}",
"$0"
],
"description": "Insert ordered list"
},
"Insert horizontal rule": {
"prefix": "horizontal rule",
"body": "----------\n",
"description": "Insert horizontal rule"
},
"Insert link": {
"prefix": "link",
"body": "[${text}](http://${link})$0",
"body": "[${1:text}](http://${2:link})$0",
"description": "Insert link"
},
"Insert image" : {
"Insert image": {
"prefix": "image",
"body": "![${alt}](http://${link})$0",
"body": "![${1:alt}](http://${2:link})$0",
"description": "Insert image"
}
}
}

View file

@ -7,10 +7,8 @@
import * as vscode from 'vscode';
import * as path from 'path';
import { ExtensionContext, TextDocumentContentProvider, EventEmitter, Event, Uri, ViewColumn } from 'vscode';
import TelemetryReporter from 'vscode-extension-telemetry';
interface IPackageInfo {
name: string;
version: string;
@ -19,7 +17,7 @@ interface IPackageInfo {
var telemetryReporter: TelemetryReporter;
export function activate(context: ExtensionContext) {
export function activate(context: vscode.ExtensionContext) {
let packageInfo = getPackageInfo(context);
telemetryReporter = packageInfo && new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
@ -63,21 +61,21 @@ function isMarkdownFile(document: vscode.TextDocument) {
&& document.uri.scheme !== 'markdown'; // prevent processing of own documents
}
function getMarkdownUri(uri: Uri) {
function getMarkdownUri(uri: vscode.Uri) {
return uri.with({ scheme: 'markdown', path: uri.path + '.rendered', query: uri.toString() });
}
function showPreview(uri?: Uri, sideBySide: boolean = false) {
function showPreview(uri?: vscode.Uri, sideBySide: boolean = false) {
let resource = uri;
if (!(resource instanceof Uri)) {
if (!(resource instanceof vscode.Uri)) {
if (vscode.window.activeTextEditor) {
// we are relaxed and don't check for markdown files
resource = vscode.window.activeTextEditor.document.uri;
}
}
if (!(resource instanceof Uri)) {
if (!(resource instanceof vscode.Uri)) {
if (!vscode.window.activeTextEditor) {
// this is most likely toggling the preview
return vscode.commands.executeCommand('markdown.showSource');
@ -93,16 +91,16 @@ function showPreview(uri?: Uri, sideBySide: boolean = false) {
telemetryReporter.sendTelemetryEvent('openPreview', {
where: sideBySide ? 'sideBySide' : 'inPlace',
how: (uri instanceof Uri) ? 'action' : 'pallete'
how: (uri instanceof vscode.Uri) ? 'action' : 'pallete'
});
return thenable;
}
function getViewColumn(sideBySide): ViewColumn {
function getViewColumn(sideBySide): vscode.ViewColumn {
const active = vscode.window.activeTextEditor;
if (!active) {
return ViewColumn.One;
return vscode.ViewColumn.One;
}
if (!sideBySide) {
@ -110,21 +108,21 @@ function getViewColumn(sideBySide): ViewColumn {
}
switch (active.viewColumn) {
case ViewColumn.One:
return ViewColumn.Two;
case ViewColumn.Two:
return ViewColumn.Three;
case vscode.ViewColumn.One:
return vscode.ViewColumn.Two;
case vscode.ViewColumn.Two:
return vscode.ViewColumn.Three;
}
return active.viewColumn;
}
function showSource(mdUri: Uri) {
function showSource(mdUri: vscode.Uri) {
if (!mdUri) {
return vscode.commands.executeCommand('workbench.action.navigateBack');
}
const docUri = Uri.parse(mdUri.query);
const docUri = vscode.Uri.parse(mdUri.query);
for (let editor of vscode.window.visibleTextEditors) {
if (editor.document.uri.toString() === docUri.toString()) {
@ -137,7 +135,7 @@ function showSource(mdUri: Uri) {
});
}
function getPackageInfo(context: ExtensionContext): IPackageInfo {
function getPackageInfo(context: vscode.ExtensionContext): IPackageInfo {
let extensionPackage = require(context.asAbsolutePath('./package.json'));
if (extensionPackage) {
return {
@ -154,13 +152,13 @@ interface IRenderer {
render(text: string): string;
}
class MDDocumentContentProvider implements TextDocumentContentProvider {
private _context: ExtensionContext;
private _onDidChange = new EventEmitter<Uri>();
class MDDocumentContentProvider implements vscode.TextDocumentContentProvider {
private _context: vscode.ExtensionContext;
private _onDidChange = new vscode.EventEmitter<vscode.Uri>();
private _waiting: boolean;
private _renderer: IRenderer;
constructor(context: ExtensionContext) {
constructor(context: vscode.ExtensionContext) {
this._context = context;
this._waiting = false;
this._renderer = this.createRenderer();
@ -191,31 +189,31 @@ class MDDocumentContentProvider implements TextDocumentContentProvider {
return path.normalize(p + '/') === path.normalize(path.resolve(p) + '/');
}
private fixHref(resource: Uri, href: string): string {
private fixHref(resource: vscode.Uri, href: string): string {
if (href) {
// Use href if it is already an URL
if (Uri.parse(href).scheme) {
if (vscode.Uri.parse(href).scheme) {
return href;
}
// Use href as file URI if it is absolute
if (this.isAbsolute(href)) {
return Uri.file(href).toString();
return vscode.Uri.file(href).toString();
}
// use a workspace relative path if there is a workspace
let rootPath = vscode.workspace.rootPath;
if (rootPath) {
return Uri.file(path.join(rootPath, href)).toString();
return vscode.Uri.file(path.join(rootPath, href)).toString();
}
// otherwise look relative to the markdown file
return Uri.file(path.join(path.dirname(resource.fsPath), href)).toString();
return vscode.Uri.file(path.join(path.dirname(resource.fsPath), href)).toString();
}
return href;
}
private computeCustomStyleSheetIncludes(uri: Uri): string[] {
private computeCustomStyleSheetIncludes(uri: vscode.Uri): string[] {
const styles = vscode.workspace.getConfiguration('markdown')['styles'];
if (styles && Array.isArray(styles) && styles.length > 0) {
return styles.map((style) => {
@ -225,9 +223,8 @@ class MDDocumentContentProvider implements TextDocumentContentProvider {
return [];
}
public provideTextDocumentContent(uri: Uri): Thenable<string> {
return vscode.workspace.openTextDocument(Uri.parse(uri.query)).then(document => {
public provideTextDocumentContent(uri: vscode.Uri): Thenable<string> {
return vscode.workspace.openTextDocument(vscode.Uri.parse(uri.query)).then(document => {
const head = [].concat(
'<!DOCTYPE html>',
'<html>',
@ -240,8 +237,7 @@ class MDDocumentContentProvider implements TextDocumentContentProvider {
'</head>',
'<body>'
).join('\n');
const body = this._renderer.render(document.getText());
const body = this._renderer.render(this.getDocumentContentForPreview(document));
const tail = [
'</body>',
@ -252,11 +248,11 @@ class MDDocumentContentProvider implements TextDocumentContentProvider {
});
}
get onDidChange(): Event<Uri> {
get onDidChange(): vscode.Event<vscode.Uri> {
return this._onDidChange.event;
}
public update(uri: Uri) {
public update(uri: vscode.Uri) {
if (!this._waiting) {
this._waiting = true;
setTimeout(() => {
@ -265,4 +261,13 @@ class MDDocumentContentProvider implements TextDocumentContentProvider {
}, 300);
}
}
private getDocumentContentForPreview(document: vscode.TextDocument): string {
const content = document.getText();
const previewFrontMatter = vscode.workspace.getConfiguration('markdown')['previewFrontMatter'];
if (previewFrontMatter === 'hide') {
return content.replace(/^-{3}[ \t]*(\r\n|\n)(.|\r\n|\n)*?(\r\n|\n)-{3}[ \t]*(\r\n|\n)/, '');
}
return content;
}
}

View file

@ -15,6 +15,10 @@
<string>Markdown</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#frontMatter</string>
</dict>
<dict>
<key>include</key>
<string>#block</string>
@ -216,7 +220,7 @@
<key>blockquote</key>
<dict>
<key>begin</key>
<string>(^|\G)(&gt;) ?</string>
<string>(^|\G)[ ]{0,3}(&gt;) ?</string>
<key>captures</key>
<dict>
<key>2</key>
@ -235,7 +239,7 @@
</dict>
</array>
<key>while</key>
<string>(^|\G)(&gt;) ?</string>
<string>(^|\G)\s*(&gt;) ?</string>
</dict>
<key>heading</key>
<dict>
@ -546,11 +550,11 @@
<key>fenced_code_block_css</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(css|css.erb)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(css|css.erb)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -562,11 +566,11 @@
<key>fenced_code_block_basic</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(html|htm|shtml|xhtml|inc|tmpl|tpl)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(html|htm|shtml|xhtml|inc|tmpl|tpl)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -578,11 +582,11 @@
<key>fenced_code_block_ini</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(ini|conf)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(ini|conf)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -594,11 +598,11 @@
<key>fenced_code_block_java</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(java|bsh)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(java|bsh)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -610,11 +614,11 @@
<key>fenced_code_block_lua</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(lua)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(lua)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -626,11 +630,11 @@
<key>fenced_code_block_makefile</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(Makefile|makefile|GNUmakefile|OCamlMakefile)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(Makefile|makefile|GNUmakefile|OCamlMakefile)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -642,11 +646,11 @@
<key>fenced_code_block_perl</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(perl|pl|pm|pod|t|PL|psgi|vcl)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(perl|pl|pm|pod|t|PL|psgi|vcl)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -658,11 +662,11 @@
<key>fenced_code_block_r</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(R|r|s|S|Rprofile)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(R|r|s|S|Rprofile)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -674,11 +678,11 @@
<key>fenced_code_block_ruby</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{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,})\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>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -690,11 +694,11 @@
<key>fenced_code_block_php</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(php|php3|php4|php5|phpt|phtml|aw|ctp)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(php|php3|php4|php5|phpt|phtml|aw|ctp)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -706,11 +710,11 @@
<key>fenced_code_block_sql</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(sql|ddl|dml)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(sql|ddl|dml)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -722,11 +726,11 @@
<key>fenced_code_block_vs_net</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(vb)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(vb)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -738,11 +742,11 @@
<key>fenced_code_block_xml</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(xml|xsd|tld|jsp|pt|cpt|dtml|rss|opml)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(xml|xsd|tld|jsp|pt|cpt|dtml|rss|opml)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -754,11 +758,11 @@
<key>fenced_code_block_xsl</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(xsl|xslt)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(xsl|xslt)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -770,11 +774,11 @@
<key>fenced_code_block_yaml</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(yaml|yml)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(yaml|yml)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -786,11 +790,11 @@
<key>fenced_code_block_dosbatch</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(bat|batch)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(bat|batch)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -802,11 +806,11 @@
<key>fenced_code_block_clojure</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(clj|cljs|clojure)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(clj|cljs|clojure)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -818,11 +822,11 @@
<key>fenced_code_block_coffee</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(coffee|Cakefile|coffee.erb)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(coffee|Cakefile|coffee.erb)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -834,11 +838,11 @@
<key>fenced_code_block_c</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(c|h)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(c|h)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -850,11 +854,11 @@
<key>fenced_code_block_diff</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(patch|diff|rej)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(patch|diff|rej)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -866,11 +870,11 @@
<key>fenced_code_block_dockerfile</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(dockerfile|Dockerfile)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(dockerfile|Dockerfile)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -882,11 +886,11 @@
<key>fenced_code_block_git_commit</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(COMMIT_EDITMSG|MERGE_MSG)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(COMMIT_EDITMSG|MERGE_MSG)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -898,11 +902,11 @@
<key>fenced_code_block_git_rebase</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(git-rebase-todo)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(git-rebase-todo)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -914,11 +918,11 @@
<key>fenced_code_block_groovy</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(groovy|gvy)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(groovy|gvy)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -930,11 +934,11 @@
<key>fenced_code_block_jade</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(jade)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(jade)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -946,11 +950,11 @@
<key>fenced_code_block_js</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(js|jsx|javascript)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(js|jsx|javascript)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -962,11 +966,11 @@
<key>fenced_code_block_js_regexp</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(regexp)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(regexp)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -978,11 +982,11 @@
<key>fenced_code_block_json</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{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,})\s*(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>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -994,11 +998,11 @@
<key>fenced_code_block_less</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(less)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(less)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -1010,11 +1014,11 @@
<key>fenced_code_block_objc</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(objectivec|mm|objc|obj-c|m|h)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(objectivec|mm|objc|obj-c|m|h)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -1026,11 +1030,11 @@
<key>fenced_code_block_perl6</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(perl6|p6|pl6|pm6|nqp)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(perl6|p6|pl6|pm6|nqp)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -1042,11 +1046,11 @@
<key>fenced_code_block_powershell</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(powershell|ps1|psm1|psd1)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(powershell|ps1|psm1|psd1)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -1058,11 +1062,11 @@
<key>fenced_code_block_python</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(python|py|py3|rpy|pyw|cpy|SConstruct|Sconstruct|sconstruct|SConscript|gyp|gypi)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(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>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -1074,11 +1078,11 @@
<key>fenced_code_block_regexp_python</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(re)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(re)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -1090,11 +1094,11 @@
<key>fenced_code_block_shell</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(shell|sh|bash|zsh|bashrc|bash_profile|bash_login|profile|bash_logout|.textmate_init)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(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>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -1106,11 +1110,11 @@
<key>fenced_code_block_ts</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(typescript|ts)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(typescript|ts)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -1122,11 +1126,11 @@
<key>fenced_code_block_tsx</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(tsx)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(tsx)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)[ ]{0,3}(\2)\s*\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -1138,11 +1142,11 @@
<key>fenced_code_block_csharp</key>
<dict>
<key>begin</key>
<string>(^|\G)\s*([`~]{3,})\s*(cs|csharp|c#)\s*$</string>
<string>(^|\G)\s*(([`~]){3,})\s*(cs|csharp|c#)\s*$</string>
<key>name</key>
<string>markup.fenced_code.block.markdown</string>
<key>end</key>
<string>(^|\G)(\2)\n</string>
<key>while</key>
<string>(^|\G)(?!\s*\2\3*\s*$)</string>
<key>patterns</key>
<array>
<dict>
@ -1880,6 +1884,20 @@
</dict>
</dict>
</dict>
<key>frontMatter</key>
<dict>
<key>begin</key>
<string>\A-{3}\s*$</string>
<key>while</key>
<string>^(?!-{3}\s*$)</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>source.yaml</string>
</dict>
</array>
</dict>
</dict>
<key>scopeName</key>
<string>text.html.markdown</string>

View file

@ -2,10 +2,9 @@
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"outDir": "out",
"outDir": "./out",
"noLib": true,
"sourceMap": true,
"rootDir": "."
"sourceMap": true
},
"exclude": [
"node_modules"

View file

@ -31,7 +31,7 @@
{
"name": "debug",
"repositoryURL": "https://github.com/visionmedia/debug",
"version": "2.2.0",
"version": "2.3.3",
"license": "MIT",
"isProd": true
},
@ -52,7 +52,7 @@
{
"name": "glob",
"repositoryURL": "https://github.com/isaacs/node-glob",
"version": "7.0.6",
"version": "7.1.1",
"license": "ISC",
"isProd": true
},
@ -73,7 +73,7 @@
{
"name": "inflight",
"repositoryURL": "https://github.com/npm/inflight",
"version": "1.0.5",
"version": "1.0.6",
"license": "ISC",
"isProd": true
},
@ -94,7 +94,7 @@
{
"name": "ms",
"repositoryURL": "https://github.com/rauchg/ms.js",
"version": "0.7.1",
"version": "0.7.2",
"license": "MIT",
"isProd": true
},
@ -108,7 +108,7 @@
{
"name": "path-is-absolute",
"repositoryURL": "https://github.com/sindresorhus/path-is-absolute",
"version": "1.0.0",
"version": "1.0.1",
"license": "MIT",
"isProd": true
},

11
extensions/npm-shrinkwrap.json generated Normal file
View file

@ -0,0 +1,11 @@
{
"name": "vscode-extensions",
"version": "0.0.1",
"dependencies": {
"typescript": {
"version": "2.0.10",
"from": "typescript@>=2.0.10 <3.0.0",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.0.10.tgz"
}
}
}

12
extensions/package.json Normal file
View file

@ -0,0 +1,12 @@
{
"name": "vscode-extensions",
"version": "0.0.1",
"private": true,
"description": "Dependencies shared by all extensions",
"dependencies": {
"typescript": "^2.0.10"
},
"scripts": {
"postinstall": "node ./postinstall"
}
}

View file

@ -1,29 +1,8 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "language-php",
"version": "0.29.0",
"version": "0.0.0",
"license": "MIT",
"repositoryURL": "https://github.com/atom/language-php",
"description": "The file snippets/php.json was derived from the Atom package https://atom.io/packages/language-php which was originally converted from the PHP TextMate bundle https://github.com/textmate/php.tmbundle."
},
{
"name": "textmate/php.tmbundle",
"version": "0.0.0",
"license": "TextMate Bundle License",
"repositoryURL": "https://github.com/textmate/php.tmbundle",
"licenseDetail": [
"Copyright (c) textmate-php.tmbundle project authors",
"",
"If not otherwise specified (see below), files in this repository fall under the following license:",
"",
"Permission to copy, use, modify, sell and distribute this",
"software is granted. This software is provided \"as is\" without",
"express or implied warranty, and with no claim as to its",
"suitability for any purpose.",
"",
"An exception is made for files in readable text which contain their own license information,",
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added",
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
]
"description": "The files snippets/php.json & syntaxes/php.tmLanguage.json were derived from the Atom package https://atom.io/packages/language-php which was originally converted from the PHP TextMate bundle https://github.com/textmate/php.tmbundle."
}]

View file

@ -19,7 +19,7 @@
"grammars": [{
"language": "php",
"scopeName": "text.html.php",
"path": "./syntaxes/php.json",
"path": "./syntaxes/php.tmLanguage.json",
"embeddedLanguages": {
"text.html": "html",
"source.php": "php",
@ -66,6 +66,7 @@
},
"scripts": {
"compile": "gulp compile-extension:php",
"watch": "gulp watch-extension:php"
"watch": "gulp watch-extension:php",
"update-grammar": "node ../../build/npm/update-grammar.js atom/language-php grammars/php.cson ./syntaxes/php.tmLanguage.json"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -223,10 +223,10 @@
"c": "<?php",
"t": "begin.block.embedded.meta.metatag.php.punctuation.section",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.metatag.php rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.metatag.php rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.metatag.php rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.metatag.php rgb(128, 0, 0)",
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.punctuation.section.embedded.begin.metatag.php rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.punctuation.section.embedded.begin.metatag.php rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.punctuation.section.embedded.begin.metatag.php rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.punctuation.section.embedded.begin.metatag.php rgb(128, 0, 0)",
"hc_black": ".hc-black .token rgb(255, 255, 255)"
}
},
@ -3237,10 +3237,10 @@
"c": "?",
"t": "block.embedded.end.meta.metatag.php.punctuation.section.source",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.metatag.php rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.metatag.php rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.metatag.php rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.metatag.php rgb(128, 0, 0)",
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.punctuation.section.embedded.end.metatag.php rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.punctuation.section.embedded.end.metatag.php rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.punctuation.section.embedded.end.metatag.php rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.punctuation.section.embedded.end.metatag.php rgb(128, 0, 0)",
"hc_black": ".hc-black .token rgb(255, 255, 255)"
}
},
@ -3248,10 +3248,10 @@
"c": ">",
"t": "block.embedded.end.meta.metatag.php.punctuation.section",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.metatag.php rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.metatag.php rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.metatag.php rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.metatag.php rgb(128, 0, 0)",
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.punctuation.section.embedded.end.metatag.php rgb(86, 156, 214)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.punctuation.section.embedded.end.metatag.php rgb(128, 0, 0)",
"dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.punctuation.section.embedded.end.metatag.php rgb(86, 156, 214)",
"light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.punctuation.section.embedded.end.metatag.php rgb(128, 0, 0)",
"hc_black": ".hc-black .token rgb(255, 255, 255)"
}
},

34
extensions/postinstall.js Normal file
View file

@ -0,0 +1,34 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
const fs = require('fs');
const path = require('path');
function removeFile(filePath) {
try {
fs.unlinkSync(filePath);
console.log(`removed '${filePath}'`);
} catch (e) {
console.warn(e);
}
}
// delete unused typescript stuff in lib folder
const libPath = path.dirname(require.resolve('typescript'));
for (let name of fs.readdirSync(libPath)) {
if (name !== 'typescript.d.ts' && name !== 'typescript.js' && name !== 'lib.es6.d.ts') {
removeFile(path.join(libPath, name));
}
}
// delete unused typescript stuff in bin folder
const binPath = path.join(path.dirname(libPath), 'bin');
for (let name of fs.readdirSync(binPath)) {
removeFile(path.join(binPath, name));
}
removeFile(path.join(path.dirname(libPath), 'Gulpfile.ts'));

View file

@ -113,8 +113,8 @@
"c": "Azure",
"t": "entity.first.inherited-class.meta.module.name.other.ruby.type",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.name.type rgb(78, 201, 176)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.name.type rgb(38, 127, 153)",
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.other.inherited-class rgb(78, 201, 176)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.other.inherited-class rgb(38, 127, 153)",
"dark_vs": ".vs-dark .token rgb(212, 212, 212)",
"light_vs": ".vs .token rgb(0, 0, 0)",
"hc_black": ".hc-black .token rgb(255, 255, 255)"
@ -124,8 +124,8 @@
"c": "::",
"t": "entity.first.inheritance.inherited-class.meta.module.name.other.punctuation.ruby.separator.type",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.name.type rgb(78, 201, 176)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.name.type rgb(38, 127, 153)",
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.other.inherited-class rgb(78, 201, 176)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.other.inherited-class rgb(38, 127, 153)",
"dark_vs": ".vs-dark .token rgb(212, 212, 212)",
"light_vs": ".vs .token rgb(0, 0, 0)",
"hc_black": ".hc-black .token rgb(255, 255, 255)"
@ -135,8 +135,8 @@
"c": "ARM",
"t": "entity.inherited-class.meta.module.name.other.ruby.second.type",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.name.type rgb(78, 201, 176)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.name.type rgb(38, 127, 153)",
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.other.inherited-class rgb(78, 201, 176)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.other.inherited-class rgb(38, 127, 153)",
"dark_vs": ".vs-dark .token rgb(212, 212, 212)",
"light_vs": ".vs .token rgb(0, 0, 0)",
"hc_black": ".hc-black .token rgb(255, 255, 255)"
@ -146,8 +146,8 @@
"c": "::",
"t": "entity.inheritance.inherited-class.meta.module.name.other.punctuation.ruby.second.separator.type",
"r": {
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.name.type rgb(78, 201, 176)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.name.type rgb(38, 127, 153)",
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.other.inherited-class rgb(78, 201, 176)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.other.inherited-class rgb(38, 127, 153)",
"dark_vs": ".vs-dark .token rgb(212, 212, 212)",
"light_vs": ".vs .token rgb(0, 0, 0)",
"hc_black": ".hc-black .token rgb(255, 255, 255)"
@ -322,8 +322,8 @@
"c": "MsRestAzure::AzureServiceClient",
"t": "class.entity.inherited-class.meta.other.ruby",
"r": {
"dark_plus": ".vs-dark .token rgb(212, 212, 212)",
"light_plus": ".vs .token rgb(0, 0, 0)",
"dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.other.inherited-class rgb(78, 201, 176)",
"light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.other.inherited-class rgb(38, 127, 153)",
"dark_vs": ".vs-dark .token rgb(212, 212, 212)",
"light_vs": ".vs .token rgb(0, 0, 0)",
"hc_black": ".hc-black .token rgb(255, 255, 255)"

File diff suppressed because one or more lines are too long

View file

@ -10,7 +10,7 @@
"languages": [{
"id": "shellscript",
"aliases": ["Shell Script (Bash)", "shellscript", "bash", "sh", "zsh"],
"extensions": [".sh", ".bash", ".bashrc", ".bash_aliases", ".bash_profile", ".bash_login", ".ebuild", ".install", ".profile", ".bash_logout", ".zsh", ".zshrc", ".zprofile", ".zlogin", ".zlogout", ".zshenv"],
"extensions": [".sh", ".bash", ".bashrc", ".bash_aliases", ".bash_profile", ".bash_login", ".ebuild", ".install", ".profile", ".bash_logout", ".zsh", ".zshrc", ".zprofile", ".zlogin", ".zlogout", ".zshenv", ".zsh-theme"],
"filenames": ["PKGBUILD"],
"firstLine": "^#!.*\\b(bash|zsh|sh|tcsh).*|^#\\s*-\\*-[^*]*mode:\\s*shell-script[^*]*-\\*-",
"configuration": "./language-configuration.json",

View file

@ -7,86 +7,70 @@
"prefix": "po",
"body": "print(\"\\($1)\")$0"
},
"repeat...while loop": {
"prefix": "repeat",
"body": [
"repeat {",
" $0",
"} while ${true}"
"} while ${1:true}"
],
"description": "repeat...while loop"
},
"While loop": {
"prefix": "while",
"body": [
"while ${true} {",
"while ${1:true} {",
" $0",
"}"
],
"description": "While loop"
},
"For-In statement": {
"prefix": "forin",
"body": [
"for ${item} in ${collection} {",
"for ${1:item} in ${2:collection} {",
" $0",
"}"
],
"description": "For-In statement"
},
"Reverse for loop": {
"prefix": "forr",
"body": [
"for var ${i} = ${length} - 1; ${i} >= 0; ${i}-- {",
"for var ${1:i} = ${2:length} - 1; ${1:i} >= 0; ${1:i}-- {",
" $0",
"}"
],
"description": "Reverse for loop"
},
"for loop": {
"prefix": "for",
"body": [
"for var ${i} = 0; ${i} < ${length}; ${i}++ {",
"for var ${1:i} = 0; ${1:i} < ${2:length}; ${1:i}++ {",
" $0",
"}"
],
"description": "for loop"
},
"if statement": {
"prefix": "if",
"body": [
"if ${true} {",
"if ${1:true} {",
" $0",
"}"
],
"description": "if statement"
},
"else-if statement": {
"prefix": "elif",
"body": [
"else if ${true} {",
"else if ${1:true} {",
" $0",
"}"
],
"description": "if statement"
},
"Else statement": {
"prefix": "else",
"body": [
"else {",
@ -95,35 +79,29 @@
],
"description": "Else statement"
},
"Guard statement": {
"prefix": "guard",
"body": [
"guard let ${a} = ${optional} else {",
"guard let ${1:a} = ${2:optional} else {",
" $0",
"}"
],
"description": "Guard statement"
},
"Optional Binding statement": {
"prefix": "ifnil",
"body": [
"if let ${a} = ${optional} {",
"if let ${1:a} = ${2:optional} {",
" $0",
"}"
],
"description": "Optional Binding statement"
},
"Switch statement": {
"prefix": "switch",
"body": [
"switch ${switch_on} {",
"case ${a}:",
"switch ${1:switch_on} {",
"case ${2:a}:",
" $0",
"default:",
" $1",
@ -131,28 +109,25 @@
],
"description": "Switch statement"
},
"Do catch": {
"prefix": "docatch",
"body": [
"do {",
" try ${function that throws}",
"} catch ${pattern} {",
" try ${1:function that throws}",
"} catch ${2:pattern} {",
" $0",
"}"
],
"description": "Try catch"
},
"Enum": {
"prefix": "enum",
"body": [
"enum ${Name} {",
"enum ${1:Name} {",
" case $0",
"}"
],
"description": "Enum"
}
}

View file

@ -20,7 +20,8 @@
"support.type",
"entity.name.type",
"storage.type.cs",
"storage.type.java"
"storage.type.java",
"entity.other.inherited-class"
],
"settings": {
"foreground": "#4EC9B0"

View file

@ -271,7 +271,8 @@
}
},
{
"scope": "metatag.php",
"name": "coloring of the PHP start and end tag (<?php and ?>)",
"scope": ["punctuation.section.embedded.begin.metatag.php", "punctuation.section.embedded.end.metatag.php"],
"settings": {
"foreground": "#569cd6"
}

View file

@ -20,7 +20,8 @@
"support.type",
"entity.name.type",
"storage.type.cs",
"storage.type.java"
"storage.type.java",
"entity.other.inherited-class"
],
"settings": {
"foreground": "#267f99"

View file

@ -268,7 +268,8 @@
}
},
{
"scope": "metatag.php",
"name": "coloring of the PHP start and end tag (<?php and ?>)",
"scope": ["punctuation.section.embedded.begin.metatag.php", "punctuation.section.embedded.end.metatag.php"],
"settings": {
"foreground": "#800000"
}

View file

@ -2,6 +2,11 @@
"name": "typescript",
"version": "0.10.1",
"dependencies": {
"@types/semver": {
"version": "5.3.30",
"from": "@types/semver@>=5.3.30 <6.0.0",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.3.30.tgz"
},
"applicationinsights": {
"version": "0.15.6",
"from": "applicationinsights@0.15.6",
@ -13,9 +18,9 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz"
},
"typescript": {
"version": "2.0.8",
"from": "typescript@2.0.8",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.0.8.tgz"
"version": "2.0.10",
"from": "typescript@2.0.10",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.0.10.tgz"
},
"vscode-extension-telemetry": {
"version": "0.0.5",

View file

@ -11,10 +11,11 @@
"vscode": "*"
},
"dependencies": {
"@types/semver": "^5.3.30",
"semver": "4.3.6",
"vscode-extension-telemetry": "^0.0.5",
"vscode-nls": "^2.0.1",
"typescript": "2.0.8"
"typescript": "2.0.10"
},
"scripts": {
"postinstall": "node ./bin/postinstall",

View file

@ -8,7 +8,6 @@
],
"description": "jsdoc snippet"
},
"Constructor": {
"prefix": "ctor",
"body": [
@ -22,99 +21,90 @@
],
"description": "Constructor"
},
"Class Definition": {
"prefix": "class",
"body": [
"/**",
" * ${name}",
" * ${1:name}",
" */",
"class ${name} {",
"\tconstructor(${parameters}) {",
"class ${1:name} {",
"\tconstructor(${2:parameters}) {",
"\t\t$0",
"\t}",
"}"
],
"description": "Class Definition"
},
"Public Method Definition": {
"prefix": "public method",
"body": [
"/**",
" * ${name}",
" * ${1:name}",
" */",
"public ${name}() {",
"public ${1:name}() {",
"\t$0",
"}"
],
"description": "Public Method Definition"
},
"Private Method Definition": {
"prefix": "private method",
"body": [
"private ${name}() {",
"private ${1:name}() {",
"\t$0",
"}"
],
"description": "Private Method Definition"
},
"Import external module.": {
"prefix": "import statement",
"body": [
"import { $0 } from '${module}';"
"import { $0 } from '${1:module}';"
],
"description": "Import external module."
},
"Property getter": {
"prefix": "get",
"body": [
"",
"public get ${value}() : ${string} {",
" ${return $0}",
"public get ${1:value}() : ${2:string} {",
" ${3:return $0}",
"}",
""
],
"description": "Property getter"
},
"Log to the console": {
"prefix": "log",
"body": [
"console.log(${_});",
"console.log($1);",
"$0"
],
"description": "Log to the console"
},
"Define a full property": {
"prefix": "prop",
"body": [
"",
"private _${value} : ${string};",
"public get ${value}() : ${string} {",
" return this._${value};",
"private _${1:value} : ${2:string};",
"public get ${1:value}() : ${2:string} {",
" return this._${1:value};",
"}",
"public set ${value}(v : ${string}) {",
" this._${value} = v;",
"public set ${1:value}(v : ${2:string}) {",
" this._${1:value} = v;",
"}",
""
],
"description": "Define a full property"
},
"Triple-slash reference": {
"prefix": "ref",
"body": [
"/// <reference path=\"${_}\" />",
"/// <reference path=\"$1\" />",
"$0"
],
"description": "Triple-slash reference"
},
"Return false": {
"prefix": "ret0",
"body": [
@ -122,7 +112,6 @@
],
"description": "Return false"
},
"Return true": {
"prefix": "ret1",
"body": [
@ -130,41 +119,37 @@
],
"description": "Return true"
},
"Return statement": {
"prefix": "ret",
"body": [
"return ${_};$0"
"return $1;$0"
],
"description": "Return statement"
},
"Property setter": {
"prefix": "set",
"body": [
"",
"public set ${value}(v : ${string}) {",
" this.${_} = v;",
"public set ${1:value}(v : ${2:string}) {",
" this.$3 = v;",
"}",
""
],
"description": "Property setter"
},
"Throw Exception": {
"prefix": "throw",
"body": [
"throw \"${_}\";",
"throw \"$1\";",
"$0"
],
"description": "Throw Exception"
},
"For Loop": {
"prefix": "for",
"body": [
"for (var ${index} = 0; ${index} < ${array}.length; ${index}++) {",
"\tvar ${element} = ${array}[${index}];",
"for (var ${1:index} = 0; ${1:index} < ${2:array}.length; ${1:index}++) {",
"\tvar ${3:element} = ${2:array}[${1:index}];",
"\t$0",
"}"
],
@ -173,7 +158,7 @@
"For-Each Loop using =>": {
"prefix": "foreach =>",
"body": [
"${array}.forEach(${element} => {",
"${1:array}.forEach(${2:element} => {",
"\t$0",
"});"
],
@ -182,9 +167,9 @@
"For-In Loop": {
"prefix": "forin",
"body": [
"for (var ${key} in ${object}) {",
"\tif (${object}.hasOwnProperty(${key})) {",
"\t\tvar ${element} = ${object}[${key}];",
"for (var ${1:key} in ${2:object}) {",
"\tif (${2:object}.hasOwnProperty(${1:key})) {",
"\t\tvar ${3:element} = ${2:object}[${1:key}];",
"\t\t$0",
"\t}",
"}"
@ -194,7 +179,7 @@
"Function Statement": {
"prefix": "function",
"body": [
"function ${name}(${params}:${type}) {",
"function ${1:name}(${2:params}:${3:type}) {",
"\t$0",
"}"
],
@ -203,7 +188,7 @@
"If Statement": {
"prefix": "if",
"body": [
"if (${condition}) {",
"if (${1:condition}) {",
"\t$0",
"}"
],
@ -212,7 +197,7 @@
"If-Else Statement": {
"prefix": "ifelse",
"body": [
"if (${condition}) {",
"if (${1:condition}) {",
"\t$0",
"} else {",
"\t",
@ -223,15 +208,15 @@
"New Statement": {
"prefix": "new",
"body": [
"var ${name} = new ${type}(${arguments});$0"
"var ${1:name} = new ${2:type}(${3:arguments});$0"
],
"description": "New Statement"
},
"Switch Statement": {
"prefix": "switch",
"body": [
"switch (${key}) {",
"\tcase ${value}:",
"switch (${1:key}) {",
"\tcase ${2:value}:",
"\t\t$0",
"\t\tbreak;",
"",
@ -244,7 +229,7 @@
"While Statement": {
"prefix": "while",
"body": [
"while (${condition}) {",
"while (${1:condition}) {",
"\t$0",
"}"
],
@ -255,16 +240,16 @@
"body": [
"do {",
"\t$0",
"} while (${condition});"
"} while (${1:condition});"
],
"description": "Do-While Statement"
},
"Try-Catch Statement":{
"Try-Catch Statement": {
"prefix": "trycatch",
"body": [
"try {",
"\t$0",
"} catch (${error}) {",
"} catch (${1:error}) {",
"\t",
"}"
],
@ -275,8 +260,8 @@
"body": [
"setTimeout(function() {",
"\t$0",
"}, ${timeout});"
"}, ${1:timeout});"
],
"description": "Set Timeout Function"
}
}
}

View file

@ -8,7 +8,6 @@
],
"description": "jsdoc snippet"
},
"Constructor": {
"prefix": "ctor",
"body": [
@ -22,99 +21,90 @@
],
"description": "Constructor"
},
"Class Definition": {
"prefix": "class",
"body": [
"/**",
" * ${name}",
" * ${1:name}",
" */",
"class ${name} {",
"\tconstructor(${parameters}) {",
"class ${1:name} {",
"\tconstructor(${2:parameters}) {",
"\t\t$0",
"\t}",
"}"
],
"description": "Class Definition"
},
"Public Method Definition": {
"prefix": "public method",
"body": [
"/**",
" * ${name}",
" * ${1:name}",
" */",
"public ${name}() {",
"public ${1:name}() {",
"\t$0",
"}"
],
"description": "Public Method Definition"
},
"Private Method Definition": {
"prefix": "private method",
"body": [
"private ${name}() {",
"private ${1:name}() {",
"\t$0",
"}"
],
"description": "Private Method Definition"
},
"Import external module.": {
"prefix": "import statement",
"body": [
"import ${name} = require('$0');"
"import ${1:name} = require('$0');"
],
"description": "Import external module."
},
"Property getter": {
"prefix": "get",
"body": [
"",
"public get ${value}() : ${string} {",
" ${return $0}",
"public get ${1:value}() : ${2:string} {",
" ${3:return $0}",
"}",
""
],
"description": "Property getter"
},
"Log to the console": {
"prefix": "log",
"body": [
"console.log(${_});",
"console.log($1);",
"$0"
],
"description": "Log to the console"
},
"Define a full property": {
"prefix": "prop",
"body": [
"",
"private _${value} : ${string};",
"public get ${value}() : ${string} {",
" return this._${value};",
"private _${1:value} : ${2:string};",
"public get ${1:value}() : ${2:string} {",
" return this._${1:value};",
"}",
"public set ${value}(v : ${string}) {",
" this._${value} = v;",
"public set ${1:value}(v : ${2:string}) {",
" this._${1:value} = v;",
"}",
""
],
"description": "Define a full property"
},
"Triple-slash reference": {
"prefix": "ref",
"body": [
"/// <reference path=\"${_}\" />",
"/// <reference path=\"$1\" />",
"$0"
],
"description": "Triple-slash reference"
},
"Return false": {
"prefix": "ret0",
"body": [
@ -122,7 +112,6 @@
],
"description": "Return false"
},
"Return true": {
"prefix": "ret1",
"body": [
@ -130,41 +119,37 @@
],
"description": "Return true"
},
"Return statement": {
"prefix": "ret",
"body": [
"return ${_};$0"
"return $1;$0"
],
"description": "Return statement"
},
"Property setter": {
"prefix": "set",
"body": [
"",
"public set ${value}(v : ${string}) {",
" this.${_} = v;",
"public set ${1:value}(v : ${2:string}) {",
" this.$3 = v;",
"}",
""
],
"description": "Property setter"
},
"Throw Exception": {
"prefix": "throw",
"body": [
"throw \"${_}\";",
"throw \"$1\";",
"$0"
],
"description": "Throw Exception"
},
"For Loop": {
"prefix": "for",
"body": [
"for (var ${index} = 0; ${index} < ${array}.length; ${index}++) {",
"\tvar ${element} = ${array}[${index}];",
"for (var ${1:index} = 0; ${1:index} < ${2:array}.length; ${1:index}++) {",
"\tvar ${3:element} = ${2:array}[${1:index}];",
"\t$0",
"}"
],
@ -173,18 +158,18 @@
"For-Each Loop using =>": {
"prefix": "foreach =>",
"body": [
"${array}.forEach(${element} => {",
"${1:array}.forEach(${2:element} => {",
"\t$0",
"});"
],
"description": "For-Each Loop using =>"
},
},
"For-In Loop": {
"prefix": "forin",
"body": [
"for (var ${key} in ${object}) {",
"\tif (${object}.hasOwnProperty(${key})) {",
"\t\tvar ${element} = ${object}[${key}];",
"for (var ${1:key} in ${2:object}) {",
"\tif (${2:object}.hasOwnProperty(${1:key})) {",
"\t\tvar ${3:element} = ${2:object}[${1:key}];",
"\t\t$0",
"\t}",
"}"
@ -194,7 +179,7 @@
"Function Statement": {
"prefix": "function",
"body": [
"function ${name}(${params}:${type}) {",
"function ${1:name}(${2:params}:${3:type}) {",
"\t$0",
"}"
],
@ -203,7 +188,7 @@
"If Statement": {
"prefix": "if",
"body": [
"if (${condition}) {",
"if (${1:condition}) {",
"\t$0",
"}"
],
@ -212,7 +197,7 @@
"If-Else Statement": {
"prefix": "ifelse",
"body": [
"if (${condition}) {",
"if (${1:condition}) {",
"\t$0",
"} else {",
"\t",
@ -223,15 +208,15 @@
"New Statement": {
"prefix": "new",
"body": [
"var ${name} = new ${type}(${arguments});$0"
"var ${1:name} = new ${2:type}(${2:arguments});$0"
],
"description": "New Statement"
},
"Switch Statement": {
"prefix": "switch",
"body": [
"switch (${key}) {",
"\tcase ${value}:",
"switch (${1:key}) {",
"\tcase ${2:value}:",
"\t\t$0",
"\t\tbreak;",
"",
@ -244,7 +229,7 @@
"While Statement": {
"prefix": "while",
"body": [
"while (${condition}) {",
"while (${1:condition}) {",
"\t$0",
"}"
],
@ -255,16 +240,16 @@
"body": [
"do {",
"\t$0",
"} while (${condition});"
"} while (${1:condition});"
],
"description": "Do-While Statement"
},
"Try-Catch Statement":{
"Try-Catch Statement": {
"prefix": "trycatch",
"body": [
"try {",
"\t$0",
"} catch (${error}) {",
"} catch (${1:error}) {",
"\t",
"}"
],
@ -275,8 +260,8 @@
"body": [
"setTimeout(function() {",
"\t$0",
"}, ${timeout});"
"}, ${1:timeout});"
],
"description": "Set Timeout Function"
}
}
}

View file

@ -5,7 +5,7 @@
'use strict';
import { CompletionItem, TextDocument, Position, CompletionItemKind, CompletionItemProvider, CancellationToken, WorkspaceConfiguration, TextEdit, Range } from 'vscode';
import { CompletionItem, TextDocument, Position, CompletionItemKind, CompletionItemProvider, CancellationToken, WorkspaceConfiguration, TextEdit, Range, SnippetString } from 'vscode';
import { ITypescriptServiceClient } from '../typescriptService';
@ -23,8 +23,10 @@ class MyCompletionItem extends CompletionItem {
this.sortText = entry.sortText;
this.kind = MyCompletionItem.convertKind(entry.kind);
if (entry.replacementSpan) {
let span = entry.replacementSpan;
this.textEdit = TextEdit.replace(new Range(span.start.line, span.start.offset, span.end.line, span.end.offset), entry.name);
let span: protocol.TextSpan = entry.replacementSpan;
// The indexing for the range returned by the server uses 1-based indexing.
// We convert to 0-based indexing.
this.textEdit = TextEdit.replace(new Range(span.start.line - 1, span.start.offset - 1, span.end.line - 1, span.end.offset - 1), entry.name);
}
}
@ -159,15 +161,15 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
suggestionArgumentNames = detail.displayParts
.filter(part => part.kind === 'parameterName')
.map(part => `{{${part.text}}}`);
.map((part, i) => `\${${i + 1}:${part.text}}`);
if (suggestionArgumentNames.length > 0) {
codeSnippet += '(' + suggestionArgumentNames.join(', ') + '){{}}';
codeSnippet += '(' + suggestionArgumentNames.join(', ') + ')$0';
} else {
codeSnippet += '()';
}
item.insertText = codeSnippet;
item.insertText = new SnippetString(codeSnippet);
}
return item;
@ -179,4 +181,4 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
}
}
}
}

View file

@ -5,7 +5,7 @@
'use strict';
import { DocumentRangeFormattingEditProvider, OnTypeFormattingEditProvider, FormattingOptions, TextDocument, Position, Range, CancellationToken, TextEdit, WorkspaceConfiguration } from 'vscode';
import { workspace as Workspace, DocumentRangeFormattingEditProvider, OnTypeFormattingEditProvider, FormattingOptions, TextDocument, Position, Range, CancellationToken, TextEdit, WorkspaceConfiguration } from 'vscode';
import * as Proto from '../protocol';
import { ITypescriptServiceClient } from '../typescriptService';
@ -77,6 +77,14 @@ export default class TypeScriptFormattingProvider implements DocumentRangeFormat
this.client = client;
this.config = Configuration.def();
this.formatOptions = Object.create(null);
Workspace.onDidCloseTextDocument((textDocument) => {
let key = textDocument.uri.toString();
// When a document gets closed delete the cached formatting options.
// This is necessary sine the tsserver now closed a project when its
// last file in it closes which drops the stored formatting options
// as well.
delete this.formatOptions[key];
});
}
public updateConfiguration(config: WorkspaceConfiguration): void {

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